/usr/lib/pypy/lib_pypy/_tkinter/tclobj.py is in pypy-tk 2.4.0+dfsg-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | # TclObject, conversions with Python objects
from .tklib import tklib, tkffi
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")
def FromTclString(s):
# If the result contains any bytes with the top bit set, it's
# UTF-8 and we should decode it to Unicode.
try:
s.decode('ascii')
except UnicodeDecodeError:
try:
return s.decode('utf8')
except UnicodeDecodeError:
# Tcl encodes null character as \xc0\x80
try:
return s.replace('\xc0\x80', '\x00').decode('utf-8')
except UnicodeDecodeError:
pass
return s
def FromObj(app, value):
"""Convert a TclObj pointer into a Python object."""
typeCache = app._typeCache
if not value.typePtr:
buf = tkffi.buffer(value.bytes, value.length)
return FromTclString(buf[:])
elif value.typePtr == typeCache.BooleanType:
return bool(value.internalRep.longValue)
elif value.typePtr == typeCache.ByteArrayType:
size = tkffi.new('int*')
data = tklib.Tcl_GetByteArrayFromObj(value, size)
return tkffi.buffer(data, size[0])[:]
elif value.typePtr == typeCache.DoubleType:
return value.internalRep.doubleValue
elif value.typePtr == typeCache.IntType:
return value.internalRep.longValue
elif value.typePtr == typeCache.ListType:
size = tkffi.new('int*')
status = tklib.Tcl_ListObjLength(app.interp, value, size)
if status == tklib.TCL_ERROR:
app.raiseTclError()
result = []
tcl_elem = tkffi.new("Tcl_Obj**")
for i in range(size[0]):
status = tklib.Tcl_ListObjIndex(app.interp,
value, i, tcl_elem)
if status == tklib.TCL_ERROR:
app.raiseTclError()
result.append(FromObj(app, tcl_elem[0]))
return tuple(result)
elif value.typePtr == typeCache.ProcBodyType:
pass # fall through and return tcl object.
elif value.typePtr == typeCache.StringType:
buf = tklib.Tcl_GetUnicode(value)
length = tklib.Tcl_GetCharLength(value)
buf = tkffi.buffer(tkffi.cast("char*", buf), length*2)[:]
return buf.decode('utf-16')
return TclObject(value)
def AsObj(value):
if isinstance(value, str):
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)
elif isinstance(value, float):
return tklib.Tcl_NewDoubleObj(value)
elif 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):
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):
tklib.Tcl_IncrRefCount(value._value)
return value._value
else:
return AsObj(str(value))
class TclObject(object):
def __new__(cls, value):
self = object.__new__(cls)
tklib.Tcl_IncrRefCount(value)
self._value = value
self._string = None
return self
def __del__(self):
tklib.Tcl_DecrRefCount(self._value)
def __str__(self):
if self._string and isinstance(self._string, str):
return self._string
return tkffi.string(tklib.Tcl_GetString(self._value))
@property
def string(self):
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')
self._string = value
return self._string
|