Author: Amaury Forgeot d'Arc <[email protected]>
Branch: py3k
Changeset: r65086:e228809dd947
Date: 2013-06-28 23:20 +0200
http://bitbucket.org/pypy/pypy/changeset/e228809dd947/

Log:    Port _tkinter-on-cffi to py3k.

diff --git a/lib_pypy/_tkinter/__init__.py b/lib_pypy/_tkinter/__init__.py
--- a/lib_pypy/_tkinter/__init__.py
+++ b/lib_pypy/_tkinter/__init__.py
@@ -16,8 +16,8 @@
 
 from .app import TkApp
 
-TK_VERSION = tkffi.string(tklib.get_tk_version())
-TCL_VERSION = tkffi.string(tklib.get_tcl_version())
+TK_VERSION = tkffi.string(tklib.get_tk_version()).decode('utf-8')
+TCL_VERSION = tkffi.string(tklib.get_tcl_version()).decode('utf-8')
 
 READABLE = tklib.TCL_READABLE
 WRITABLE = tklib.TCL_WRITABLE
@@ -26,7 +26,7 @@
 def create(screenName=None, baseName=None, className=None,
            interactive=False, wantobjects=False, wantTk=True,
            sync=False, use=None):
-    return TkApp(screenName, baseName, className,
+    return TkApp(screenName, className,
                  interactive, wantobjects, wantTk, sync, use)
 
 def _flatten(item):
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
@@ -9,15 +9,15 @@
 def varname_converter(input):
     if isinstance(input, TclObject):
         return input.string
-    return input
+    return input.encode('utf-8')
 
 
 def Tcl_AppInit(app):
     if tklib.Tcl_Init(app.interp) == tklib.TCL_ERROR:
         app.raiseTclError()
     skip_tk_init = tklib.Tcl_GetVar(
-        app.interp, "_tkinter_skip_tk_init", tklib.TCL_GLOBAL_ONLY)
-    if skip_tk_init and tkffi.string(skip_tk_init) == "1":
+        app.interp, b"_tkinter_skip_tk_init", tklib.TCL_GLOBAL_ONLY)
+    if skip_tk_init and tkffi.string(skip_tk_init) == b"1":
         return
 
     if tklib.Tk_Init(app.interp) == tklib.TCL_ERROR:
@@ -38,7 +38,8 @@
         self = tkffi.from_handle(clientData)
         assert self.app.interp == interp
         try:
-            args = [tkffi.string(arg) for arg in argv[1:argc]]
+            args = [tkffi.string(arg).decode('utf-8')
+                    for arg in argv[1:argc]]
             result = self.func(*args)
             obj = AsObj(result)
             tklib.Tcl_SetObjResult(interp, obj)
@@ -58,7 +59,7 @@
 
 
 class TkApp(object):
-    def __new__(cls, screenName, baseName, className,
+    def __new__(cls, screenName, className,
                 interactive, wantobjects, wantTk, sync, use):
         if not wantobjects:
             raise NotImplementedError("wantobjects=True only")
@@ -66,7 +67,7 @@
         self.interp = tklib.Tcl_CreateInterp()
         self._wantobjects = wantobjects
         self.threaded = bool(tklib.Tcl_GetVar2Ex(
-            self.interp, "tcl_platform", "threaded",
+            self.interp, b"tcl_platform", b"threaded",
             tklib.TCL_GLOBAL_ONLY))
         self.thread_id = tklib.Tcl_GetCurrentThread()
         self.dispatching = False
@@ -77,26 +78,27 @@
         self._commands = {}
 
         # Delete the 'exit' command, which can screw things up
-        tklib.Tcl_DeleteCommand(self.interp, "exit")
+        tklib.Tcl_DeleteCommand(self.interp, b"exit")
 
         if screenName is not None:
-            tklib.Tcl_SetVar2(self.interp, "env", "DISPLAY", screenName,
+            tklib.Tcl_SetVar2(self.interp, b"env", b"DISPLAY",
+                              screenName.encode('utf-8'),
                               tklib.TCL_GLOBAL_ONLY)
 
         if interactive:
-            tklib.Tcl_SetVar(self.interp, "tcl_interactive", "1",
+            tklib.Tcl_SetVar(self.interp, b"tcl_interactive", b"1",
                              tklib.TCL_GLOBAL_ONLY)
         else:
-            tklib.Tcl_SetVar(self.interp, "tcl_interactive", "0",
+            tklib.Tcl_SetVar(self.interp, b"tcl_interactive", b"0",
                              tklib.TCL_GLOBAL_ONLY)
 
         # This is used to get the application class for Tk 4.1 and up
-        argv0 = className.lower()
-        tklib.Tcl_SetVar(self.interp, "argv0", argv0,
+        argv0 = className.lower().encode('utf-8')
+        tklib.Tcl_SetVar(self.interp, b"argv0", argv0,
                          tklib.TCL_GLOBAL_ONLY)
 
         if not wantTk:
-            tklib.Tcl_SetVar(self.interp, "_tkinter_skip_tk_init", "1",
+            tklib.Tcl_SetVar(self.interp, b"_tkinter_skip_tk_init", b"1",
                              tklib.TCL_GLOBAL_ONLY)
 
         # some initial arguments need to be in argv
@@ -123,8 +125,9 @@
     def raiseTclError(self):
         if self.errorInCmd:
             self.errorInCmd = False
-            raise self.exc_info[0], self.exc_info[1], self.exc_info[2]
-        raise TclError(tkffi.string(tklib.Tcl_GetStringResult(self.interp)))
+            raise self.exc_info[1].with_traceback(self.exc_info[2])
+        raise TclError(tkffi.string(
+                tklib.Tcl_GetStringResult(self.interp)).decode('utf-8'))
 
     def wantobjects(self):
         return self._wantobjects
@@ -135,11 +138,11 @@
 
     def loadtk(self):
         # We want to guard against calling Tk_Init() multiple times
-        err = tklib.Tcl_Eval(self.interp, "info exists     tk_version")
+        err = tklib.Tcl_Eval(self.interp, b"info exists     tk_version")
         if err == tklib.TCL_ERROR:
             self.raiseTclError()
         tk_exists = tklib.Tcl_GetStringResult(self.interp)
-        if not tk_exists or tkffi.string(tk_exists) != "1":
+        if not tk_exists or tkffi.string(tk_exists) != b"1":
             err = tklib.Tk_Init(self.interp)
             if err == tklib.TCL_ERROR:
                 self.raiseTclError()
@@ -220,7 +223,7 @@
             raise NotImplementedError("Call from another thread")
 
         res = tklib.Tcl_CreateCommand(
-            self.interp, cmdName, _CommandData.PythonCmd,
+            self.interp, cmdName.encode('utf-8'), _CommandData.PythonCmd,
             clientData, _CommandData.PythonCmdDelete)
         if not res:
             raise TclError("can't create Tcl command")
@@ -229,7 +232,7 @@
         if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread():
             raise NotImplementedError("Call from another thread")
 
-        res = tklib.Tcl_DeleteCommand(self.interp, cmdName)
+        res = tklib.Tcl_DeleteCommand(self.interp, cmdName.encode('utf-8'))
         if res == -1:
             raise TclError("can't delete Tcl command")
 
@@ -280,17 +283,19 @@
 
     def eval(self, script):
         self._check_tcl_appartment()
-        res = tklib.Tcl_Eval(self.interp, script)
+        res = tklib.Tcl_Eval(self.interp, script.encode('utf-8'))
         if res == tklib.TCL_ERROR:
             self.raiseTclError()
-        return tkffi.string(tklib.Tcl_GetStringResult(self.interp))
+        result = tkffi.string(tklib.Tcl_GetStringResult(self.interp))
+        return result.decode('utf-8')
 
     def evalfile(self, filename):
         self._check_tcl_appartment()
-        res = tklib.Tcl_EvalFile(self.interp, filename)
+        res = tklib.Tcl_EvalFile(self.interp, filename.encode('utf-8'))
         if res == tklib.TCL_ERROR:
             self.raiseTclError()
-        return tkffi.string(tklib.Tcl_GetStringResult(self.interp))
+        result = tkffi.string(tklib.Tcl_GetStringResult(self.interp))
+        return result.decode('utf-8')
 
     def split(self, arg):
         if isinstance(arg, tuple):
@@ -301,7 +306,7 @@
     def splitlist(self, arg):
         if isinstance(arg, tuple):
             return arg
-        if isinstance(arg, unicode):
+        if isinstance(arg, str):
             arg = arg.encode('utf8')
 
         argc = tkffi.new("int*")
@@ -310,7 +315,7 @@
         if res == tklib.TCL_ERROR:
             self.raiseTclError()
 
-        result = tuple(tkffi.string(argv[0][i])
+        result = tuple(tkffi.string(argv[0][i]).decode('utf-8')
                        for i in range(argc[0]))
         tklib.Tcl_Free(argv[0])
         return result
@@ -326,7 +331,7 @@
             for elem, newelem in zip(arg, newelems):
                 if elem is not newelem:
                     return newelems
-        elif isinstance(arg, str):
+        elif isinstance(arg, bytes):
             argc = tkffi.new("int*")
             argv = tkffi.new("char***")
             res = tklib.Tcl_SplitList(tkffi.NULL, arg, argc, argv)
@@ -345,7 +350,7 @@
             # Not a list.
             # Could be a quoted string containing funnies, e.g. {"}.
             # Return the string itself.
-            return arg
+            return arg.decode('utf-8')
 
         try:
             if argc[0] == 0:
@@ -361,6 +366,7 @@
     def getboolean(self, s):
         if isinstance(s, int):
             return s
+        s = s.encode('utf-8')
         v = tkffi.new("int*")
         res = tklib.Tcl_GetBoolean(self.interp, s, v)
         if res == tklib.TCL_ERROR:
@@ -383,7 +389,7 @@
         self.quitMainLoop = False
         if self.errorInCmd:
             self.errorInCmd = False
-            raise self.exc_info[0], self.exc_info[1], self.exc_info[2]
+            raise self.exc_info[1].with_traceback(self.exc_info[2])
 
     def quit(self):
         self.quitMainLoop = True
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
@@ -4,13 +4,13 @@
 
 class TypeCache(object):
     def __init__(self):
-        self.BooleanType = tklib.Tcl_GetObjType("boolean")
-        self.ByteArrayType = tklib.Tcl_GetObjType("bytearray")
-        self.DoubleType = tklib.Tcl_GetObjType("double")
-        self.IntType = tklib.Tcl_GetObjType("int")
-        self.ListType = tklib.Tcl_GetObjType("list")
-        self.ProcBodyType = tklib.Tcl_GetObjType("procbody")
-        self.StringType = tklib.Tcl_GetObjType("string")
+        self.BooleanType = tklib.Tcl_GetObjType(b"boolean")
+        self.ByteArrayType = tklib.Tcl_GetObjType(b"bytearray")
+        self.DoubleType = tklib.Tcl_GetObjType(b"double")
+        self.IntType = tklib.Tcl_GetObjType(b"int")
+        self.ListType = tklib.Tcl_GetObjType(b"list")
+        self.ProcBodyType = tklib.Tcl_GetObjType(b"procbody")
+        self.StringType = tklib.Tcl_GetObjType(b"string")
         
 
 def FromObj(app, value):
@@ -18,13 +18,7 @@
     typeCache = app._typeCache
     if not value.typePtr:
         buf = tkffi.buffer(value.bytes, value.length)
-        result = buf[:]
-        # If the result contains any bytes with the top bit set, it's
-        # UTF-8 and we should decode it to Unicode.
-        try:
-            result.decode('ascii')
-        except UnicodeDecodeError:
-            result = result.decode('utf8')
+        result = buf[:].decode('utf8')
         return result
 
     elif value.typePtr == typeCache.BooleanType:
@@ -60,12 +54,15 @@
     return TclObject(value)
 
 def AsObj(value):
-    if isinstance(value, str):
+    if isinstance(value, bytes):
         return tklib.Tcl_NewStringObj(value, len(value))
     elif isinstance(value, bool):
         return tklib.Tcl_NewBooleanObj(value)
     elif isinstance(value, int):
-        return tklib.Tcl_NewLongObj(value)
+        try:
+            return tklib.Tcl_NewLongObj(value)
+        except OverflowError:
+            pass  # and fall through to default object handling.
     elif isinstance(value, float):
         return tklib.Tcl_NewDoubleObj(value)
     elif isinstance(value, tuple):
@@ -73,16 +70,16 @@
         for i in range(len(value)):
             argv[i] = AsObj(value[i])
         return tklib.Tcl_NewListObj(len(value), argv)
-    elif isinstance(value, unicode):
+    elif isinstance(value, str):
         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)
+        return tklib.Tcl_NewUnicodeObj(buf, len(encoded)//2)
     elif 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):
@@ -98,17 +95,15 @@
     def __str__(self):
         if self._string and isinstance(self._string, str):
             return self._string
-        return tkffi.string(tklib.Tcl_GetString(self._value))
+        return tkffi.string(tklib.Tcl_GetString(self._value)).decode('utf-8')
 
     @property
     def string(self):
+        "the string representation of this object, either as str or bytes"
         if self._string is None:
             length = tkffi.new("int*")
             s = tklib.Tcl_GetStringFromObj(self._value, length)
             value = tkffi.buffer(s, length[0])[:]
-            try:
-                value.decode('ascii')
-            except UnicodeDecodeError:
-                value = value.decode('utf8')
+            value = value.decode('utf8')
             self._string = value
         return self._string
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to