summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2015-09-01 18:39:57 +0200
committerStefan Behnel <stefan_ml@behnel.de>2015-09-01 18:39:57 +0200
commitea6414cd293ba2134c3df5b37b158d8e3db79083 (patch)
tree2df2ae81c26b603a10c7fa17cf305958b4390655
parentf4ae2572c6bebc586a0b263e68cac3f4dfe13f1a (diff)
downloadcython-ea6414cd293ba2134c3df5b37b158d8e3db79083.tar.gz
correct processing of large integers (PyLong values) in compile time env under Py2.x
-rw-r--r--CHANGES.rst3
-rw-r--r--Cython/Compiler/Parsing.py9
-rw-r--r--tests/run/ct_DEF.pyx18
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()