From ea6414cd293ba2134c3df5b37b158d8e3db79083 Mon Sep 17 00:00:00 2001
From: Stefan Behnel <stefan_ml@behnel.de>
Date: Tue, 1 Sep 2015 18:39:57 +0200
Subject: [PATCH] correct processing of large integers (PyLong values) in
 compile time env under Py2.x

---
 CHANGES.rst                |  3 +++
 Cython/Compiler/Parsing.py |  9 ++++++---
 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()
-- 
2.30.9