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