[pypy-commit] pypy default: tkinter: add "WideInt" type.

amauryfa noreply at buildbot.pypy.org
Mon Jun 15 09:33:21 CEST 2015


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: 
Changeset: r78104:fd331e4bf733
Date: 2015-06-15 09:12 +0200
http://bitbucket.org/pypy/pypy/changeset/fd331e4bf733/

Log:	tkinter: add "WideInt" type.

diff --git a/lib_pypy/_tkinter/app.py b/lib_pypy/_tkinter/app.py
--- a/lib_pypy/_tkinter/app.py
+++ b/lib_pypy/_tkinter/app.py
@@ -2,7 +2,8 @@
 
 from .tklib_cffi import ffi as tkffi, lib as tklib
 from . import TclError
-from .tclobj import TclObject, FromObj, FromTclString, AsObj, TypeCache
+from .tclobj import (TclObject, FromObj, FromTclString, AsObj, TypeCache,
+                     FromBignumObj, FromWideIntObj)
 
 import contextlib
 import sys
@@ -458,11 +459,23 @@
             s = str(s)
         if '\x00' in s:
             raise TypeError
-        v = tkffi.new("int*")
-        res = tklib.Tcl_GetInt(self.interp, s, v)
-        if res == tklib.TCL_ERROR:
-            self.raiseTclError()
-        return v[0]
+        if tklib.HAVE_LIBTOMMATH or tklib.HAVE_WIDE_INT_TYPE:
+            value = tklib.Tcl_NewStringObj(s, -1)
+            if not value:
+                self.raiseTclError()
+            try:
+                if tklib.HAVE_LIBTOMMATH:
+                    return FromBignumObj(self, value)
+                else:
+                    return FromWideIntObj(self, value)
+            finally:
+                tklib.Tcl_DecrRefCount(value)
+        else:
+            v = tkffi.new("int*")
+            res = tklib.Tcl_GetInt(self.interp, s, v)
+            if res == tklib.TCL_ERROR:
+                self.raiseTclError()
+            return v[0]
 
     def getdouble(self, s):
         if isinstance(s, float):
diff --git a/lib_pypy/_tkinter/tclobj.py b/lib_pypy/_tkinter/tclobj.py
--- a/lib_pypy/_tkinter/tclobj.py
+++ b/lib_pypy/_tkinter/tclobj.py
@@ -10,6 +10,7 @@
         self.ByteArrayType = tklib.Tcl_GetObjType("bytearray")
         self.DoubleType = tklib.Tcl_GetObjType("double")
         self.IntType = tklib.Tcl_GetObjType("int")
+        self.WideIntType = tklib.Tcl_GetObjType("wideInt")
         self.BigNumType = None
         self.ListType = tklib.Tcl_GetObjType("list")
         self.ProcBodyType = tklib.Tcl_GetObjType("procbody")
@@ -45,6 +46,13 @@
     return s
 
 
+# Only when tklib.HAVE_WIDE_INT_TYPE.
+def FromWideIntObj(app, value):
+    wide = tkffi.new("Tcl_WideInt*")
+    if tklib.Tcl_GetWideIntFromObj(app.interp, value, wide) != tklib.TCL_OK:
+        app.raiseTclError()
+    return wide[0]
+
 # Only when tklib.HAVE_LIBTOMMATH!
 def FromBignumObj(app, value):
     bigValue = tkffi.new("mp_int*")
@@ -57,9 +65,11 @@
         if tklib.mp_to_unsigned_bin_n(
                 bigValue, buf, bufSize_ptr) != tklib.MP_OKAY:
             raise MemoryError
+        if bufSize_ptr[0] == 0:
+            return 0
         bytes = tkffi.buffer(buf)[0:bufSize_ptr[0]]
         sign = -1 if bigValue.sign == tklib.MP_NEG else 1
-        return sign * int(binascii.hexlify(bytes), 16)
+        return int(sign * int(binascii.hexlify(bytes), 16))
     finally:
         tklib.mp_clear(bigValue)
 
@@ -113,27 +123,40 @@
 def AsObj(value):
     if isinstance(value, str):
         return tklib.Tcl_NewStringObj(value, len(value))
-    elif isinstance(value, bool):
+    if isinstance(value, bool):
         return tklib.Tcl_NewBooleanObj(value)
-    elif isinstance(value, int):
+    if isinstance(value, int):
         return tklib.Tcl_NewLongObj(value)
-    elif isinstance(value, float):
+    if isinstance(value, long):
+        try:
+            tkffi.new("long[]", [value])
+        except OverflowError:
+            try:
+                tkffi.new("Tcl_WideInt[]", [value])
+            except OverflowError:
+                pass
+                # Too wide, fall through defaut object handling.
+            else:
+                return tklib.Tcl_NewWideIntObj(value)
+        else:
+            return tklib.Tcl_NewLongObj(value)
+    if isinstance(value, float):
         return tklib.Tcl_NewDoubleObj(value)
-    elif isinstance(value, tuple):
+    if isinstance(value, tuple):
         argv = tkffi.new("Tcl_Obj*[]", len(value))
         for i in range(len(value)):
             argv[i] = AsObj(value[i])
         return tklib.Tcl_NewListObj(len(value), argv)
-    elif isinstance(value, unicode):
+    if isinstance(value, unicode):
         encoded = value.encode('utf-16')[2:]
         buf = tkffi.new("char[]", encoded)
         inbuf = tkffi.cast("Tcl_UniChar*", buf)
         return tklib.Tcl_NewUnicodeObj(buf, len(encoded)/2)
-    elif isinstance(value, TclObject):
+    if isinstance(value, TclObject):
         tklib.Tcl_IncrRefCount(value._value)
         return value._value
-    else:
-        return AsObj(str(value))
+
+    return AsObj(str(value))
 
 class TclObject(object):
     def __new__(cls, value):
diff --git a/lib_pypy/_tkinter/tklib_build.py b/lib_pypy/_tkinter/tklib_build.py
--- a/lib_pypy/_tkinter/tklib_build.py
+++ b/lib_pypy/_tkinter/tklib_build.py
@@ -30,14 +30,21 @@
             break
 
 config_ffi = FFI()
-config_ffi.cdef(
-"#define TK_HEX_VERSION ...")
+config_ffi.cdef("""
+#define TK_HEX_VERSION ...
+#define HAVE_WIDE_INT_TYPE ...
+""")
 config_lib = config_ffi.verify("""
 #include <tk.h>
 #define TK_HEX_VERSION ((TK_MAJOR_VERSION << 24) | \
                         (TK_MINOR_VERSION << 16) | \
                         (TK_RELEASE_LEVEL << 8) | \
                         (TK_RELEASE_SERIAL << 0))
+#ifdef TCL_WIDE_INT_TYPE
+#define HAVE_WIDE_INT_TYPE 1
+#else
+#define HAVE_WIDE_INT_TYPE 0
+#endif
 """,
 include_dirs=incdirs,
 libraries=linklibs,
@@ -48,6 +55,7 @@
 
 HAVE_LIBTOMMATH = int((0x08050208 <= TK_HEX_VERSION < 0x08060000) or
                       (0x08060200 <= TK_HEX_VERSION))
+HAVE_WIDE_INT_TYPE = config_lib.HAVE_WIDE_INT_TYPE
 
 tkffi = FFI()
 
@@ -55,6 +63,7 @@
 char *get_tk_version();
 char *get_tcl_version();
 #define HAVE_LIBTOMMATH ...
+#define HAVE_WIDE_INT_TYPE ...
 
 #define TCL_READABLE ...
 #define TCL_WRITABLE ...
@@ -165,6 +174,13 @@
 void Tcl_FindExecutable(char *argv0);
 """)
 
+if HAVE_WIDE_INT_TYPE:
+    tkffi.cdef("""
+typedef int... Tcl_WideInt;
+
+int Tcl_GetWideIntFromObj(Tcl_Interp *interp, Tcl_Obj *obj, Tcl_WideInt *value);
+""")
+
 if HAVE_LIBTOMMATH:
     tkffi.cdef("""
 #define MP_OKAY ...
@@ -183,6 +199,7 @@
 
 tkffi.set_source("_tkinter.tklib_cffi", """
 #define HAVE_LIBTOMMATH %(HAVE_LIBTOMMATH)s
+#define HAVE_WIDE_INT_TYPE %(HAVE_WIDE_INT_TYPE)s
 #include <tcl.h>
 #include <tk.h>
 


More information about the pypy-commit mailing list