From 3d280f63e31cb927abb0bda2292ad4cd5830b7f5 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Tue, 2 Nov 2010 18:14:29 +0100 Subject: [PATCH] fix octal literals as Python constants, convert octal/binary/hex integer literals to plain decimal integers when using them as Python integers --- Cython/Compiler/ExprNodes.py | 15 ++++++++-- tests/run/int_literals.pyx | 53 ++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 72e7b5e3..4d8f3ed1 100755 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -833,19 +833,28 @@ class IntNode(ConstNode): def generate_evaluation_code(self, code): if self.type.is_pyobject: # pre-allocate a Python version of the number - self.result_code = code.get_py_num(self.value, self.longness) + plain_integer_string = self.value_as_c_integer_string(plain_digits=True) + self.result_code = code.get_py_num(plain_integer_string, self.longness) else: self.result_code = self.get_constant_c_result_code() def get_constant_c_result_code(self): + return self.value_as_c_integer_string() + self.unsigned + self.longness + + def value_as_c_integer_string(self, plain_digits=False): value = self.value if isinstance(value, basestring) and len(value) > 2: # must convert C-incompatible Py3 oct/bin notations if value[1] in 'oO': - value = value[0] + value[2:] # '0o123' => '0123' + if plain_digits: + value = int(value[2:], 8) + else: + value = value[0] + value[2:] # '0o123' => '0123' elif value[1] in 'bB': value = int(value[2:], 2) - return str(value) + self.unsigned + self.longness + elif plain_digits and value[1] in 'xX': + value = int(value[2:], 16) + return str(value) def calculate_result_code(self): return self.result_code diff --git a/tests/run/int_literals.pyx b/tests/run/int_literals.pyx index 2e38b0cf..2ff8351b 100644 --- a/tests/run/int_literals.pyx +++ b/tests/run/int_literals.pyx @@ -53,3 +53,56 @@ def c_long_types(): print typeof(1U) print typeof(1UL) print typeof(1ULL) + +# different ways to write an integer in Python + +def c_oct(): + """ + >>> c_oct() + (1, 17, 63) + """ + cdef int a = 0o01 + cdef int b = 0o21 + cdef int c = 0o77 + return a,b,c + +def py_oct(): + """ + >>> py_oct() + (1, 17, 63) + """ + return 0o01, 0o21, 0o77 + +def c_hex(): + """ + >>> c_hex() + (1, 33, 255) + """ + cdef int a = 0x01 + cdef int b = 0x21 + cdef int c = 0xFF + return a,b,c + +def py_hex(): + """ + >>> py_hex() + (1, 33, 255) + """ + return 0x01, 0x21, 0xFF + +def c_bin(): + """ + >>> c_bin() + (1, 2, 15) + """ + cdef int a = 0b01 + cdef int b = 0b10 + cdef int c = 0b1111 + return a,b,c + +def py_bin(): + """ + >>> py_bin() + (1, 2, 15) + """ + return 0b01, 0b10, 0b1111 -- 2.26.2