Author: Amaury Forgeot d'Arc <amaur...@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> _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit