diff options
author | Stefan Behnel <stefan_ml@behnel.de> | 2015-09-01 18:39:57 +0200 |
---|---|---|
committer | Stefan Behnel <stefan_ml@behnel.de> | 2015-09-01 18:39:57 +0200 |
commit | ea6414cd293ba2134c3df5b37b158d8e3db79083 (patch) | |
tree | 2df2ae81c26b603a10c7fa17cf305958b4390655 | |
parent | f4ae2572c6bebc586a0b263e68cac3f4dfe13f1a (diff) | |
download | cython-ea6414cd293ba2134c3df5b37b158d8e3db79083.tar.gz |
correct processing of large integers (PyLong values) in compile time env under Py2.x
-rw-r--r-- | CHANGES.rst | 3 | ||||
-rw-r--r-- | Cython/Compiler/Parsing.py | 9 | ||||
-rw-r--r-- | tests/run/ct_DEF.pyx | 18 |
3 files changed, 27 insertions, 3 deletions
diff --git a/CHANGES.rst b/CHANGES.rst index eeeb7c312..a95b337b9 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -8,6 +8,9 @@ Cython Changelog Bugs fixed ---------- +* Incorrect handling of large integers in compile-time evaluated DEF + expressions under Python 2.x. + * Invalid C code when caching known builtin methods. This fixes ticket 860. diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index d51a2825d..0610544f4 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -761,9 +761,10 @@ def wrap_compile_time_constant(pos, value): elif isinstance(value, bool): return ExprNodes.BoolNode(pos, value=value) elif isinstance(value, int): - return ExprNodes.IntNode(pos, value=rep) + return ExprNodes.IntNode( + pos, value=rep, constant_result=value, unsigned='U' if value > 0 else '') elif isinstance(value, float): - return ExprNodes.FloatNode(pos, value=rep) + return ExprNodes.FloatNode(pos, value=rep, constant_result=value) elif isinstance(value, _unicode): return ExprNodes.UnicodeNode(pos, value=EncodedString(value)) elif isinstance(value, _bytes): @@ -777,7 +778,9 @@ def wrap_compile_time_constant(pos, value): # error already reported return None elif not _IS_PY3 and isinstance(value, long): - return ExprNodes.IntNode(pos, value=rep, longness="L") + return ExprNodes.IntNode( + pos, value=rep.rstrip('L'), longness="L", constant_result=value, + unsigned='U' if value > 0 else '') error(pos, "Invalid type for compile-time constant: %r (type %s)" % (value, value.__class__.__name__)) return None diff --git a/tests/run/ct_DEF.pyx b/tests/run/ct_DEF.pyx index 29a82c226..85dd3eb8e 100644 --- a/tests/run/ct_DEF.pyx +++ b/tests/run/ct_DEF.pyx @@ -11,6 +11,10 @@ if sys.version_info[0] < 3: __doc__ = __doc__.replace(u" b'", u" '") +def print_large_number(n): + print(str(n).rstrip('L')) + + DEF TUPLE = (1, 2, u"buckle my shoe") DEF TRUE_FALSE = (True, False) DEF NONE = None @@ -21,6 +25,8 @@ DEF INT1 = 42 DEF INT2 = 0x42 DEF INT3 = -0x42 DEF LONG = 666L +DEF LARGE_NUM32 = (1 << 32) - 1 +DEF LARGE_NUM64 = (1 << 64) - 1 DEF FLOAT = 12.5 DEF STR = b"spam" DEF TWO = TUPLE[1] @@ -81,6 +87,18 @@ def l(): cdef long l = LONG return l +def large_nums(): + """ + >>> l32, l64 = large_nums() + >>> print_large_number(l32) + 4294967295 + >>> print_large_number(l64) + 18446744073709551615 + """ + cdef unsigned long l32 = LARGE_NUM32 + cdef unsigned long long l64 = LARGE_NUM64 + return l32, l64 + def f(): """ >>> f() |