[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