[pypy-commit] pypy stdlib-2.7.4: merge default
pjenvey
noreply at buildbot.pypy.org
Thu Jun 20 20:18:04 CEST 2013
Author: Philip Jenvey <pjenvey at underboss.org>
Branch: stdlib-2.7.4
Changeset: r64949:ffcba4b6a2e8
Date: 2013-06-20 11:17 -0700
http://bitbucket.org/pypy/pypy/changeset/ffcba4b6a2e8/
Log: merge default
diff too long, truncating to 2000 out of 49489 lines
diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -3,3 +3,6 @@
d8ac7d23d3ec5f9a0fa1264972f74a010dbfd07f release-1.6
ff4af8f318821f7f5ca998613a60fca09aa137da release-1.7
07e08e9c885ca67d89bcc304e45a32346daea2fa release-2.0-beta-1
+9b623bc48b5950cf07184462a0e48f2c4df0d720 pypy-2.1-beta1-arm
+9b623bc48b5950cf07184462a0e48f2c4df0d720 pypy-2.1-beta1-arm
+ab0dd631c22015ed88e583d9fdd4c43eebf0be21 pypy-2.1-beta1-arm
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -218,6 +218,7 @@
Impara, Germany
Change Maker, Sweden
University of California Berkeley, USA
+ Google Inc.
The PyPy Logo as used by http://speed.pypy.org and others was created
by Samuel Reis and is distributed on terms of Creative Commons Share Alike
diff --git a/Makefile b/Makefile
new file mode 100644
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,7 @@
+
+all: pypy-c
+
+pypy-c:
+ @echo "Building PyPy with JIT, it'll take about 40 minutes and 4G of RAM"
+ @sleep 3
+ rpython/bin/rpython -Ojit pypy/goal/targetpypystandalone.py
diff --git a/README.rst b/README.rst
--- a/README.rst
+++ b/README.rst
@@ -22,3 +22,16 @@
and send us feedback!
the pypy-dev team <pypy-dev at python.org>
+
+Building
+========
+
+build with::
+
+ rpython/bin/rpython -Ojit pypy/goal/targetpypystandalone.py
+
+This ends up with ``pypy-c`` binary in the main pypy directory. We suggest
+to use virtualenv with the resulting pypy-c as the interpreter, you can
+find more details about various installation schemes here:
+
+http://doc.pypy.org/en/latest/getting-started.html#installing-pypy
diff --git a/lib-python/2.7/distutils/command/build_ext.py b/lib-python/2.7/distutils/command/build_ext.py
--- a/lib-python/2.7/distutils/command/build_ext.py
+++ b/lib-python/2.7/distutils/command/build_ext.py
@@ -8,7 +8,7 @@
__revision__ = "$Id$"
-import sys, os, string, re
+import sys, os, string, re, imp
from types import *
from site import USER_BASE, USER_SITE
from distutils.core import Command
@@ -33,6 +33,11 @@
from distutils.ccompiler import show_compilers
show_compilers()
+def _get_c_extension_suffix():
+ for ext, mod, typ in imp.get_suffixes():
+ if typ == imp.C_EXTENSION:
+ return ext
+
class build_ext (Command):
@@ -677,10 +682,18 @@
# OS/2 has an 8 character module (extension) limit :-(
if os.name == "os2":
ext_path[len(ext_path) - 1] = ext_path[len(ext_path) - 1][:8]
+ # PyPy tweak: first try to get the C extension suffix from
+ # 'imp'. If it fails we fall back to the 'SO' config var, like
+ # the previous version of this code did. This should work for
+ # CPython too. The point is that on PyPy with cpyext, the
+ # config var 'SO' is just ".so" but we want to return
+ # ".pypy-VERSION.so" instead.
+ so_ext = _get_c_extension_suffix()
+ if so_ext is None:
+ so_ext = get_config_var('SO') # fall-back
# extensions in debug_mode are named 'module_d.pyd' under windows
- so_ext = get_config_var('SO')
if os.name == 'nt' and self.debug:
- return os.path.join(*ext_path) + '_d' + so_ext
+ so_ext = '_d.pyd'
return os.path.join(*ext_path) + so_ext
def get_export_symbols (self, ext):
diff --git a/lib-python/2.7/distutils/command/install.py b/lib-python/2.7/distutils/command/install.py
--- a/lib-python/2.7/distutils/command/install.py
+++ b/lib-python/2.7/distutils/command/install.py
@@ -474,8 +474,8 @@
def select_scheme (self, name):
# it's the caller's problem if they supply a bad name!
- if hasattr(sys, 'pypy_version_info') and not (
- name.endswith('_user') or name.endswith('_home')):
+ if (hasattr(sys, 'pypy_version_info') and
+ not name.endswith(('_user', '_home'))):
name = 'pypy'
scheme = INSTALL_SCHEMES[name]
for key in SCHEME_KEYS:
diff --git a/lib-python/2.7/distutils/sysconfig.py b/lib-python/2.7/distutils/sysconfig.py
--- a/lib-python/2.7/distutils/sysconfig.py
+++ b/lib-python/2.7/distutils/sysconfig.py
@@ -1,27 +1,16 @@
-"""Provide access to Python's configuration information. The specific
-configuration variables available depend heavily on the platform and
-configuration. The values may be retrieved using
-get_config_var(name), and the list of variables is available via
-get_config_vars().keys(). Additional convenience functions are also
-available.
-
-Written by: Fred L. Drake, Jr.
-Email: <fdrake at acm.org>
-"""
-
-__revision__ = "$Id: sysconfig.py 85358 2010-10-10 09:54:59Z antoine.pitrou $"
-
-import sys
-
# The content of this file is redirected from
# sysconfig_cpython or sysconfig_pypy.
+# All underscore names are imported too, because
+# people like to use undocumented sysconfig._xxx
+# directly.
+import sys
if '__pypy__' in sys.builtin_module_names:
- from distutils.sysconfig_pypy import *
- from distutils.sysconfig_pypy import _config_vars # needed by setuptools
- from distutils.sysconfig_pypy import _variable_rx # read_setup_file()
+ from distutils import sysconfig_pypy as _sysconfig_module
else:
- from distutils.sysconfig_cpython import *
- from distutils.sysconfig_cpython import _config_vars # needed by setuptools
- from distutils.sysconfig_cpython import _variable_rx # read_setup_file()
+ from distutils import sysconfig_cpython as _sysconfig_module
+globals().update(_sysconfig_module.__dict__)
+
+_USE_CLANG = None
+
diff --git a/lib-python/2.7/distutils/sysconfig_cpython.py b/lib-python/2.7/distutils/sysconfig_cpython.py
--- a/lib-python/2.7/distutils/sysconfig_cpython.py
+++ b/lib-python/2.7/distutils/sysconfig_cpython.py
@@ -9,7 +9,7 @@
Email: <fdrake at acm.org>
"""
-__revision__ = "$Id$"
+__revision__ = "$Id: sysconfig.py 85358 2010-10-10 09:54:59Z antoine.pitrou $"
import os
import re
diff --git a/lib-python/2.7/distutils/sysconfig_pypy.py b/lib-python/2.7/distutils/sysconfig_pypy.py
--- a/lib-python/2.7/distutils/sysconfig_pypy.py
+++ b/lib-python/2.7/distutils/sysconfig_pypy.py
@@ -1,9 +1,17 @@
-"""PyPy's minimal configuration information.
+"""Provide access to Python's configuration information.
+This is actually PyPy's minimal configuration information.
+
+The specific configuration variables available depend heavily on the
+platform and configuration. The values may be retrieved using
+get_config_var(name), and the list of variables is available via
+get_config_vars().keys(). Additional convenience functions are also
+available.
"""
+__revision__ = "$Id: sysconfig.py 85358 2010-10-10 09:54:59Z antoine.pitrou $"
+
import sys
import os
-import imp
from distutils.errors import DistutilsPlatformError
@@ -49,16 +57,11 @@
_config_vars = None
-def _get_so_extension():
- for ext, mod, typ in imp.get_suffixes():
- if typ == imp.C_EXTENSION:
- return ext
-
def _init_posix():
"""Initialize the module as appropriate for POSIX systems."""
g = {}
g['EXE'] = ""
- g['SO'] = _get_so_extension() or ".so"
+ g['SO'] = ".so"
g['SOABI'] = g['SO'].rsplit('.')[0]
g['LIBDIR'] = os.path.join(sys.prefix, 'lib')
g['CC'] = "gcc -pthread" # -pthread might not be valid on OS/X, check
@@ -71,7 +74,7 @@
"""Initialize the module as appropriate for NT"""
g = {}
g['EXE'] = ".exe"
- g['SO'] = _get_so_extension() or ".pyd"
+ g['SO'] = ".pyd"
g['SOABI'] = g['SO'].rsplit('.')[0]
global _config_vars
@@ -119,13 +122,13 @@
optional C speedup components.
"""
if compiler.compiler_type == "unix":
- compiler.compiler_so.extend(['-fPIC', '-Wimplicit'])
+ compiler.compiler_so.extend(['-O2', '-fPIC', '-Wimplicit'])
compiler.shared_lib_extension = get_config_var('SO')
if "CFLAGS" in os.environ:
- cflags = os.environ["CFLAGS"]
- compiler.compiler.append(cflags)
- compiler.compiler_so.append(cflags)
- compiler.linker_so.append(cflags)
+ cflags = os.environ["CFLAGS"].split()
+ compiler.compiler.extend(cflags)
+ compiler.compiler_so.extend(cflags)
+ compiler.linker_so.extend(cflags)
from sysconfig_cpython import (
diff --git a/lib-python/2.7/json/tests/test_decode.py b/lib-python/2.7/json/tests/test_decode.py
--- a/lib-python/2.7/json/tests/test_decode.py
+++ b/lib-python/2.7/json/tests/test_decode.py
@@ -49,6 +49,7 @@
self.assertEqual(self.loads('{"empty": {}}',
object_pairs_hook=OrderedDict),
OrderedDict([('empty', OrderedDict())]))
+ self.assertEqual(self.loads("{}", object_pairs_hook=list), [])
def test_extra_data(self):
s = '[1, 2, 3]5'
diff --git a/lib-python/2.7/logging/__init__.py b/lib-python/2.7/logging/__init__.py
--- a/lib-python/2.7/logging/__init__.py
+++ b/lib-python/2.7/logging/__init__.py
@@ -134,21 +134,30 @@
DEBUG = 10
NOTSET = 0
-_levelNames = {
- CRITICAL : 'CRITICAL',
- ERROR : 'ERROR',
- WARNING : 'WARNING',
- INFO : 'INFO',
- DEBUG : 'DEBUG',
- NOTSET : 'NOTSET',
- 'CRITICAL' : CRITICAL,
- 'ERROR' : ERROR,
- 'WARN' : WARNING,
- 'WARNING' : WARNING,
- 'INFO' : INFO,
- 'DEBUG' : DEBUG,
- 'NOTSET' : NOTSET,
+# NOTE(flaper87): This is different from
+# python's stdlib module since pypy's
+# dicts are much faster when their
+# keys are all of the same type.
+# Introduced in commit 9de7b40c586f
+_levelToName = {
+ CRITICAL: 'CRITICAL',
+ ERROR: 'ERROR',
+ WARNING: 'WARNING',
+ INFO: 'INFO',
+ DEBUG: 'DEBUG',
+ NOTSET: 'NOTSET',
}
+_nameToLevel = {
+ 'CRITICAL': CRITICAL,
+ 'ERROR': ERROR,
+ 'WARN': WARNING,
+ 'WARNING': WARNING,
+ 'INFO': INFO,
+ 'DEBUG': DEBUG,
+ 'NOTSET': NOTSET,
+}
+_levelNames = dict(_levelToName)
+_levelNames.update(_nameToLevel) # backward compatibility
def getLevelName(level):
"""
@@ -164,7 +173,11 @@
Otherwise, the string "Level %s" % level is returned.
"""
- return _levelNames.get(level, ("Level %s" % level))
+
+ # NOTE(flaper87): Check also in _nameToLevel
+ # if value is None.
+ return (_levelToName.get(level) or
+ _nameToLevel.get(level, ("Level %s" % level)))
def addLevelName(level, levelName):
"""
@@ -174,8 +187,8 @@
"""
_acquireLock()
try: #unlikely to cause an exception, but you never know...
- _levelNames[level] = levelName
- _levelNames[levelName] = level
+ _levelToName[level] = levelName
+ _nameToLevel[levelName] = level
finally:
_releaseLock()
@@ -183,9 +196,9 @@
if isinstance(level, (int, long)):
rv = level
elif str(level) == level:
- if level not in _levelNames:
+ if level not in _nameToLevel:
raise ValueError("Unknown level: %r" % level)
- rv = _levelNames[level]
+ rv = _nameToLevel[level]
else:
raise TypeError("Level not an integer or a valid string: %r" % level)
return rv
@@ -277,7 +290,7 @@
self.lineno = lineno
self.funcName = func
self.created = ct
- self.msecs = (ct - long(ct)) * 1000
+ self.msecs = (ct - int(ct)) * 1000
self.relativeCreated = (self.created - _startTime) * 1000
if logThreads and thread:
self.thread = thread.get_ident()
diff --git a/lib-python/2.7/logging/config.py b/lib-python/2.7/logging/config.py
--- a/lib-python/2.7/logging/config.py
+++ b/lib-python/2.7/logging/config.py
@@ -156,7 +156,7 @@
h = klass(*args)
if "level" in opts:
level = cp.get(sectname, "level")
- h.setLevel(logging._levelNames[level])
+ h.setLevel(level)
if len(fmt):
h.setFormatter(formatters[fmt])
if issubclass(klass, logging.handlers.MemoryHandler):
@@ -187,7 +187,7 @@
opts = cp.options(sectname)
if "level" in opts:
level = cp.get(sectname, "level")
- log.setLevel(logging._levelNames[level])
+ log.setLevel(level)
for h in root.handlers[:]:
root.removeHandler(h)
hlist = cp.get(sectname, "handlers")
@@ -237,7 +237,7 @@
existing.remove(qn)
if "level" in opts:
level = cp.get(sectname, "level")
- logger.setLevel(logging._levelNames[level])
+ logger.setLevel(level)
for h in logger.handlers[:]:
logger.removeHandler(h)
logger.propagate = propagate
diff --git a/lib-python/2.7/opcode.py b/lib-python/2.7/opcode.py
--- a/lib-python/2.7/opcode.py
+++ b/lib-python/2.7/opcode.py
@@ -193,5 +193,6 @@
hasname.append(201)
def_op('CALL_METHOD', 202) # #args not including 'self'
def_op('BUILD_LIST_FROM_ARG', 203)
+jrel_op('JUMP_IF_NOT_DEBUG', 204) # jump over assert statements
del def_op, name_op, jrel_op, jabs_op
diff --git a/lib-python/2.7/pydoc.py b/lib-python/2.7/pydoc.py
--- a/lib-python/2.7/pydoc.py
+++ b/lib-python/2.7/pydoc.py
@@ -1954,7 +1954,11 @@
if key is None:
callback(None, modname, '')
else:
- desc = split(__import__(modname).__doc__ or '', '\n')[0]
+ try:
+ module_doc = __import__(modname).__doc__
+ except ImportError:
+ module_doc = None
+ desc = split(module_doc or '', '\n')[0]
if find(lower(modname + ' - ' + desc), key) >= 0:
callback(None, modname, desc)
diff --git a/lib-python/2.7/socket.py b/lib-python/2.7/socket.py
--- a/lib-python/2.7/socket.py
+++ b/lib-python/2.7/socket.py
@@ -96,6 +96,7 @@
_realsocket = socket
+_type = type
# WSA error codes
if sys.platform.lower().startswith("win"):
@@ -173,31 +174,37 @@
__doc__ = _realsocket.__doc__
+ __slots__ = ["_sock", "__weakref__"]
+
def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None):
if _sock is None:
_sock = _realsocket(family, type, proto)
+ elif _type(_sock) is _realsocket:
+ _sock._reuse()
+ # PyPy note about refcounting: implemented with _reuse()/_drop()
+ # on the class '_socket.socket'. Python 3 did it differently
+ # with a reference counter on this class 'socket._socketobject'
+ # instead, but it is a less compatible change (breaks eventlet).
self._sock = _sock
- self._io_refs = 0
- self._closed = False
def send(self, data, flags=0):
- return self._sock.send(data, flags=flags)
+ return self._sock.send(data, flags)
send.__doc__ = _realsocket.send.__doc__
def recv(self, buffersize, flags=0):
- return self._sock.recv(buffersize, flags=flags)
+ return self._sock.recv(buffersize, flags)
recv.__doc__ = _realsocket.recv.__doc__
def recv_into(self, buffer, nbytes=0, flags=0):
- return self._sock.recv_into(buffer, nbytes=nbytes, flags=flags)
+ return self._sock.recv_into(buffer, nbytes, flags)
recv_into.__doc__ = _realsocket.recv_into.__doc__
def recvfrom(self, buffersize, flags=0):
- return self._sock.recvfrom(buffersize, flags=flags)
+ return self._sock.recvfrom(buffersize, flags)
recvfrom.__doc__ = _realsocket.recvfrom.__doc__
def recvfrom_into(self, buffer, nbytes=0, flags=0):
- return self._sock.recvfrom_into(buffer, nbytes=nbytes, flags=flags)
+ return self._sock.recvfrom_into(buffer, nbytes, flags)
recvfrom_into.__doc__ = _realsocket.recvfrom_into.__doc__
def sendto(self, data, param2, param3=None):
@@ -208,13 +215,17 @@
sendto.__doc__ = _realsocket.sendto.__doc__
def close(self):
- # This function should not reference any globals. See issue #808164.
+ s = self._sock
+ if type(s) is _realsocket:
+ s._drop()
self._sock = _closedsocket()
close.__doc__ = _realsocket.close.__doc__
def accept(self):
sock, addr = self._sock.accept()
- return _socketobject(_sock=sock), addr
+ sockobj = _socketobject(_sock=sock)
+ sock._drop() # already a copy in the _socketobject()
+ return sockobj, addr
accept.__doc__ = _realsocket.accept.__doc__
def dup(self):
@@ -228,24 +239,7 @@
Return a regular file object corresponding to the socket. The mode
and bufsize arguments are as for the built-in open() function."""
- self._io_refs += 1
- return _fileobject(self, mode, bufsize)
-
- def _decref_socketios(self):
- if self._io_refs > 0:
- self._io_refs -= 1
- if self._closed:
- self.close()
-
- def _real_close(self):
- # This function should not reference any globals. See issue #808164.
- self._sock.close()
-
- def close(self):
- # This function should not reference any globals. See issue #808164.
- self._closed = True
- if self._io_refs <= 0:
- self._real_close()
+ return _fileobject(self._sock, mode, bufsize)
family = property(lambda self: self._sock.family, doc="the socket family")
type = property(lambda self: self._sock.type, doc="the socket type")
@@ -286,6 +280,8 @@
"_close"]
def __init__(self, sock, mode='rb', bufsize=-1, close=False):
+ if type(sock) is _realsocket:
+ sock._reuse()
self._sock = sock
self.mode = mode # Not actually used in this version
if bufsize < 0:
@@ -320,11 +316,11 @@
if self._sock:
self.flush()
finally:
- if self._sock:
- if self._close:
- self._sock.close()
- else:
- self._sock._decref_socketios()
+ s = self._sock
+ if type(s) is _realsocket:
+ s._drop()
+ if self._close:
+ self._sock.close()
self._sock = None
def __del__(self):
diff --git a/lib-python/2.7/test/test_code.py b/lib-python/2.7/test/test_code.py
--- a/lib-python/2.7/test/test_code.py
+++ b/lib-python/2.7/test/test_code.py
@@ -75,7 +75,7 @@
cellvars: ()
freevars: ()
nlocals: 0
-flags: 67
+flags: 1048643
consts: ("'doc string'", 'None')
"""
diff --git a/lib-python/2.7/test/test_codecs.py b/lib-python/2.7/test/test_codecs.py
--- a/lib-python/2.7/test/test_codecs.py
+++ b/lib-python/2.7/test/test_codecs.py
@@ -2,7 +2,11 @@
import unittest
import codecs
import locale
-import sys, StringIO, _testcapi
+import sys, StringIO
+try:
+ import _testcapi
+except ImportError:
+ _testcapi = None
def coding_checker(self, coder):
def check(input, expect):
@@ -1496,7 +1500,7 @@
decodedresult += reader.read()
self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding))
- if encoding not in broken_incremental_coders:
+ if encoding not in broken_incremental_coders and _testcapi:
# check incremental decoder/encoder (fetched via the Python
# and C API) and iterencode()/iterdecode()
try:
diff --git a/lib-python/2.7/test/test_descr.py b/lib-python/2.7/test/test_descr.py
--- a/lib-python/2.7/test/test_descr.py
+++ b/lib-python/2.7/test/test_descr.py
@@ -3609,6 +3609,9 @@
list.__init__(a, sequence=[0, 1, 2])
self.assertEqual(a, [0, 1, 2])
+ @unittest.skipIf(test_support.check_impl_detail(pypy=True) and
+ sys.platform == 'win32',
+ "XXX: https://bugs.pypy.org/issue1461")
def test_recursive_call(self):
# Testing recursive __call__() by setting to instance of class...
class A(object):
diff --git a/lib-python/2.7/test/test_dis.py b/lib-python/2.7/test/test_dis.py
--- a/lib-python/2.7/test/test_dis.py
+++ b/lib-python/2.7/test/test_dis.py
@@ -53,25 +53,26 @@
pass
dis_bug1333982 = """\
- %-4d 0 LOAD_CONST 1 (0)
- 3 POP_JUMP_IF_TRUE 41
- 6 LOAD_GLOBAL 0 (AssertionError)
- 9 LOAD_FAST 0 (x)
- 12 BUILD_LIST_FROM_ARG 0
- 15 GET_ITER
- >> 16 FOR_ITER 12 (to 31)
- 19 STORE_FAST 1 (s)
- 22 LOAD_FAST 1 (s)
- 25 LIST_APPEND 2
- 28 JUMP_ABSOLUTE 16
+ %-4d 0 JUMP_IF_NOT_DEBUG 41 (to 44)
+ 3 LOAD_CONST 1 (0)
+ 6 POP_JUMP_IF_TRUE 44
+ 9 LOAD_GLOBAL 0 (AssertionError)
+ 12 LOAD_FAST 0 (x)
+ 15 BUILD_LIST_FROM_ARG 0
+ 18 GET_ITER
+ >> 19 FOR_ITER 12 (to 34)
+ 22 STORE_FAST 1 (s)
+ 25 LOAD_FAST 1 (s)
+ 28 LIST_APPEND 2
+ 31 JUMP_ABSOLUTE 19
- %-4d >> 31 LOAD_CONST 2 (1)
- 34 BINARY_ADD
- 35 CALL_FUNCTION 1
- 38 RAISE_VARARGS 1
+ %-4d >> 34 LOAD_CONST 2 (1)
+ 37 BINARY_ADD
+ 38 CALL_FUNCTION 1
+ 41 RAISE_VARARGS 1
- %-4d >> 41 LOAD_CONST 0 (None)
- 44 RETURN_VALUE
+ %-4d >> 44 LOAD_CONST 0 (None)
+ 47 RETURN_VALUE
"""%(bug1333982.func_code.co_firstlineno + 1,
bug1333982.func_code.co_firstlineno + 2,
bug1333982.func_code.co_firstlineno + 3)
diff --git a/lib-python/2.7/test/test_fileio.py b/lib-python/2.7/test/test_fileio.py
--- a/lib-python/2.7/test/test_fileio.py
+++ b/lib-python/2.7/test/test_fileio.py
@@ -348,7 +348,6 @@
self.assertRaises(ValueError, _FileIO, -10)
self.assertRaises(OSError, _FileIO, make_bad_fd())
if sys.platform == 'win32':
- raise unittest.SkipTest('Set _invalid_parameter_handler for low level io')
import msvcrt
self.assertRaises(IOError, msvcrt.get_osfhandle, make_bad_fd())
# Issue 15989
diff --git a/lib-python/2.7/test/test_logging.py b/lib-python/2.7/test/test_logging.py
--- a/lib-python/2.7/test/test_logging.py
+++ b/lib-python/2.7/test/test_logging.py
@@ -67,7 +67,8 @@
self.saved_handlers = logging._handlers.copy()
self.saved_handler_list = logging._handlerList[:]
self.saved_loggers = logger_dict.copy()
- self.saved_level_names = logging._levelNames.copy()
+ self.saved_name_to_level = logging._nameToLevel.copy()
+ self.saved_level_to_name = logging._levelToName.copy()
finally:
logging._releaseLock()
@@ -99,8 +100,10 @@
self.root_logger.setLevel(self.original_logging_level)
logging._acquireLock()
try:
- logging._levelNames.clear()
- logging._levelNames.update(self.saved_level_names)
+ logging._levelToName.clear()
+ logging._levelToName.update(self.saved_level_to_name)
+ logging._nameToLevel.clear()
+ logging._nameToLevel.update(self.saved_name_to_level)
logging._handlers.clear()
logging._handlers.update(self.saved_handlers)
logging._handlerList[:] = self.saved_handler_list
@@ -277,6 +280,24 @@
def test_invalid_name(self):
self.assertRaises(TypeError, logging.getLogger, any)
+ def test_get_level_name(self):
+ """Test getLevelName returns level constant."""
+ # NOTE(flaper87): Bug #1517
+ self.assertEqual(logging.getLevelName('NOTSET'), 0)
+ self.assertEqual(logging.getLevelName('DEBUG'), 10)
+ self.assertEqual(logging.getLevelName('INFO'), 20)
+ self.assertEqual(logging.getLevelName('WARN'), 30)
+ self.assertEqual(logging.getLevelName('WARNING'), 30)
+ self.assertEqual(logging.getLevelName('ERROR'), 40)
+ self.assertEqual(logging.getLevelName('CRITICAL'), 50)
+
+ self.assertEqual(logging.getLevelName(0), 'NOTSET')
+ self.assertEqual(logging.getLevelName(10), 'DEBUG')
+ self.assertEqual(logging.getLevelName(20), 'INFO')
+ self.assertEqual(logging.getLevelName(30), 'WARNING')
+ self.assertEqual(logging.getLevelName(40), 'ERROR')
+ self.assertEqual(logging.getLevelName(50), 'CRITICAL')
+
class BasicFilterTest(BaseTest):
"""Test the bundled Filter class."""
diff --git a/lib-python/2.7/test/test_sysconfig.py b/lib-python/2.7/test/test_sysconfig.py
--- a/lib-python/2.7/test/test_sysconfig.py
+++ b/lib-python/2.7/test/test_sysconfig.py
@@ -7,7 +7,8 @@
import subprocess
from copy import copy, deepcopy
-from test.test_support import run_unittest, TESTFN, unlink, get_attribute
+from test.test_support import (run_unittest, TESTFN, unlink, get_attribute,
+ import_module)
import sysconfig
from sysconfig import (get_paths, get_platform, get_config_vars,
@@ -245,7 +246,10 @@
def test_get_config_h_filename(self):
config_h = sysconfig.get_config_h_filename()
- self.assertTrue(os.path.isfile(config_h), config_h)
+ # import_module skips the test when the CPython C Extension API
+ # appears to not be supported
+ self.assertTrue(os.path.isfile(config_h) or
+ not import_module('_testcapi'), config_h)
def test_get_scheme_names(self):
wanted = ('nt', 'nt_user', 'os2', 'os2_home', 'osx_framework_user',
diff --git a/lib-python/2.7/test/test_traceback.py b/lib-python/2.7/test/test_traceback.py
--- a/lib-python/2.7/test/test_traceback.py
+++ b/lib-python/2.7/test/test_traceback.py
@@ -1,6 +1,9 @@
"""Test cases for traceback module"""
-from _testcapi import traceback_print
+try:
+ from _testcapi import traceback_print
+except ImportError:
+ traceback_print = None
from StringIO import StringIO
import sys
import unittest
@@ -176,6 +179,8 @@
class TracebackFormatTests(unittest.TestCase):
def test_traceback_format(self):
+ if traceback_print is None:
+ raise unittest.SkipTest('Requires _testcapi')
try:
raise KeyError('blah')
except KeyError:
diff --git a/lib-python/2.7/test/test_unicode.py b/lib-python/2.7/test/test_unicode.py
--- a/lib-python/2.7/test/test_unicode.py
+++ b/lib-python/2.7/test/test_unicode.py
@@ -1636,7 +1636,10 @@
self.assertEqual("{}".format(u), '__unicode__ overridden')
def test_encode_decimal(self):
- from _testcapi import unicode_encodedecimal
+ try:
+ from _testcapi import unicode_encodedecimal
+ except ImportError:
+ raise unittest.SkipTest('Requires _testcapi')
self.assertEqual(unicode_encodedecimal(u'123'),
b'123')
self.assertEqual(unicode_encodedecimal(u'\u0663.\u0661\u0664'),
diff --git a/lib-python/conftest.py b/lib-python/conftest.py
--- a/lib-python/conftest.py
+++ b/lib-python/conftest.py
@@ -131,7 +131,7 @@
RegrTest('test_bz2.py', usemodules='bz2'),
RegrTest('test_calendar.py'),
RegrTest('test_call.py', core=True),
- RegrTest('test_capi.py'),
+ RegrTest('test_capi.py', usemodules='cpyext'),
RegrTest('test_cd.py'),
RegrTest('test_cfgparser.py'),
RegrTest('test_cgi.py'),
@@ -178,7 +178,7 @@
RegrTest('test_cprofile.py'),
RegrTest('test_crypt.py', usemodules='crypt'),
RegrTest('test_csv.py', usemodules='_csv'),
- RegrTest('test_ctypes.py', usemodules="_rawffi thread"),
+ RegrTest('test_ctypes.py', usemodules="_rawffi thread cpyext"),
RegrTest('test_curses.py'),
RegrTest('test_datetime.py', usemodules='binascii struct'),
RegrTest('test_dbm.py'),
diff --git a/lib_pypy/_ctypes/pointer.py b/lib_pypy/_ctypes/pointer.py
--- a/lib_pypy/_ctypes/pointer.py
+++ b/lib_pypy/_ctypes/pointer.py
@@ -120,6 +120,7 @@
return self._buffer[0] != 0
contents = property(getcontents, setcontents)
+ _obj = property(getcontents) # byref interface
def _as_ffi_pointer_(self, ffitype):
return as_ffi_pointer(self, ffitype)
diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py
--- a/lib_pypy/_ctypes/structure.py
+++ b/lib_pypy/_ctypes/structure.py
@@ -20,7 +20,7 @@
or tp._type_ not in "iIhHbBlLqQ"):
#XXX: are those all types?
# we just dont get the type name
- # in the interp levle thrown TypeError
+ # in the interp level thrown TypeError
# from rawffi if there are more
raise TypeError('bit fields not allowed for type ' + tp.__name__)
@@ -166,9 +166,7 @@
if self is StructOrUnion:
return
if '_fields_' not in self.__dict__:
- self._fields_ = []
- self._names = []
- _set_shape(self, [], self._is_union)
+ self._fields_ = [] # As a side-effet, this also sets the ffishape.
__setattr__ = struct_setattr
diff --git a/lib_pypy/_ctypes_test.py b/lib_pypy/_ctypes_test.py
--- a/lib_pypy/_ctypes_test.py
+++ b/lib_pypy/_ctypes_test.py
@@ -1,60 +1,7 @@
-import os, sys
-import tempfile
-
-def compile_shared():
- """Compile '_ctypes_test.c' into an extension module, and import it
- """
- thisdir = os.path.dirname(__file__)
- output_dir = tempfile.mkdtemp()
-
- from distutils.ccompiler import new_compiler
- from distutils import sysconfig
-
- compiler = new_compiler()
- compiler.output_dir = output_dir
-
- # Compile .c file
- include_dir = os.path.join(thisdir, '..', 'include')
- if sys.platform == 'win32':
- ccflags = ['-D_CRT_SECURE_NO_WARNINGS']
- else:
- ccflags = ['-fPIC', '-Wimplicit-function-declaration']
- res = compiler.compile([os.path.join(thisdir, '_ctypes_test.c')],
- include_dirs=[include_dir],
- extra_preargs=ccflags)
- object_filename = res[0]
-
- # set link options
- output_filename = '_ctypes_test' + sysconfig.get_config_var('SO')
- if sys.platform == 'win32':
- # XXX libpypy-c.lib is currently not installed automatically
- library = os.path.join(thisdir, '..', 'include', 'libpypy-c')
- if not os.path.exists(library + '.lib'):
- #For a nightly build
- library = os.path.join(thisdir, '..', 'include', 'python27')
- if not os.path.exists(library + '.lib'):
- # For a local translation
- library = os.path.join(thisdir, '..', 'pypy', 'goal', 'libpypy-c')
- libraries = [library, 'oleaut32']
- extra_ldargs = ['/MANIFEST', # needed for VC10
- '/EXPORT:init_ctypes_test']
- else:
- libraries = []
- extra_ldargs = []
-
- # link the dynamic library
- compiler.link_shared_object(
- [object_filename],
- output_filename,
- libraries=libraries,
- extra_preargs=extra_ldargs)
-
- # Now import the newly created library, it will replace our module in sys.modules
- import imp
- fp, filename, description = imp.find_module('_ctypes_test', path=[output_dir])
- imp.load_module('_ctypes_test', fp, filename, description)
-
-
+try:
+ import cpyext
+except ImportError:
+ raise ImportError("No module named '_ctypes_test'")
try:
import _ctypes
_ctypes.PyObj_FromPtr = None
@@ -62,4 +9,5 @@
except ImportError:
pass # obscure condition of _ctypes_test.py being imported by py.test
else:
- compile_shared()
+ import _pypy_testcapi
+ _pypy_testcapi.compile_shared('_ctypes_test.c', '_ctypes_test')
diff --git a/lib_pypy/_curses.py b/lib_pypy/_curses.py
--- a/lib_pypy/_curses.py
+++ b/lib_pypy/_curses.py
@@ -476,6 +476,15 @@
def _chtype(ch):
return int(ffi.cast("chtype", ch))
+def _texttype(text):
+ if isinstance(text, str):
+ return text
+ elif isinstance(text, unicode):
+ return str(text) # default encoding
+ else:
+ raise TypeError("str or unicode expected, got a '%s' object"
+ % (type(text).__name__,))
+
def _extract_yx(args):
if len(args) >= 2:
@@ -589,6 +598,7 @@
@_argspec(1, 1, 2)
def addstr(self, y, x, text, attr=None):
+ text = _texttype(text)
if attr is not None:
attr_old = lib.getattrs(self._win)
lib.wattrset(self._win, attr)
@@ -602,6 +612,7 @@
@_argspec(2, 1, 2)
def addnstr(self, y, x, text, n, attr=None):
+ text = _texttype(text)
if attr is not None:
attr_old = lib.getattrs(self._win)
lib.wattrset(self._win, attr)
@@ -780,6 +791,7 @@
@_argspec(1, 1, 2)
def insstr(self, y, x, text, attr=None):
+ text = _texttype(text)
if attr is not None:
attr_old = lib.getattrs(self._win)
lib.wattrset(self._win, attr)
@@ -793,6 +805,7 @@
@_argspec(2, 1, 2)
def insnstr(self, y, x, text, n, attr=None):
+ text = _texttype(text)
if attr is not None:
attr_old = lib.getattrs(self._win)
lib.wattrset(self._win, attr)
@@ -1197,6 +1210,7 @@
def putp(text):
+ text = _texttype(text)
return _check_ERR(lib.putp(text), "putp")
diff --git a/lib_pypy/_pypy_interact.py b/lib_pypy/_pypy_interact.py
--- a/lib_pypy/_pypy_interact.py
+++ b/lib_pypy/_pypy_interact.py
@@ -44,7 +44,7 @@
import code
if mainmodule is None:
import __main__ as mainmodule
- console = code.InteractiveConsole(mainmodule.__dict__)
+ console = code.InteractiveConsole(mainmodule.__dict__, filename='<stdin>')
# some parts of code.py are copied here because it seems to be impossible
# to start an interactive console without printing at least one line
# of banner
diff --git a/lib_pypy/_pypy_irc_topic.py b/lib_pypy/_pypy_irc_topic.py
--- a/lib_pypy/_pypy_irc_topic.py
+++ b/lib_pypy/_pypy_irc_topic.py
@@ -1,4 +1,4 @@
-"""eclguba: flagnk naq frznagvpf bs clguba, fcrrq bs p, erfgevpgvbaf bs wnin naq pbzcvyre reebe zrffntrf nf crargenoyr nf ZHZCF
+__doc__ = """eclguba: flagnk naq frznagvpf bs clguba, fcrrq bs p, erfgevpgvbaf bs wnin naq pbzcvyre reebe zrffntrf nf crargenoyr nf ZHZCF
pglcrf unf n fcva bs 1/3
' ' vf n fcnpr gbb
Clguba 2.k rfg cerfdhr zbeg, ivir Clguba!
diff --git a/lib_pypy/_testcapi.py b/lib_pypy/_pypy_testcapi.py
copy from lib_pypy/_testcapi.py
copy to lib_pypy/_pypy_testcapi.py
--- a/lib_pypy/_testcapi.py
+++ b/lib_pypy/_pypy_testcapi.py
@@ -1,14 +1,20 @@
-import os, sys
+import os, sys, imp
import tempfile
-def compile_shared():
- """Compile '_testcapi.c' into an extension module, and import it
+def _get_c_extension_suffix():
+ for ext, mod, typ in imp.get_suffixes():
+ if typ == imp.C_EXTENSION:
+ return ext
+
+
+def compile_shared(csource, modulename):
+ """Compile '_testcapi.c' or '_ctypes_test.c' into an extension module,
+ and import it.
"""
thisdir = os.path.dirname(__file__)
output_dir = tempfile.mkdtemp()
from distutils.ccompiler import new_compiler
- from distutils import sysconfig
compiler = new_compiler()
compiler.output_dir = output_dir
@@ -19,13 +25,13 @@
ccflags = ['-D_CRT_SECURE_NO_WARNINGS']
else:
ccflags = ['-fPIC', '-Wimplicit-function-declaration']
- res = compiler.compile([os.path.join(thisdir, '_testcapimodule.c')],
+ res = compiler.compile([os.path.join(thisdir, csource)],
include_dirs=[include_dir],
extra_preargs=ccflags)
object_filename = res[0]
# set link options
- output_filename = '_testcapi' + sysconfig.get_config_var('SO')
+ output_filename = modulename + _get_c_extension_suffix()
if sys.platform == 'win32':
# XXX libpypy-c.lib is currently not installed automatically
library = os.path.join(thisdir, '..', 'include', 'libpypy-c')
@@ -37,7 +43,7 @@
library = os.path.join(thisdir, '..', 'pypy', 'goal', 'libpypy-c')
libraries = [library, 'oleaut32']
extra_ldargs = ['/MANIFEST', # needed for VC10
- '/EXPORT:init_testcapi']
+ '/EXPORT:init' + modulename]
else:
libraries = []
extra_ldargs = []
@@ -49,9 +55,7 @@
libraries=libraries,
extra_preargs=extra_ldargs)
- # Now import the newly created library, it will replace our module in sys.modules
- import imp
- fp, filename, description = imp.find_module('_testcapi', path=[output_dir])
- imp.load_module('_testcapi', fp, filename, description)
-
-compile_shared()
+ # Now import the newly created library, it will replace the original
+ # module in sys.modules
+ fp, filename, description = imp.find_module(modulename, path=[output_dir])
+ imp.load_module(modulename, fp, filename, description)
diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -1007,17 +1007,18 @@
# Actually execute the SQL statement
ret = _lib.sqlite3_step(self.__statement._statement)
- if ret not in (_lib.SQLITE_DONE, _lib.SQLITE_ROW):
- self.__statement._reset()
- raise self.__connection._get_exception(ret)
if ret == _lib.SQLITE_ROW:
if multiple:
raise ProgrammingError("executemany() can only execute DML statements.")
self.__build_row_cast_map()
self.__next_row = self.__fetch_one_row()
- elif ret == _lib.SQLITE_DONE and not multiple:
+ elif ret == _lib.SQLITE_DONE:
+ if not multiple:
+ self.__statement._reset()
+ else:
self.__statement._reset()
+ raise self.__connection._get_exception(ret)
if self.__statement._type in ("UPDATE", "DELETE", "INSERT", "REPLACE"):
if self.__rowcount == -1:
@@ -1098,7 +1099,6 @@
try:
next_row = self.__next_row
except AttributeError:
- self.__statement._reset()
raise StopIteration
del self.__next_row
@@ -1106,11 +1106,12 @@
next_row = self.row_factory(self, next_row)
ret = _lib.sqlite3_step(self.__statement._statement)
- if ret not in (_lib.SQLITE_DONE, _lib.SQLITE_ROW):
+ if ret == _lib.SQLITE_ROW:
+ self.__next_row = self.__fetch_one_row()
+ else:
self.__statement._reset()
- raise self.__connection._get_exception(ret)
- elif ret == _lib.SQLITE_ROW:
- self.__next_row = self.__fetch_one_row()
+ if ret != _lib.SQLITE_DONE:
+ raise self.__connection._get_exception(ret)
return next_row
if sys.version_info[0] < 3:
diff --git a/lib_pypy/_testcapi.py b/lib_pypy/_testcapi.py
--- a/lib_pypy/_testcapi.py
+++ b/lib_pypy/_testcapi.py
@@ -1,57 +1,7 @@
-import os, sys
-import tempfile
-
-def compile_shared():
- """Compile '_testcapi.c' into an extension module, and import it
- """
- thisdir = os.path.dirname(__file__)
- output_dir = tempfile.mkdtemp()
-
- from distutils.ccompiler import new_compiler
- from distutils import sysconfig
-
- compiler = new_compiler()
- compiler.output_dir = output_dir
-
- # Compile .c file
- include_dir = os.path.join(thisdir, '..', 'include')
- if sys.platform == 'win32':
- ccflags = ['-D_CRT_SECURE_NO_WARNINGS']
- else:
- ccflags = ['-fPIC', '-Wimplicit-function-declaration']
- res = compiler.compile([os.path.join(thisdir, '_testcapimodule.c')],
- include_dirs=[include_dir],
- extra_preargs=ccflags)
- object_filename = res[0]
-
- # set link options
- output_filename = '_testcapi' + sysconfig.get_config_var('SO')
- if sys.platform == 'win32':
- # XXX libpypy-c.lib is currently not installed automatically
- library = os.path.join(thisdir, '..', 'include', 'libpypy-c')
- if not os.path.exists(library + '.lib'):
- #For a nightly build
- library = os.path.join(thisdir, '..', 'include', 'python27')
- if not os.path.exists(library + '.lib'):
- # For a local translation
- library = os.path.join(thisdir, '..', 'pypy', 'goal', 'libpypy-c')
- libraries = [library, 'oleaut32']
- extra_ldargs = ['/MANIFEST', # needed for VC10
- '/EXPORT:init_testcapi']
- else:
- libraries = []
- extra_ldargs = []
-
- # link the dynamic library
- compiler.link_shared_object(
- [object_filename],
- output_filename,
- libraries=libraries,
- extra_preargs=extra_ldargs)
-
- # Now import the newly created library, it will replace our module in sys.modules
- import imp
- fp, filename, description = imp.find_module('_testcapi', path=[output_dir])
- imp.load_module('_testcapi', fp, filename, description)
-
-compile_shared()
+try:
+ import cpyext
+except ImportError:
+ raise ImportError("No module named '_testcapi'")
+else:
+ import _pypy_testcapi
+ _pypy_testcapi.compile_shared('_testcapimodule.c', '_testcapi')
diff --git a/lib_pypy/_tkinter/__init__.py b/lib_pypy/_tkinter/__init__.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_tkinter/__init__.py
@@ -0,0 +1,48 @@
+# _tkinter package -- low-level interface to libtk and libtcl.
+#
+# This is an internal module, applications should "import Tkinter" instead.
+#
+# This version is based on cffi, and is a translation of _tkinter.c
+# from CPython, version 2.7.4.
+
+class TclError(Exception):
+ pass
+
+import cffi
+try:
+ from .tklib import tklib, tkffi
+except cffi.VerificationError:
+ raise ImportError("Tk headers and development libraries are required")
+
+from .app import TkApp
+
+TK_VERSION = tkffi.string(tklib.get_tk_version())
+TCL_VERSION = tkffi.string(tklib.get_tcl_version())
+
+READABLE = tklib.TCL_READABLE
+WRITABLE = tklib.TCL_WRITABLE
+EXCEPTION = tklib.TCL_EXCEPTION
+
+def create(screenName=None, baseName=None, className=None,
+ interactive=False, wantobjects=False, wantTk=True,
+ sync=False, use=None):
+ return TkApp(screenName, baseName, className,
+ interactive, wantobjects, wantTk, sync, use)
+
+def _flatten(item):
+ def _flatten1(output, item, depth):
+ if depth > 1000:
+ raise ValueError("nesting too deep in _flatten")
+ if not isinstance(item, (list, tuple)):
+ raise TypeError("argument must be sequence")
+ # copy items to output tuple
+ for o in item:
+ if isinstance(o, (list, tuple)):
+ _flatten1(output, o, depth + 1)
+ elif o is not None:
+ output.append(o)
+
+ result = []
+ _flatten1(result, item, 0)
+ return tuple(result)
+
diff --git a/lib_pypy/_tkinter/app.py b/lib_pypy/_tkinter/app.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_tkinter/app.py
@@ -0,0 +1,389 @@
+# The TkApp class.
+
+from .tklib import tklib, tkffi
+from . import TclError
+from .tclobj import TclObject, FromObj, AsObj, TypeCache
+
+import sys
+
+def varname_converter(input):
+ if isinstance(input, TclObject):
+ return input.string
+ return input
+
+
+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":
+ return
+
+ if tklib.Tk_Init(app.interp) == tklib.TCL_ERROR:
+ app.raiseTclError()
+
+class _CommandData(object):
+ def __new__(cls, app, name, func):
+ self = object.__new__(cls)
+ self.app = app
+ self.name = name
+ self.func = func
+ handle = tkffi.new_handle(self)
+ app._commands[name] = handle # To keep the command alive
+ return tkffi.cast("ClientData", handle)
+
+ @tkffi.callback("Tcl_CmdProc")
+ def PythonCmd(clientData, interp, argc, argv):
+ self = tkffi.from_handle(clientData)
+ assert self.app.interp == interp
+ try:
+ args = [tkffi.string(arg) for arg in argv[1:argc]]
+ result = self.func(*args)
+ obj = AsObj(result)
+ tklib.Tcl_SetObjResult(interp, obj)
+ except:
+ self.app.errorInCmd = True
+ self.app.exc_info = sys.exc_info()
+ return tklib.TCL_ERROR
+ else:
+ return tklib.TCL_OK
+
+ @tkffi.callback("Tcl_CmdDeleteProc")
+ def PythonCmdDelete(clientData):
+ self = tkffi.from_handle(clientData)
+ app = self.app
+ del app._commands[self.name]
+ return
+
+
+class TkApp(object):
+ def __new__(cls, screenName, baseName, className,
+ interactive, wantobjects, wantTk, sync, use):
+ if not wantobjects:
+ raise NotImplementedError("wantobjects=True only")
+ self = object.__new__(cls)
+ self.interp = tklib.Tcl_CreateInterp()
+ self._wantobjects = wantobjects
+ self.threaded = bool(tklib.Tcl_GetVar2Ex(
+ self.interp, "tcl_platform", "threaded",
+ tklib.TCL_GLOBAL_ONLY))
+ self.thread_id = tklib.Tcl_GetCurrentThread()
+ self.dispatching = False
+ self.quitMainLoop = False
+ self.errorInCmd = False
+
+ self._typeCache = TypeCache()
+ self._commands = {}
+
+ # Delete the 'exit' command, which can screw things up
+ tklib.Tcl_DeleteCommand(self.interp, "exit")
+
+ if screenName is not None:
+ tklib.Tcl_SetVar2(self.interp, "env", "DISPLAY", screenName,
+ tklib.TCL_GLOBAL_ONLY)
+
+ if interactive:
+ tklib.Tcl_SetVar(self.interp, "tcl_interactive", "1",
+ tklib.TCL_GLOBAL_ONLY)
+ else:
+ tklib.Tcl_SetVar(self.interp, "tcl_interactive", "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,
+ tklib.TCL_GLOBAL_ONLY)
+
+ if not wantTk:
+ tklib.Tcl_SetVar(self.interp, "_tkinter_skip_tk_init", "1",
+ tklib.TCL_GLOBAL_ONLY)
+
+ # some initial arguments need to be in argv
+ if sync or use:
+ args = ""
+ if sync:
+ args += "-sync"
+ if use:
+ if sync:
+ args += " "
+ args += "-use " + use
+
+ tklib.Tcl_SetVar(self.interp, "argv", args,
+ tklib.TCL_GLOBAL_ONLY)
+
+ Tcl_AppInit(self)
+ # EnableEventHook()
+ return self
+
+ def __del__(self):
+ tklib.Tcl_DeleteInterp(self.interp)
+ # DisableEventHook()
+
+ 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)))
+
+ def wantobjects(self):
+ return self._wantobjects
+
+ def _check_tcl_appartment(self):
+ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread():
+ raise RuntimeError("Calling Tcl from different appartment")
+
+ def loadtk(self):
+ # We want to guard against calling Tk_Init() multiple times
+ err = tklib.Tcl_Eval(self.interp, "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":
+ err = tklib.Tk_Init(self.interp)
+ if err == tklib.TCL_ERROR:
+ self.raiseTclError()
+
+ def _var_invoke(self, func, *args, **kwargs):
+ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread():
+ # The current thread is not the interpreter thread.
+ # Marshal the call to the interpreter thread, then wait
+ # for completion.
+ raise NotImplementedError("Call from another thread")
+ return func(*args, **kwargs)
+
+ def _getvar(self, name1, name2=None, global_only=False):
+ name1 = varname_converter(name1)
+ if not name2:
+ name2 = tkffi.NULL
+ flags=tklib.TCL_LEAVE_ERR_MSG
+ if global_only:
+ flags |= tklib.TCL_GLOBAL_ONLY
+ res = tklib.Tcl_GetVar2Ex(self.interp, name1, name2, flags)
+ if not res:
+ self.raiseTclError()
+ assert self._wantobjects
+ return FromObj(self, res)
+
+ def _setvar(self, name1, value, global_only=False):
+ name1 = varname_converter(name1)
+ newval = AsObj(value)
+ flags=tklib.TCL_LEAVE_ERR_MSG
+ if global_only:
+ flags |= tklib.TCL_GLOBAL_ONLY
+ res = tklib.Tcl_SetVar2Ex(self.interp, name1, tkffi.NULL,
+ newval, flags)
+ if not res:
+ self.raiseTclError()
+
+ def _unsetvar(self, name1, name2=None, global_only=False):
+ name1 = varname_converter(name1)
+ if not name2:
+ name2 = tkffi.NULL
+ flags=tklib.TCL_LEAVE_ERR_MSG
+ if global_only:
+ flags |= tklib.TCL_GLOBAL_ONLY
+ res = tklib.Tcl_UnsetVar2(self.interp, name1, name2, flags)
+ if res == tklib.TCL_ERROR:
+ self.raiseTclError()
+
+ def getvar(self, name1, name2=None):
+ return self._var_invoke(self._getvar, name1, name2)
+
+ def globalgetvar(self, name1, name2=None):
+ return self._var_invoke(self._getvar, name1, name2, global_only=True)
+
+ def setvar(self, name1, value):
+ return self._var_invoke(self._setvar, name1, value)
+
+ def globalsetvar(self, name1, value):
+ return self._var_invoke(self._setvar, name1, value, global_only=True)
+
+ def unsetvar(self, name1, name2=None):
+ return self._var_invoke(self._unsetvar, name1, name2)
+
+ def globalunsetvar(self, name1, name2=None):
+ return self._var_invoke(self._unsetvar, name1, name2, global_only=True)
+
+ # COMMANDS
+
+ def createcommand(self, cmdName, func):
+ if not callable(func):
+ raise TypeError("command not callable")
+
+ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread():
+ raise NotImplementedError("Call from another thread")
+
+ clientData = _CommandData(self, cmdName, func)
+
+ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread():
+ raise NotImplementedError("Call from another thread")
+
+ res = tklib.Tcl_CreateCommand(
+ self.interp, cmdName, _CommandData.PythonCmd,
+ clientData, _CommandData.PythonCmdDelete)
+ if not res:
+ raise TclError("can't create Tcl command")
+
+ def deletecommand(self, cmdName):
+ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread():
+ raise NotImplementedError("Call from another thread")
+
+ res = tklib.Tcl_DeleteCommand(self.interp, cmdName)
+ if res == -1:
+ raise TclError("can't delete Tcl command")
+
+ def call(self, *args):
+ flags = tklib.TCL_EVAL_DIRECT | tklib.TCL_EVAL_GLOBAL
+
+ # If args is a single tuple, replace with contents of tuple
+ if len(args) == 1 and isinstance(args[0], tuple):
+ args = args[0]
+
+ if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread():
+ # We cannot call the command directly. Instead, we must
+ # marshal the parameters to the interpreter thread.
+ raise NotImplementedError("Call from another thread")
+
+ objects = tkffi.new("Tcl_Obj*[]", len(args))
+ argc = len(args)
+ try:
+ for i, arg in enumerate(args):
+ if arg is None:
+ argc = i
+ break
+ obj = AsObj(arg)
+ tklib.Tcl_IncrRefCount(obj)
+ objects[i] = obj
+
+ res = tklib.Tcl_EvalObjv(self.interp, argc, objects, flags)
+ if res == tklib.TCL_ERROR:
+ self.raiseTclError()
+ else:
+ result = self._callResult()
+ finally:
+ for obj in objects:
+ if obj:
+ tklib.Tcl_DecrRefCount(obj)
+ return result
+
+ def _callResult(self):
+ assert self._wantobjects
+ value = tklib.Tcl_GetObjResult(self.interp)
+ # Not sure whether the IncrRef is necessary, but something
+ # may overwrite the interpreter result while we are
+ # converting it.
+ tklib.Tcl_IncrRefCount(value)
+ res = FromObj(self, value)
+ tklib.Tcl_DecrRefCount(value)
+ return res
+
+ def eval(self, script):
+ self._check_tcl_appartment()
+ res = tklib.Tcl_Eval(self.interp, script)
+ if res == tklib.TCL_ERROR:
+ self.raiseTclError()
+ return tkffi.string(tklib.Tcl_GetStringResult(self.interp))
+
+ def evalfile(self, filename):
+ self._check_tcl_appartment()
+ res = tklib.Tcl_EvalFile(self.interp, filename)
+ if res == tklib.TCL_ERROR:
+ self.raiseTclError()
+ return tkffi.string(tklib.Tcl_GetStringResult(self.interp))
+
+ def split(self, arg):
+ if isinstance(arg, tuple):
+ return self._splitObj(arg)
+ else:
+ return self._split(arg)
+
+ def splitlist(self, arg):
+ if isinstance(arg, tuple):
+ return arg
+ if isinstance(arg, unicode):
+ arg = arg.encode('utf8')
+
+ argc = tkffi.new("int*")
+ argv = tkffi.new("char***")
+ res = tklib.Tcl_SplitList(self.interp, arg, argc, argv)
+ if res == tklib.TCL_ERROR:
+ self.raiseTclError()
+
+ result = tuple(tkffi.string(argv[0][i])
+ for i in range(argc[0]))
+ tklib.Tcl_Free(argv[0])
+ return result
+
+ def _splitObj(self, arg):
+ if isinstance(arg, tuple):
+ size = len(arg)
+ # Recursively invoke SplitObj for all tuple items.
+ # If this does not return a new object, no action is
+ # needed.
+ result = None
+ newelems = (self._splitObj(elem) for elem in arg)
+ for elem, newelem in zip(arg, newelems):
+ if elem is not newelem:
+ return newelems
+ elif isinstance(arg, str):
+ argc = tkffi.new("int*")
+ argv = tkffi.new("char***")
+ res = tklib.Tcl_SplitList(tkffi.NULL, arg, argc, argv)
+ if res == tklib.TCL_ERROR:
+ return arg
+ tklib.Tcl_Free(argv[0])
+ if argc[0] > 1:
+ return self._split(arg)
+ return arg
+
+ def _split(self, arg):
+ argc = tkffi.new("int*")
+ argv = tkffi.new("char***")
+ res = tklib.Tcl_SplitList(tkffi.NULL, arg, argc, argv)
+ if res == tklib.TCL_ERROR:
+ # Not a list.
+ # Could be a quoted string containing funnies, e.g. {"}.
+ # Return the string itself.
+ return arg
+
+ try:
+ if argc[0] == 0:
+ return ""
+ elif argc[0] == 1:
+ return argv[0][0]
+ else:
+ return (self._split(argv[0][i])
+ for i in range(argc[0]))
+ finally:
+ tklib.Tcl_Free(argv[0])
+
+ def getboolean(self, s):
+ if isinstance(s, int):
+ return s
+ v = tkffi.new("int*")
+ res = tklib.Tcl_GetBoolean(self.interp, s, v)
+ if res == tklib.TCL_ERROR:
+ self.raiseTclError()
+
+ def mainloop(self, threshold):
+ self._check_tcl_appartment()
+ self.dispatching = True
+ while (tklib.Tk_GetNumMainWindows() > threshold and
+ not self.quitMainLoop and not self.errorInCmd):
+
+ if self.threaded:
+ result = tklib.Tcl_DoOneEvent(0)
+ else:
+ raise NotImplementedError("TCL configured without threads")
+
+ if result < 0:
+ break
+ self.dispatching = False
+ self.quitMainLoop = False
+ if self.errorInCmd:
+ self.errorInCmd = False
+ raise self.exc_info[0], self.exc_info[1], self.exc_info[2]
+
+ def quit(self):
+ self.quitMainLoop = True
diff --git a/lib_pypy/_tkinter/tclobj.py b/lib_pypy/_tkinter/tclobj.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_tkinter/tclobj.py
@@ -0,0 +1,114 @@
+# 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 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)
+ 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')
+ return result
+
+ elif value.typePtr == typeCache.BooleanType:
+ return result
+ elif value.typePtr == typeCache.ByteArrayType:
+ return result
+ 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:
+ return result
+ 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
diff --git a/lib_pypy/_tkinter/tklib.py b/lib_pypy/_tkinter/tklib.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_tkinter/tklib.py
@@ -0,0 +1,114 @@
+# C bindings with libtcl and libtk.
+
+from cffi import FFI
+
+tkffi = FFI()
+
+tkffi.cdef("""
+char *get_tk_version();
+char *get_tcl_version();
+#define TCL_READABLE ...
+#define TCL_WRITABLE ...
+#define TCL_EXCEPTION ...
+#define TCL_ERROR ...
+#define TCL_OK ...
+
+#define TCL_LEAVE_ERR_MSG ...
+#define TCL_GLOBAL_ONLY ...
+#define TCL_EVAL_DIRECT ...
+#define TCL_EVAL_GLOBAL ...
+
+typedef unsigned short Tcl_UniChar;
+typedef ... Tcl_Interp;
+typedef ...* Tcl_ThreadId;
+typedef ...* Tcl_Command;
+
+typedef struct Tcl_ObjType {
+ char *name;
+ ...;
+} Tcl_ObjType;
+typedef struct Tcl_Obj {
+ char *bytes;
+ int length;
+ Tcl_ObjType *typePtr;
+ union { /* The internal representation: */
+ long longValue; /* - an long integer value. */
+ double doubleValue; /* - a double-precision floating value. */
+ struct { /* - internal rep as two pointers. */
+ void *ptr1;
+ void *ptr2;
+ } twoPtrValue;
+ } internalRep;
+ ...;
+} Tcl_Obj;
+
+Tcl_Interp *Tcl_CreateInterp();
+void Tcl_DeleteInterp(Tcl_Interp* interp);
+int Tcl_Init(Tcl_Interp* interp);
+int Tk_Init(Tcl_Interp* interp);
+
+void Tcl_Free(char* ptr);
+
+const char *Tcl_SetVar(Tcl_Interp* interp, const char* varName, const char* newValue, int flags);
+const char *Tcl_SetVar2(Tcl_Interp* interp, const char* name1, const char* name2, const char* newValue, int flags);
+const char *Tcl_GetVar(Tcl_Interp* interp, const char* varName, int flags);
+Tcl_Obj *Tcl_SetVar2Ex(Tcl_Interp* interp, const char* name1, const char* name2, Tcl_Obj* newValuePtr, int flags);
+Tcl_Obj *Tcl_GetVar2Ex(Tcl_Interp* interp, const char* name1, const char* name2, int flags);
+int Tcl_UnsetVar2(Tcl_Interp* interp, const char* name1, const char* name2, int flags);
+const Tcl_ObjType *Tcl_GetObjType(const char* typeName);
+
+Tcl_Obj *Tcl_NewStringObj(const char* bytes, int length);
+Tcl_Obj *Tcl_NewUnicodeObj(const Tcl_UniChar* unicode, int numChars);
+Tcl_Obj *Tcl_NewLongObj(long longValue);
+Tcl_Obj *Tcl_NewBooleanObj(int boolValue);
+Tcl_Obj *Tcl_NewDoubleObj(double doubleValue);
+
+void Tcl_IncrRefCount(Tcl_Obj* objPtr);
+void Tcl_DecrRefCount(Tcl_Obj* objPtr);
+
+int Tcl_GetBoolean(Tcl_Interp* interp, const char* src, int* boolPtr);
+char *Tcl_GetString(Tcl_Obj* objPtr);
+char *Tcl_GetStringFromObj(Tcl_Obj* objPtr, int* lengthPtr);
+
+Tcl_UniChar *Tcl_GetUnicode(Tcl_Obj* objPtr);
+int Tcl_GetCharLength(Tcl_Obj* objPtr);
+
+Tcl_Obj *Tcl_NewListObj(int objc, Tcl_Obj* const objv[]);
+int Tcl_ListObjLength(Tcl_Interp* interp, Tcl_Obj* listPtr, int* intPtr);
+int Tcl_ListObjIndex(Tcl_Interp* interp, Tcl_Obj* listPtr, int index, Tcl_Obj** objPtrPtr);
+int Tcl_SplitList(Tcl_Interp* interp, char* list, int* argcPtr, const char*** argvPtr);
+
+int Tcl_Eval(Tcl_Interp* interp, const char* script);
+int Tcl_EvalFile(Tcl_Interp* interp, const char* filename);
+int Tcl_EvalObjv(Tcl_Interp* interp, int objc, Tcl_Obj** objv, int flags);
+Tcl_Obj *Tcl_GetObjResult(Tcl_Interp* interp);
+const char *Tcl_GetStringResult(Tcl_Interp* interp);
+void Tcl_SetObjResult(Tcl_Interp* interp, Tcl_Obj* objPtr);
+
+typedef void* ClientData;
+typedef int Tcl_CmdProc(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ int argc,
+ const char *argv[]);
+typedef void Tcl_CmdDeleteProc(
+ ClientData clientData);
+Tcl_Command Tcl_CreateCommand(Tcl_Interp* interp, const char* cmdName, Tcl_CmdProc proc, ClientData clientData, Tcl_CmdDeleteProc deleteProc);
+int Tcl_DeleteCommand(Tcl_Interp* interp, const char* cmdName);
+
+Tcl_ThreadId Tcl_GetCurrentThread();
+int Tcl_DoOneEvent(int flags);
+
+int Tk_GetNumMainWindows();
+""")
+
+tklib = tkffi.verify("""
+#include <tcl.h>
+#include <tk.h>
+
+char *get_tk_version() { return TK_VERSION; }
+char *get_tcl_version() { return TCL_VERSION; }
+""",
+include_dirs=['/usr/include/tcl'],
+libraries=['tcl', 'tk'],
+)
diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py
--- a/lib_pypy/cffi/__init__.py
+++ b/lib_pypy/cffi/__init__.py
@@ -4,5 +4,5 @@
from .api import FFI, CDefError, FFIError
from .ffiplatform import VerificationError, VerificationMissing
-__version__ = "0.6"
-__version_info__ = (0, 6)
+__version__ = "0.7"
+__version_info__ = (0, 7)
diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py
--- a/lib_pypy/cffi/api.py
+++ b/lib_pypy/cffi/api.py
@@ -73,15 +73,15 @@
if name.startswith('RTLD_'):
setattr(self, name, getattr(backend, name))
#
- BVoidP = self._get_cached_btype(model.voidp_type)
+ self.BVoidP = self._get_cached_btype(model.voidp_type)
if isinstance(backend, types.ModuleType):
# _cffi_backend: attach these constants to the class
if not hasattr(FFI, 'NULL'):
- FFI.NULL = self.cast(BVoidP, 0)
+ FFI.NULL = self.cast(self.BVoidP, 0)
FFI.CData, FFI.CType = backend._get_types()
else:
# ctypes backend: attach these constants to the instance
- self.NULL = self.cast(BVoidP, 0)
+ self.NULL = self.cast(self.BVoidP, 0)
self.CData, self.CType = backend._get_types()
def cdef(self, csource, override=False):
@@ -346,6 +346,12 @@
self._cdefsources.extend(ffi_to_include._cdefsources)
self._cdefsources.append(']')
+ def new_handle(self, x):
+ return self._backend.newp_handle(self.BVoidP, x)
+
+ def from_handle(self, x):
+ return self._backend.from_handle(x)
+
def _make_ffi_library(ffi, libname, flags):
import os
@@ -355,13 +361,13 @@
backend = ffi._backend
try:
if '.' not in name and '/' not in name:
- raise OSError
+ raise OSError("library not found: %r" % (name,))
backendlib = backend.load_library(name, flags)
except OSError:
import ctypes.util
path = ctypes.util.find_library(name)
if path is None:
- raise OSError("library not found: %r" % (name,))
+ raise # propagate the original OSError
backendlib = backend.load_library(path, flags)
copied_enums = []
#
@@ -370,7 +376,10 @@
if key in ffi._parser._declarations:
tp = ffi._parser._declarations[key]
BType = ffi._get_cached_btype(tp)
- value = backendlib.load_function(BType, name)
+ try:
+ value = backendlib.load_function(BType, name)
+ except KeyError as e:
+ raise AttributeError('%s: %s' % (name, e))
library.__dict__[name] = value
return
#
diff --git a/lib_pypy/cffi/backend_ctypes.py b/lib_pypy/cffi/backend_ctypes.py
--- a/lib_pypy/cffi/backend_ctypes.py
+++ b/lib_pypy/cffi/backend_ctypes.py
@@ -16,6 +16,7 @@
class CTypesData(object):
__metaclass__ = CTypesType
__slots__ = ['__weakref__']
+ __name__ = '<cdata>'
def __init__(self, *args):
raise TypeError("cannot instantiate %r" % (self.__class__,))
@@ -491,6 +492,8 @@
elif BItem in (getbtype(model.PrimitiveType('signed char')),
getbtype(model.PrimitiveType('unsigned char'))):
kind = 'bytep'
+ elif BItem is getbtype(model.void_type):
+ kind = 'voidp'
else:
kind = 'generic'
#
@@ -546,13 +549,13 @@
def __setitem__(self, index, value):
self._as_ctype_ptr[index] = BItem._to_ctypes(value)
- if kind == 'charp':
+ if kind == 'charp' or kind == 'voidp':
@classmethod
- def _arg_to_ctypes(cls, value):
- if isinstance(value, bytes):
- return ctypes.c_char_p(value)
+ def _arg_to_ctypes(cls, *value):
+ if value and isinstance(value[0], bytes):
+ return ctypes.c_char_p(value[0])
else:
- return super(CTypesPtr, cls)._arg_to_ctypes(value)
+ return super(CTypesPtr, cls)._arg_to_ctypes(*value)
if kind == 'charp' or kind == 'bytep':
def _to_string(self, maxlen):
@@ -704,7 +707,7 @@
class CTypesStructOrUnion(CTypesBaseStructOrUnion):
__slots__ = ['_blob']
_ctype = struct_or_union
- _reftypename = '%s %s &' % (kind, name)
+ _reftypename = '%s &' % (name,)
_kind = kind
#
CTypesStructOrUnion._fix_class()
@@ -931,7 +934,7 @@
#
class CTypesEnum(CTypesInt):
__slots__ = []
- _reftypename = 'enum %s &' % name
+ _reftypename = '%s &' % name
def _get_own_repr(self):
value = self._value
diff --git a/lib_pypy/cffi/model.py b/lib_pypy/cffi/model.py
--- a/lib_pypy/cffi/model.py
+++ b/lib_pypy/cffi/model.py
@@ -244,6 +244,10 @@
self.forcename = forcename
self.build_c_name_with_marker()
+ def get_official_name(self):
+ assert self.c_name_with_marker.endswith('&')
+ return self.c_name_with_marker[:-1]
+
class StructOrUnion(StructOrUnionOrEnum):
fixedlayout = None
@@ -357,7 +361,9 @@
def build_backend_type(self, ffi, finishlist):
self.check_not_partial()
finishlist.append(self)
- return global_cache(self, ffi, 'new_struct_type', self.name, key=self)
+
+ return global_cache(self, ffi, 'new_struct_type',
+ self.get_official_name(), key=self)
class UnionType(StructOrUnion):
@@ -365,7 +371,8 @@
def build_backend_type(self, ffi, finishlist):
finishlist.append(self)
- return global_cache(self, ffi, 'new_union_type', self.name, key=self)
+ return global_cache(self, ffi, 'new_union_type',
+ self.get_official_name(), key=self)
class EnumType(StructOrUnionOrEnum):
@@ -388,7 +395,8 @@
def build_backend_type(self, ffi, finishlist):
self.check_not_partial()
base_btype = self.build_baseinttype(ffi, finishlist)
- return global_cache(self, ffi, 'new_enum_type', self.name,
+ return global_cache(self, ffi, 'new_enum_type',
+ self.get_official_name(),
More information about the pypy-commit
mailing list