[pypy-commit] pypy py3.5-mac-embedding: merge py3.5 into py3.5-mac-embedding
danchr
pypy.commits at gmail.com
Tue Oct 10 03:35:32 EDT 2017
Author: Dan Villiom Podlaski Christiansen <danchr at gmail.com>
Branch: py3.5-mac-embedding
Changeset: r92695:1dae3639ba33
Date: 2017-10-07 15:32 +0200
http://bitbucket.org/pypy/pypy/changeset/1dae3639ba33/
Log: merge py3.5 into py3.5-mac-embedding
diff too long, truncating to 2000 out of 50513 lines
diff --git a/.hgignore b/.hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -27,16 +27,17 @@
^pypy/module/cpyext/test/.+\.manifest$
^pypy/module/test_lib_pypy/ctypes_tests/.+\.o$
^pypy/module/test_lib_pypy/ctypes_tests/_ctypes_test\.o$
-^pypy/module/cppyy/src/.+\.o$
-^pypy/module/cppyy/bench/.+\.so$
-^pypy/module/cppyy/bench/.+\.root$
-^pypy/module/cppyy/bench/.+\.d$
-^pypy/module/cppyy/src/.+\.errors$
-^pypy/module/cppyy/test/.+_rflx\.cpp$
-^pypy/module/cppyy/test/.+\.so$
-^pypy/module/cppyy/test/.+\.rootmap$
-^pypy/module/cppyy/test/.+\.exe$
-^pypy/module/cppyy/test/.+_cint.h$
+^pypy/module/_cppyy/src/.+\.o$
+^pypy/module/_cppyy/bench/.+\.so$
+^pypy/module/_cppyy/bench/.+\.root$
+^pypy/module/_cppyy/bench/.+\.d$
+^pypy/module/_cppyy/src/.+\.errors$
+^pypy/module/_cppyy/test/.+_rflx\.cpp$
+^pypy/module/_cppyy/test/.+\.so$
+^pypy/module/_cppyy/test/.+\.rootmap$
+^pypy/module/_cppyy/test/.+\.exe$
+^pypy/module/_cppyy/test/.+_cint.h$
+^pypy/module/_cppyy/.+/*\.pcm$
^pypy/module/test_lib_pypy/cffi_tests/__pycache__.+$
^pypy/doc/.+\.html$
^pypy/doc/config/.+\.rst$
@@ -94,6 +95,3 @@
^release/
^rpython/_cache$
-pypy/module/cppyy/.+/*\.pcm
-
-
diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -40,3 +40,7 @@
2875f328eae2216a87f3d6f335092832eb031f56 release-pypy3.5-v5.7.1
c925e73810367cd960a32592dd7f728f436c125c release-pypy2.7-v5.8.0
a37ecfe5f142bc971a86d17305cc5d1d70abec64 release-pypy3.5-v5.8.0
+03d614975835870da65ff0481e1edad68ebbcb8d release-pypy2.7-v5.9.0
+d72f9800a42b46a8056951b1da2426d2c2d8d502 release-pypy3.5-v5.9.0
+03d614975835870da65ff0481e1edad68ebbcb8d release-pypy2.7-v5.9.0
+84a2f3e6a7f88f2fe698e473998755b3bd1a12e2 release-pypy2.7-v5.9.0
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -60,8 +60,8 @@
Wim Lavrijsen
Eric van Riet Paap
Richard Emslie
+ Remi Meier
Alexander Schremmer
- Remi Meier
Dan Villiom Podlaski Christiansen
Lukas Diekmann
Sven Hager
@@ -102,6 +102,7 @@
Michael Foord
Stephan Diehl
Stefano Rivera
+ Jean-Paul Calderone
Stefan Schwarzer
Tomek Meka
Valentino Volonghi
@@ -110,14 +111,13 @@
Bob Ippolito
Bruno Gola
David Malcolm
- Jean-Paul Calderone
Squeaky
Edd Barrett
Timo Paulssen
Marius Gedminas
+ Nicolas Truessel
Alexandre Fayolle
Simon Burton
- Nicolas Truessel
Martin Matusiak
Laurence Tratt
Wenzhu Man
@@ -156,6 +156,7 @@
Stefan H. Muller
Tim Felgentreff
Eugene Oden
+ Dodan Mihai
Jeff Terrace
Henry Mason
Vasily Kuznetsov
@@ -182,11 +183,13 @@
Rocco Moretti
Gintautas Miliauskas
Lucian Branescu Mihaila
+ Mariano Anaya
anatoly techtonik
- Dodan Mihai
Karl Bartel
+ Stefan Beyer
Gabriel Lavoie
Jared Grubb
+ Alecsandru Patrascu
Olivier Dormond
Wouter van Heyst
Sebastian Pawluś
@@ -194,6 +197,7 @@
Victor Stinner
Andrews Medina
Aaron Iles
+ p_zieschang at yahoo.de
Toby Watson
Daniel Patrick
Stuart Williams
@@ -204,6 +208,7 @@
Michael Cheng
Mikael Schönenberg
Stanislaw Halik
+ Mihnea Saracin
Berkin Ilbeyi
Gasper Zejn
Faye Zhao
@@ -214,14 +219,12 @@
Jonathan David Riehl
Beatrice During
Alex Perry
- p_zieschang at yahoo.de
Robert Zaremba
Alan McIntyre
Alexander Sedov
Vaibhav Sood
Reuben Cummings
Attila Gobi
- Alecsandru Patrascu
Christopher Pope
Tristan Arthur
Christian Tismer
@@ -243,7 +246,6 @@
Jacek Generowicz
Sylvain Thenault
Jakub Stasiak
- Stefan Beyer
Andrew Dalke
Alejandro J. Cura
Vladimir Kryachko
@@ -275,6 +277,7 @@
Christoph Gerum
Miguel de Val Borro
Artur Lisiecki
+ afteryu
Toni Mattis
Laurens Van Houtven
Bobby Impollonia
@@ -305,6 +308,7 @@
Anna Katrina Dominguez
Kim Jin Su
Amber Brown
+ Anthony Sottile
Nate Bragg
Ben Darnell
Juan Francisco Cantero Hurtado
@@ -325,12 +329,14 @@
Mike Bayer
Rodrigo Araújo
Daniil Yarancev
+ Min RK
OlivierBlanvillain
Jonas Pfannschmidt
Zearin
Andrey Churin
Dan Crosta
reubano at gmail.com
+ Stanisław Halik
Julien Phalip
Roman Podoliaka
Eli Stevens
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,7 @@
RUNINTERP = $(PYPY_EXECUTABLE)
endif
-.PHONY: cffi_imports
+.PHONY: pypy-c cffi_imports
pypy-c:
@echo
@@ -32,7 +32,7 @@
@echo "===================================================================="
@echo
@sleep 5
- $(RUNINTERP) rpython/bin/rpython -Ojit pypy/goal/targetpypystandalone.py
+ cd pypy/goal && $(RUNINTERP) ../../rpython/bin/rpython -Ojit targetpypystandalone.py
# Note: the -jN option, or MAKEFLAGS=-jN, are not usable. They are
# replaced with an opaque --jobserver option by the time this Makefile
@@ -40,4 +40,4 @@
# http://lists.gnu.org/archive/html/help-make/2010-08/msg00106.html
cffi_imports: pypy-c
- PYTHONPATH=. ./pypy-c pypy/tool/build_cffi_imports.py || /bin/true
+ PYTHONPATH=. pypy/goal/pypy-c pypy/tool/build_cffi_imports.py || /bin/true
diff --git a/lib-python/2.7/ctypes/__init__.py b/lib-python/2.7/ctypes/__init__.py
--- a/lib-python/2.7/ctypes/__init__.py
+++ b/lib-python/2.7/ctypes/__init__.py
@@ -361,17 +361,20 @@
if handle is None:
if flags & _FUNCFLAG_CDECL:
- self._handle = _ffi.CDLL(name, mode)
+ pypy_dll = _ffi.CDLL(name, mode)
else:
- self._handle = _ffi.WinDLL(name, mode)
- else:
- self._handle = handle
+ pypy_dll = _ffi.WinDLL(name, mode)
+ self.__pypy_dll__ = pypy_dll
+ handle = int(pypy_dll)
+ if _sys.maxint > 2 ** 32:
+ handle = int(handle) # long -> int
+ self._handle = handle
def __repr__(self):
- return "<%s '%s', handle %r at 0x%x>" % (
- self.__class__.__name__, self._name, self._handle,
- id(self) & (_sys.maxint * 2 + 1))
-
+ return "<%s '%s', handle %x at %x>" % \
+ (self.__class__.__name__, self._name,
+ (self._handle & (_sys.maxint*2 + 1)),
+ id(self) & (_sys.maxint*2 + 1))
def __getattr__(self, name):
if name.startswith('__') and name.endswith('__'):
diff --git a/lib-python/2.7/ctypes/test/test_byteswap.py b/lib-python/2.7/ctypes/test/test_byteswap.py
--- a/lib-python/2.7/ctypes/test/test_byteswap.py
+++ b/lib-python/2.7/ctypes/test/test_byteswap.py
@@ -23,7 +23,6 @@
setattr(bits, "i%s" % i, 1)
dump(bits)
- @xfail
def test_endian_short(self):
if sys.byteorder == "little":
self.assertIs(c_short.__ctype_le__, c_short)
@@ -51,7 +50,6 @@
self.assertEqual(bin(s), "3412")
self.assertEqual(s.value, 0x1234)
- @xfail
def test_endian_int(self):
if sys.byteorder == "little":
self.assertIs(c_int.__ctype_le__, c_int)
@@ -80,7 +78,6 @@
self.assertEqual(bin(s), "78563412")
self.assertEqual(s.value, 0x12345678)
- @xfail
def test_endian_longlong(self):
if sys.byteorder == "little":
self.assertIs(c_longlong.__ctype_le__, c_longlong)
@@ -109,7 +106,6 @@
self.assertEqual(bin(s), "EFCDAB9078563412")
self.assertEqual(s.value, 0x1234567890ABCDEF)
- @xfail
def test_endian_float(self):
if sys.byteorder == "little":
self.assertIs(c_float.__ctype_le__, c_float)
@@ -128,7 +124,6 @@
self.assertAlmostEqual(s.value, math.pi, 6)
self.assertEqual(bin(struct.pack(">f", math.pi)), bin(s))
- @xfail
def test_endian_double(self):
if sys.byteorder == "little":
self.assertIs(c_double.__ctype_le__, c_double)
@@ -156,7 +151,6 @@
self.assertIs(c_char.__ctype_le__, c_char)
self.assertIs(c_char.__ctype_be__, c_char)
- @xfail
def test_struct_fields_1(self):
if sys.byteorder == "little":
base = BigEndianStructure
@@ -192,7 +186,6 @@
pass
self.assertRaises(TypeError, setattr, T, "_fields_", [("x", typ)])
- @xfail
def test_struct_struct(self):
# nested structures with different byteorders
@@ -221,7 +214,6 @@
self.assertEqual(s.point.x, 1)
self.assertEqual(s.point.y, 2)
- @xfail
def test_struct_fields_2(self):
# standard packing in struct uses no alignment.
# So, we have to align using pad bytes.
@@ -245,7 +237,6 @@
s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14)
self.assertEqual(bin(s1), bin(s2))
- @xfail
def test_unaligned_nonnative_struct_fields(self):
if sys.byteorder == "little":
base = BigEndianStructure
diff --git a/lib-python/2.7/ctypes/test/test_unaligned_structures.py b/lib-python/2.7/ctypes/test/test_unaligned_structures.py
--- a/lib-python/2.7/ctypes/test/test_unaligned_structures.py
+++ b/lib-python/2.7/ctypes/test/test_unaligned_structures.py
@@ -37,10 +37,7 @@
for typ in byteswapped_structures:
## print >> sys.stderr, typ.value
self.assertEqual(typ.value.offset, 1)
- try:
- o = typ()
- except NotImplementedError as e:
- self.skipTest(str(e)) # for PyPy
+ o = typ()
o.value = 4
self.assertEqual(o.value, 4)
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
@@ -218,6 +218,10 @@
compiler.shared_lib_extension = so_ext
+def get_config_h_filename():
+ """Returns the path of pyconfig.h."""
+ inc_dir = get_python_inc(plat_specific=1)
+ return os.path.join(inc_dir, 'pyconfig.h')
from sysconfig_cpython import (
parse_makefile, _variable_rx, expand_makefile_vars)
diff --git a/lib-python/2.7/distutils/unixccompiler.py b/lib-python/2.7/distutils/unixccompiler.py
--- a/lib-python/2.7/distutils/unixccompiler.py
+++ b/lib-python/2.7/distutils/unixccompiler.py
@@ -226,7 +226,19 @@
return "-L" + dir
def _is_gcc(self, compiler_name):
- return "gcc" in compiler_name or "g++" in compiler_name
+ # XXX PyPy workaround, look at the big comment below for more
+ # context. On CPython, the hack below works fine because
+ # `compiler_name` contains the name of the actual compiler which was
+ # used at compile time (e.g. 'x86_64-linux-gnu-gcc' on my machine).
+ # PyPy hardcodes it to 'cc', so the hack doesn't work, and the end
+ # result is that we pass the wrong option to the compiler.
+ #
+ # The workaround is to *always* pretend to be GCC if we are on Linux:
+ # this should cover the vast majority of real systems, including the
+ # ones which use clang (which understands the '-Wl,-rpath' syntax as
+ # well)
+ return (sys.platform == "linux2" or
+ "gcc" in compiler_name or "g++" in compiler_name)
def runtime_library_dir_option(self, dir):
# XXX Hackish, at the very least. See Python bug #445902:
diff --git a/lib-python/2.7/inspect.py b/lib-python/2.7/inspect.py
--- a/lib-python/2.7/inspect.py
+++ b/lib-python/2.7/inspect.py
@@ -203,7 +203,7 @@
f_locals local namespace seen by this frame
f_restricted 0 or 1 if frame is in restricted execution mode
f_trace tracing function for this frame, or None"""
- return isinstance(object, types.FrameType)
+ return isinstance(object, (types.FrameType, types.FakeFrameType))
def iscode(object):
"""Return true if the object is a code object.
diff --git a/lib-python/2.7/multiprocessing/heap.py b/lib-python/2.7/multiprocessing/heap.py
--- a/lib-python/2.7/multiprocessing/heap.py
+++ b/lib-python/2.7/multiprocessing/heap.py
@@ -62,7 +62,7 @@
self.size = size
self.name = 'pym-%d-%d' % (os.getpid(), Arena._counter.next())
self.buffer = mmap.mmap(-1, self.size, tagname=self.name)
- assert win32.GetLastError() == 0, 'tagname already in use'
+ #assert win32.GetLastError() == 0, 'tagname already in use'
self._state = (self.size, self.name)
def __getstate__(self):
@@ -72,7 +72,7 @@
def __setstate__(self, state):
self.size, self.name = self._state = state
self.buffer = mmap.mmap(-1, self.size, tagname=self.name)
- assert win32.GetLastError() == win32.ERROR_ALREADY_EXISTS
+ #assert win32.GetLastError() == win32.ERROR_ALREADY_EXISTS
else:
diff --git a/lib-python/2.7/string.py b/lib-python/2.7/string.py
--- a/lib-python/2.7/string.py
+++ b/lib-python/2.7/string.py
@@ -75,7 +75,7 @@
for i in range(256):
buf[i] = i
for i in range(n):
- buf[ord(fromstr[i])] = tostr[i]
+ buf[ord(fromstr[i])] = ord(tostr[i])
return str(buf)
diff --git a/lib-python/2.7/test/test_os.py b/lib-python/2.7/test/test_os.py
--- a/lib-python/2.7/test/test_os.py
+++ b/lib-python/2.7/test/test_os.py
@@ -580,6 +580,7 @@
"getentropy() does not use a file descriptor")
class URandomFDTests(unittest.TestCase):
@unittest.skipUnless(resource, "test requires the resource module")
+ @test_support.impl_detail(pypy=False) # on Linux, may use getrandom()
def test_urandom_failure(self):
# Check urandom() failing when it is not able to open /dev/random.
# We spawn a new process to make the test more robust (if getrlimit()
diff --git a/lib-python/2.7/types.py b/lib-python/2.7/types.py
--- a/lib-python/2.7/types.py
+++ b/lib-python/2.7/types.py
@@ -71,6 +71,12 @@
FrameType = type(tb.tb_frame)
del tb
+# PyPy extension
+try:
+ FakeFrameType = type(next(sys._current_frames().itervalues()))
+except (AttributeError, StopIteration):
+ FakeFrameType = FrameType
+
SliceType = slice
EllipsisType = type(Ellipsis)
diff --git a/lib-python/3/ctypes/__init__.py b/lib-python/3/ctypes/__init__.py
--- a/lib-python/3/ctypes/__init__.py
+++ b/lib-python/3/ctypes/__init__.py
@@ -346,16 +346,18 @@
if handle is None:
if flags & _FUNCFLAG_CDECL:
- self._handle = _ffi.CDLL(name, mode)
+ pypy_dll = _ffi.CDLL(name, mode)
else:
- self._handle = _ffi.WinDLL(name, mode)
- else:
- self._handle = handle
+ pypy_dll = _ffi.WinDLL(name, mode)
+ self.__pypy_dll__ = pypy_dll
+ handle = int(pypy_dll)
+ self._handle = handle
def __repr__(self):
- return "<%s '%s', handle %r at 0x%x>" % (
- self.__class__.__name__, self._name, self._handle,
- id(self) & (_sys.maxsize * 2 + 1))
+ return "<%s '%s', handle %x at 0x%x>" % \
+ (self.__class__.__name__, self._name,
+ (self._handle & (_sys.maxsize*2 + 1)),
+ id(self) & (_sys.maxsize*2 + 1))
def __getattr__(self, name):
if name.startswith('__') and name.endswith('__'):
diff --git a/lib-python/3/ctypes/test/test_byteswap.py b/lib-python/3/ctypes/test/test_byteswap.py
--- a/lib-python/3/ctypes/test/test_byteswap.py
+++ b/lib-python/3/ctypes/test/test_byteswap.py
@@ -2,7 +2,6 @@
from binascii import hexlify
from ctypes import *
-from ctypes.test import xfail
def bin(s):
return hexlify(memoryview(s)).decode().upper()
@@ -43,7 +42,6 @@
with self.assertRaises(AttributeError):
little.z = 24
- @xfail
def test_endian_short(self):
if sys.byteorder == "little":
self.assertIs(c_short.__ctype_le__, c_short)
@@ -71,7 +69,6 @@
self.assertEqual(bin(s), "3412")
self.assertEqual(s.value, 0x1234)
- @xfail
def test_endian_int(self):
if sys.byteorder == "little":
self.assertIs(c_int.__ctype_le__, c_int)
@@ -100,7 +97,6 @@
self.assertEqual(bin(s), "78563412")
self.assertEqual(s.value, 0x12345678)
- @xfail
def test_endian_longlong(self):
if sys.byteorder == "little":
self.assertIs(c_longlong.__ctype_le__, c_longlong)
@@ -129,7 +125,6 @@
self.assertEqual(bin(s), "EFCDAB9078563412")
self.assertEqual(s.value, 0x1234567890ABCDEF)
- @xfail
def test_endian_float(self):
if sys.byteorder == "little":
self.assertIs(c_float.__ctype_le__, c_float)
@@ -148,7 +143,6 @@
self.assertAlmostEqual(s.value, math.pi, places=6)
self.assertEqual(bin(struct.pack(">f", math.pi)), bin(s))
- @xfail
def test_endian_double(self):
if sys.byteorder == "little":
self.assertIs(c_double.__ctype_le__, c_double)
@@ -176,7 +170,6 @@
self.assertIs(c_char.__ctype_le__, c_char)
self.assertIs(c_char.__ctype_be__, c_char)
- @xfail
def test_struct_fields_1(self):
if sys.byteorder == "little":
base = BigEndianStructure
@@ -212,7 +205,6 @@
pass
self.assertRaises(TypeError, setattr, T, "_fields_", [("x", typ)])
- @xfail
def test_struct_struct(self):
# nested structures with different byteorders
@@ -241,7 +233,6 @@
self.assertEqual(s.point.x, 1)
self.assertEqual(s.point.y, 2)
- @xfail
def test_struct_fields_2(self):
# standard packing in struct uses no alignment.
# So, we have to align using pad bytes.
@@ -265,7 +256,6 @@
s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14)
self.assertEqual(bin(s1), bin(s2))
- @xfail
def test_unaligned_nonnative_struct_fields(self):
if sys.byteorder == "little":
base = BigEndianStructure
diff --git a/lib-python/3/ctypes/test/test_values.py b/lib-python/3/ctypes/test/test_values.py
--- a/lib-python/3/ctypes/test/test_values.py
+++ b/lib-python/3/ctypes/test/test_values.py
@@ -4,6 +4,7 @@
import unittest
import sys
+from test.support import cpython_only
from ctypes import *
import _ctypes_test
@@ -28,6 +29,7 @@
ctdll = CDLL(_ctypes_test.__file__)
self.assertRaises(ValueError, c_int.in_dll, ctdll, "Undefined_Symbol")
+ at cpython_only
class PythonValuesTestCase(unittest.TestCase):
"""This test only works when python itself is a dll/shared library"""
diff --git a/lib-python/3/datetime.py b/lib-python/3/datetime.py
--- a/lib-python/3/datetime.py
+++ b/lib-python/3/datetime.py
@@ -810,7 +810,8 @@
month = self._month
if day is None:
day = self._day
- return date(year, month, day)
+ # PyPy fix: returns type(self)() instead of date()
+ return type(self)(year, month, day)
# Comparisons of date objects with other.
@@ -1285,7 +1286,8 @@
microsecond = self.microsecond
if tzinfo is True:
tzinfo = self.tzinfo
- return time(hour, minute, second, microsecond, tzinfo)
+ # PyPy fix: returns type(self)() instead of time()
+ return type(self)(hour, minute, second, microsecond, tzinfo)
# Pickle support.
@@ -1497,7 +1499,8 @@
microsecond = self.microsecond
if tzinfo is True:
tzinfo = self.tzinfo
- return datetime(year, month, day, hour, minute, second, microsecond,
+ # PyPy fix: returns type(self)() instead of datetime()
+ return type(self)(year, month, day, hour, minute, second, microsecond,
tzinfo)
def astimezone(self, tz=None):
diff --git a/lib-python/3/distutils/sysconfig_pypy.py b/lib-python/3/distutils/sysconfig_pypy.py
--- a/lib-python/3/distutils/sysconfig_pypy.py
+++ b/lib-python/3/distutils/sysconfig_pypy.py
@@ -73,7 +73,7 @@
g['CCSHARED'] = "-fPIC"
g['LDSHARED'] = "cc -pthread -shared"
g['EXT_SUFFIX'] = so_ext
- g['SHLIB_SUFFIX'] = so_ext
+ g['SHLIB_SUFFIX'] = ".so"
g['SO'] = so_ext # deprecated in Python 3, for backward compatibility
g['AR'] = "ar"
g['ARFLAGS'] = "rc"
@@ -81,6 +81,19 @@
g['LIBDIR'] = os.path.join(sys.prefix, 'lib')
g['VERSION'] = get_python_version()
+ if sys.platform[:6] == "darwin":
+ import platform
+ if platform.machine() == 'i386':
+ if platform.architecture()[0] == '32bit':
+ arch = 'i386'
+ else:
+ arch = 'x86_64'
+ else:
+ # just a guess
+ arch = platform.machine()
+ g['LDSHARED'] += ' -undefined dynamic_lookup'
+ g['CC'] += ' -arch %s' % (arch,)
+
global _config_vars
_config_vars = g
diff --git a/lib-python/3/stat.py b/lib-python/3/stat.py
--- a/lib-python/3/stat.py
+++ b/lib-python/3/stat.py
@@ -139,13 +139,21 @@
def filemode(mode):
"""Convert a file's mode to a string of the form '-rwxrwxrwx'."""
perm = []
+
+ # The first group gets a question mark if none of the bits match the mode.
+ empty = "?"
+
for table in _filemode_table:
for bit, char in table:
if mode & bit == bit:
perm.append(char)
break
else:
- perm.append("-")
+ perm.append(empty)
+
+ # All the rest of the positions get a - if the bits don't match.
+ empty = "-"
+
return "".join(perm)
diff --git a/lib-python/3/test/test_asyncio/test_base_events.py b/lib-python/3/test/test_asyncio/test_base_events.py
--- a/lib-python/3/test/test_asyncio/test_base_events.py
+++ b/lib-python/3/test/test_asyncio/test_base_events.py
@@ -1588,9 +1588,15 @@
sock.getsockopt(
socket.SOL_SOCKET, socket.SO_REUSEADDR))
if reuseport_supported:
- self.assertFalse(
- sock.getsockopt(
- socket.SOL_SOCKET, socket.SO_REUSEPORT))
+ try:
+ self.assertFalse(
+ sock.getsockopt(
+ socket.SOL_SOCKET, socket.SO_REUSEPORT))
+ except OSError:
+ # Python's socket module was compiled using modern headers
+ # thus defining SO_REUSEPORT but this process is running
+ # under an older kernel that does not support SO_REUSEPORT.
+ reuseport_supported = False
self.assertFalse(
sock.getsockopt(
socket.SOL_SOCKET, socket.SO_BROADCAST))
diff --git a/lib-python/3/test/test_importlib/builtin/test_loader.py b/lib-python/3/test/test_importlib/builtin/test_loader.py
--- a/lib-python/3/test/test_importlib/builtin/test_loader.py
+++ b/lib-python/3/test/test_importlib/builtin/test_loader.py
@@ -1,6 +1,8 @@
from .. import abc
from .. import util
+from importlib.machinery import BuiltinImporter
+
machinery = util.import_importlib('importlib.machinery')
import sys
@@ -14,7 +16,7 @@
def setUp(self):
self.verification = {'__name__': 'errno', '__package__': '',
- '__loader__': self.machinery.BuiltinImporter}
+ '__loader__': BuiltinImporter} # PyPy change
def verify(self, module):
"""Verify that the module matches against what it should have."""
diff --git a/lib-python/3/test/test_importlib/extension/test_loader.py b/lib-python/3/test/test_importlib/extension/test_loader.py
--- a/lib-python/3/test/test_importlib/extension/test_loader.py
+++ b/lib-python/3/test/test_importlib/extension/test_loader.py
@@ -88,6 +88,7 @@
def setUp(self):
self.name = '_testmultiphase'
+ __import__(self.name) # PyPy hack
finder = self.machinery.FileFinder(None)
self.spec = importlib.util.find_spec(self.name)
assert self.spec
@@ -145,7 +146,8 @@
importlib.reload(module)
self.assertIs(ex_class, module.Example)
- def test_try_registration(self):
+ # XXX: PyPy doesn't support the PyState_* functions yet
+ def XXXtest_try_registration(self):
'''Assert that the PyState_{Find,Add,Remove}Module C API doesn't work'''
module = self.load_module()
with self.subTest('PyState_FindModule'):
diff --git a/lib-python/3/test/test_marshal.py b/lib-python/3/test/test_marshal.py
--- a/lib-python/3/test/test_marshal.py
+++ b/lib-python/3/test/test_marshal.py
@@ -271,6 +271,11 @@
if n is not None and n > 4:
n += 10**6
return n
+ def read(self, n): # PyPy calls read(), not readinto()
+ result = super().read(n)
+ if len(result) > 4:
+ result += b'\x00' * (10**6)
+ return result
for value in (1.0, 1j, b'0123456789', '0123456789'):
self.assertRaises(ValueError, marshal.load,
BadReader(marshal.dumps(value)))
@@ -348,7 +353,8 @@
strobj = "abcde"*3
dictobj = {"hello":floatobj, "goodbye":floatobj, floatobj:"hello"}
- def helper3(self, rsample, recursive=False, simple=False):
+ def helper3(self, rsample, recursive=False, simple=False,
+ check_sharing=True, check_non_sharing=True):
#we have two instances
sample = (rsample, rsample)
@@ -358,28 +364,35 @@
n3 = CollectObjectIDs(set(), marshal.loads(s3))
#same number of instances generated
- self.assertEqual(n3, n0)
+ # except in one corner case on top of pypy, for code objects
+ if check_sharing:
+ self.assertEqual(n3, n0)
if not recursive:
#can compare with version 2
s2 = marshal.dumps(sample, 2)
n2 = CollectObjectIDs(set(), marshal.loads(s2))
#old format generated more instances
- self.assertGreater(n2, n0)
+ # except on pypy where equal ints or floats always have
+ # the same id anyway
+ if check_non_sharing:
+ self.assertGreater(n2, n0)
#if complex objects are in there, old format is larger
- if not simple:
+ if check_non_sharing and not simple:
self.assertGreater(len(s2), len(s3))
else:
self.assertGreaterEqual(len(s2), len(s3))
def testInt(self):
self.helper(self.intobj)
- self.helper3(self.intobj, simple=True)
+ self.helper3(self.intobj, simple=True,
+ check_non_sharing=support.check_impl_detail())
def testFloat(self):
self.helper(self.floatobj)
- self.helper3(self.floatobj)
+ self.helper3(self.floatobj,
+ check_non_sharing=support.check_impl_detail())
def testStr(self):
self.helper(self.strobj)
@@ -395,7 +408,7 @@
if __file__.endswith(".py"):
code = compile(code, __file__, "exec")
self.helper(code)
- self.helper3(code)
+ self.helper3(code, check_sharing=support.check_impl_detail())
def testRecursion(self):
d = dict(self.dictobj)
diff --git a/lib-python/3/test/test_pyexpat.py b/lib-python/3/test/test_pyexpat.py
--- a/lib-python/3/test/test_pyexpat.py
+++ b/lib-python/3/test/test_pyexpat.py
@@ -11,7 +11,7 @@
from xml.parsers import expat
from xml.parsers.expat import errors
-from test.support import sortdict
+from test.support import sortdict, impl_detail
class SetAttributeTest(unittest.TestCase):
@@ -446,6 +446,7 @@
self.assertEqual(os.path.basename(entry[0]), filename)
self.assertEqual(entry[2], funcname)
+ @impl_detail("PyPy does not have pyexpat.c", pypy=False)
def test_exception(self):
parser = expat.ParserCreate()
parser.StartElementHandler = self.StartElementHandler
diff --git a/lib-python/3/test/test_stat.py b/lib-python/3/test/test_stat.py
--- a/lib-python/3/test/test_stat.py
+++ b/lib-python/3/test/test_stat.py
@@ -138,6 +138,10 @@
self.assertS_IS("REG", st_mode)
self.assertEqual(modestr, '-r--r--r--')
self.assertEqual(self.statmod.S_IMODE(st_mode), 0o444)
+
+ # If there are only permission bits, no type bytes, a question
+ # mark is rendered in the type field.
+ self.assertEqual(self.statmod.filemode(0o420), '?r---w----')
else:
os.chmod(TESTFN, 0o700)
st_mode, modestr = self.get_mode()
diff --git a/lib-python/3/test/test_sysconfig.py b/lib-python/3/test/test_sysconfig.py
--- a/lib-python/3/test/test_sysconfig.py
+++ b/lib-python/3/test/test_sysconfig.py
@@ -397,9 +397,16 @@
self.assertTrue('linux' in suffix, suffix)
if re.match('(i[3-6]86|x86_64)$', machine):
if ctypes.sizeof(ctypes.c_char_p()) == 4:
- self.assertTrue(suffix.endswith('i386-linux-gnu.so') \
- or suffix.endswith('x86_64-linux-gnux32.so'),
- suffix)
+ self.assertTrue(
+ suffix.endswith((
+ 'i386-linux-gnu.so',
+ 'i486-linux-gnu.so',
+ 'i586-linux-gnu.so',
+ 'i686-linux-gnu.so',
+ 'x86_64-linux-gnux32.so',
+ )),
+ suffix,
+ )
else: # 8 byte pointer size
self.assertTrue(suffix.endswith('x86_64-linux-gnu.so'), suffix)
diff --git a/lib_pypy/_cffi_ssl/README.md b/lib_pypy/_cffi_ssl/README.md
--- a/lib_pypy/_cffi_ssl/README.md
+++ b/lib_pypy/_cffi_ssl/README.md
@@ -5,9 +5,15 @@
it renames the compiled shared object to _pypy_openssl.so (which means
that cryptography can ship their own cffi backend)
-NOTE: currently, we have changed ``_cffi_src/openssl/callbacks.py`` to
-not rely on the CPython C API, and ``_cffi_src/utils.py`` for issue #2575
-(29c9a89359e4). (The first change is now backported.)
+NOTE: currently, we have the following changes:
+
+* ``_cffi_src/openssl/callbacks.py`` to not rely on the CPython C API
+ (this change is now backported)
+
+* ``_cffi_src/utils.py`` for issue #2575 (29c9a89359e4)
+
+* ``_cffi_src/openssl/x509_vfy.py`` for issue #2605 (ca4d0c90f5a1)
+
# Tests?
diff --git a/lib_pypy/_cffi_ssl/_cffi_src/openssl/x509_vfy.py b/lib_pypy/_cffi_ssl/_cffi_src/openssl/x509_vfy.py
--- a/lib_pypy/_cffi_ssl/_cffi_src/openssl/x509_vfy.py
+++ b/lib_pypy/_cffi_ssl/_cffi_src/openssl/x509_vfy.py
@@ -221,9 +221,13 @@
static const long X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM = 0;
static const long X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED = 0;
static const long X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 = 0;
-#if !CRYPTOGRAPHY_LIBRESSL_251_OR_GREATER
+#ifndef X509_V_ERR_HOSTNAME_MISMATCH
static const long X509_V_ERR_HOSTNAME_MISMATCH = 0;
+#endif
+#ifndef X509_V_ERR_EMAIL_MISMATCH
static const long X509_V_ERR_EMAIL_MISMATCH = 0;
+#endif
+#ifndef X509_V_ERR_IP_ADDRESS_MISMATCH
static const long X509_V_ERR_IP_ADDRESS_MISMATCH = 0;
#endif
#endif
diff --git a/lib_pypy/_cffi_ssl/_stdssl/certificate.py b/lib_pypy/_cffi_ssl/_stdssl/certificate.py
--- a/lib_pypy/_cffi_ssl/_stdssl/certificate.py
+++ b/lib_pypy/_cffi_ssl/_stdssl/certificate.py
@@ -173,14 +173,13 @@
return tuple(dn)
-STATIC_BIO_BUF = ffi.new("char[]", 2048)
-
def _bio_get_str(biobuf):
- length = lib.BIO_gets(biobuf, STATIC_BIO_BUF, len(STATIC_BIO_BUF)-1)
+ bio_buf = ffi.new("char[]", 2048)
+ length = lib.BIO_gets(biobuf, bio_buf, len(bio_buf)-1)
if length < 0:
if biobuf: lib.BIO_free(biobuf)
raise ssl_error(None)
- return _str_with_len(STATIC_BIO_BUF, length)
+ return _str_with_len(bio_buf, length)
def _decode_certificate(certificate):
retval = {}
diff --git a/lib_pypy/_ctypes/basics.py b/lib_pypy/_ctypes/basics.py
--- a/lib_pypy/_ctypes/basics.py
+++ b/lib_pypy/_ctypes/basics.py
@@ -82,7 +82,7 @@
return False
def in_dll(self, dll, name):
- return self.from_address(dll._handle.getaddressindll(name))
+ return self.from_address(dll.__pypy_dll__.getaddressindll(name))
def from_buffer(self, obj, offset=0):
size = self._sizeofinstances()
diff --git a/lib_pypy/_ctypes/function.py b/lib_pypy/_ctypes/function.py
--- a/lib_pypy/_ctypes/function.py
+++ b/lib_pypy/_ctypes/function.py
@@ -430,7 +430,7 @@
ffires = restype.get_ffi_argtype()
return _ffi.FuncPtr.fromaddr(ptr, '', ffiargs, ffires, self._flags_)
- cdll = self.dll._handle
+ cdll = self.dll.__pypy_dll__
try:
ffi_argtypes = [argtype.get_ffi_argtype() for argtype in argtypes]
ffi_restype = restype.get_ffi_argtype()
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
@@ -141,6 +141,10 @@
ptr._buffer = tp._ffiarray(1, autofree=True)
ptr._buffer[0] = obj._buffer
result = ptr
+ elif isinstance(obj, bytes):
+ result = tp()
+ result._buffer[0] = memoryview(obj)._pypy_raw_address()
+ return result
elif not (isinstance(obj, _CData) and type(obj)._is_pointer_like()):
raise TypeError("cast() argument 1 must be a pointer, not %s"
% (type(obj),))
diff --git a/lib_pypy/_ctypes/primitive.py b/lib_pypy/_ctypes/primitive.py
--- a/lib_pypy/_ctypes/primitive.py
+++ b/lib_pypy/_ctypes/primitive.py
@@ -61,6 +61,54 @@
pyobj_container = GlobalPyobjContainer()
+def swap_bytes(value, sizeof, typeof, get_or_set):
+ def swap_2():
+ return ((value >> 8) & 0x00FF) | ((value << 8) & 0xFF00)
+
+ def swap_4():
+ return ((value & 0x000000FF) << 24) | \
+ ((value & 0x0000FF00) << 8) | \
+ ((value & 0x00FF0000) >> 8) | \
+ ((value >> 24) & 0xFF)
+
+ def swap_8():
+ return ((value & 0x00000000000000FF) << 56) | \
+ ((value & 0x000000000000FF00) << 40) | \
+ ((value & 0x0000000000FF0000) << 24) | \
+ ((value & 0x00000000FF000000) << 8) | \
+ ((value & 0x000000FF00000000) >> 8) | \
+ ((value & 0x0000FF0000000000) >> 24) | \
+ ((value & 0x00FF000000000000) >> 40) | \
+ ((value >> 56) & 0xFF)
+
+ def swap_double_float(typ):
+ from struct import pack, unpack
+ if get_or_set == 'set':
+ if sys.byteorder == 'little':
+ st = pack(''.join(['>', typ]), value)
+ else:
+ st = pack(''.join(['<', typ]), value)
+ return unpack(typ, st)[0]
+ else:
+ packed = pack(typ, value)
+ if sys.byteorder == 'little':
+ st = unpack(''.join(['>', typ]), packed)
+ else:
+ st = unpack(''.join(['<', typ]), packed)
+ return st[0]
+
+ if typeof in ('c_float', 'c_float_le', 'c_float_be'):
+ return swap_double_float('f')
+ elif typeof in ('c_double', 'c_double_le', 'c_double_be'):
+ return swap_double_float('d')
+ else:
+ if sizeof == 2:
+ return swap_2()
+ elif sizeof == 4:
+ return swap_4()
+ elif sizeof == 8:
+ return swap_8()
+
def generic_xxx_p_from_param(cls, value):
if value is None:
return cls(None)
@@ -265,6 +313,31 @@
def _as_ffi_pointer_(self, ffitype):
return as_ffi_pointer(self, ffitype)
result._as_ffi_pointer_ = _as_ffi_pointer_
+ if name[-2:] != '_p' and name[-3:] not in ('_le', '_be') \
+ and name not in ('c_wchar', '_SimpleCData', 'c_longdouble', 'c_bool', 'py_object'):
+ from sys import byteorder
+ if byteorder == 'big':
+ name += '_le'
+ swapped = self.__new__(self, name, bases, dct)
+ result.__ctype_le__ = swapped
+ result.__ctype_be__ = result
+ swapped.__ctype_be__ = result
+ swapped.__ctype_le__ = swapped
+ else:
+ name += '_be'
+ swapped = self.__new__(self, name, bases, dct)
+ result.__ctype_be__ = swapped
+ result.__ctype_le__ = result
+ swapped.__ctype_le__ = result
+ swapped.__ctype_be__ = swapped
+ from _ctypes import sizeof
+ def _getval(self):
+ return swap_bytes(self._buffer[0], sizeof(self), name, 'get')
+ def _setval(self, value):
+ d = result()
+ d.value = value
+ self._buffer[0] = swap_bytes(d.value, sizeof(self), name, 'set')
+ swapped.value = property(_getval, _setval)
return result
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
@@ -40,6 +40,22 @@
else:
rawfields.append((f[0], f[1]._ffishape_))
+ # hack for duplicate field names
+ already_seen = set()
+ names1 = names
+ names = []
+ for f in names1:
+ if f not in already_seen:
+ names.append(f)
+ already_seen.add(f)
+ already_seen = set()
+ for i in reversed(range(len(rawfields))):
+ if rawfields[i][0] in already_seen:
+ rawfields[i] = (('$DUP%d$%s' % (i, rawfields[i][0]),)
+ + rawfields[i][1:])
+ already_seen.add(rawfields[i][0])
+ # /hack
+
_set_shape(self, rawfields, self._is_union)
fields = {}
@@ -130,6 +146,7 @@
obj._buffer.__setattr__(self.name, arg)
+
def _set_shape(tp, rawfields, is_union=False):
tp._ffistruct_ = _rawffi.Structure(rawfields, is_union,
getattr(tp, '_pack_', 0))
@@ -224,18 +241,26 @@
res.__dict__['_index'] = -1
return res
-
class StructOrUnion(_CData, metaclass=StructOrUnionMeta):
def __new__(cls, *args, **kwds):
from _ctypes import union
- self = super(_CData, cls).__new__(cls)
- if ('_abstract_' in cls.__dict__ or cls is Structure
+ if ('_abstract_' in cls.__dict__ or cls is Structure
or cls is union.Union):
raise TypeError("abstract class")
if hasattr(cls, '_swappedbytes_'):
- raise NotImplementedError("missing in PyPy: structure/union with "
- "swapped (non-native) byte ordering")
+ fields = [None] * len(cls._fields_)
+ for i in range(len(cls._fields_)):
+ if cls._fields_[i][1] == cls._fields_[i][1].__dict__.get('__ctype_be__', None):
+ swapped = cls._fields_[i][1].__dict__.get('__ctype_le__', cls._fields_[i][1])
+ else:
+ swapped = cls._fields_[i][1].__dict__.get('__ctype_be__', cls._fields_[i][1])
+ if len(cls._fields_[i]) < 3:
+ fields[i] = (cls._fields_[i][0], swapped)
+ else:
+ fields[i] = (cls._fields_[i][0], swapped, cls._fields_[i][2])
+ names_and_fields(cls, fields, _CData, cls.__dict__.get('_anonymous_', None))
+ self = super(_CData, cls).__new__(cls)
if hasattr(cls, '_ffistruct_'):
self.__dict__['_buffer'] = self._ffistruct_(autofree=True)
return self
diff --git a/lib_pypy/_curses.py b/lib_pypy/_curses.py
--- a/lib_pypy/_curses.py
+++ b/lib_pypy/_curses.py
@@ -404,14 +404,14 @@
return val
def get_wch(self, *args):
- wch = ffi.new("int[1]")
+ wch = ffi.new("wint_t[1]")
if len(args) == 0:
val = lib.wget_wch(self._win, wch)
elif len(args) == 2:
val = lib.mvwget_wch(self._win, *args, wch)
else:
raise error("get_wch requires 0 or 2 arguments")
- _check_ERR(val, "get_wch"):
+ _check_ERR(val, "get_wch")
return wch[0]
def getkey(self, *args):
diff --git a/lib_pypy/_testmultiphase.c b/lib_pypy/_testmultiphase.c
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_testmultiphase.c
@@ -0,0 +1,627 @@
+/* Copied from CPython's Modules/_testmultiphase.c */
+/***************************************************/
+
+/* Testing module for multi-phase initialization of extension modules (PEP 489)
+ */
+
+#include "Python.h"
+
+/* Example objects */
+typedef struct {
+ PyObject_HEAD
+ PyObject *x_attr; /* Attributes dictionary */
+} ExampleObject;
+
+/* Example methods */
+
+static int
+Example_traverse(ExampleObject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->x_attr);
+ return 0;
+}
+
+static int
+Example_finalize(ExampleObject *self)
+{
+ Py_CLEAR(self->x_attr);
+ return 0;
+}
+
+static PyObject *
+Example_demo(ExampleObject *self, PyObject *args)
+{
+ PyObject *o = NULL;
+ if (!PyArg_ParseTuple(args, "|O:demo", &o))
+ return NULL;
+ if (o != NULL && PyUnicode_Check(o)) {
+ Py_INCREF(o);
+ return o;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+static PyMethodDef Example_methods[] = {
+ {"demo", (PyCFunction)Example_demo, METH_VARARGS,
+ PyDoc_STR("demo() -> None")},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyObject *
+Example_getattro(ExampleObject *self, PyObject *name)
+{
+ if (self->x_attr != NULL) {
+ PyObject *v = PyDict_GetItem(self->x_attr, name);
+ if (v != NULL) {
+ Py_INCREF(v);
+ return v;
+ }
+ }
+ return PyObject_GenericGetAttr((PyObject *)self, name);
+}
+
+static int
+Example_setattr(ExampleObject *self, char *name, PyObject *v)
+{
+ if (self->x_attr == NULL) {
+ self->x_attr = PyDict_New();
+ if (self->x_attr == NULL)
+ return -1;
+ }
+ if (v == NULL) {
+ int rv = PyDict_DelItemString(self->x_attr, name);
+ if (rv < 0)
+ PyErr_SetString(PyExc_AttributeError,
+ "delete non-existing Example attribute");
+ return rv;
+ }
+ else
+ return PyDict_SetItemString(self->x_attr, name, v);
+}
+
+static PyType_Slot Example_Type_slots[] = {
+ {Py_tp_doc, "The Example type"},
+// {Py_tp_finalize, Example_finalize},
+ {Py_tp_traverse, Example_traverse},
+ {Py_tp_getattro, Example_getattro},
+ {Py_tp_setattr, Example_setattr},
+ {Py_tp_methods, Example_methods},
+ {0, 0},
+};
+
+static PyType_Spec Example_Type_spec = {
+ "_testimportexec.Example",
+ sizeof(ExampleObject),
+ 0,
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE,
+ Example_Type_slots
+};
+
+/* Function of two integers returning integer */
+
+PyDoc_STRVAR(testexport_foo_doc,
+"foo(i,j)\n\
+\n\
+Return the sum of i and j.");
+
+static PyObject *
+testexport_foo(PyObject *self, PyObject *args)
+{
+ long i, j;
+ long res;
+ if (!PyArg_ParseTuple(args, "ll:foo", &i, &j))
+ return NULL;
+ res = i + j;
+ return PyLong_FromLong(res);
+}
+
+/* Test that PyState registration fails */
+
+//PyDoc_STRVAR(call_state_registration_func_doc,
+//"register_state(0): call PyState_FindModule()\n\
+//register_state(1): call PyState_AddModule()\n\
+//register_state(2): call PyState_RemoveModule()");
+//
+//static PyObject *
+//call_state_registration_func(PyObject *mod, PyObject *args)
+//{
+// int i, ret;
+// PyModuleDef *def = PyModule_GetDef(mod);
+// if (def == NULL) {
+// return NULL;
+// }
+// if (!PyArg_ParseTuple(args, "i:call_state_registration_func", &i))
+// return NULL;
+// switch (i) {
+// case 0:
+// mod = PyState_FindModule(def);
+// if (mod == NULL) {
+// Py_RETURN_NONE;
+// }
+// return mod;
+// case 1:
+// ret = PyState_AddModule(mod, def);
+// if (ret != 0) {
+// return NULL;
+// }
+// break;
+// case 2:
+// ret = PyState_RemoveModule(def);
+// if (ret != 0) {
+// return NULL;
+// }
+// break;
+// }
+// Py_RETURN_NONE;
+//}
+
+
+static PyType_Slot Str_Type_slots[] = {
+ {Py_tp_base, NULL}, /* filled out in module exec function */
+ {0, 0},
+};
+
+static PyType_Spec Str_Type_spec = {
+ "_testimportexec.Str",
+ 0,
+ 0,
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ Str_Type_slots
+};
+
+static PyMethodDef testexport_methods[] = {
+ {"foo", testexport_foo, METH_VARARGS,
+ testexport_foo_doc},
+// {"call_state_registration_func", call_state_registration_func,
+// METH_VARARGS, call_state_registration_func_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+static int execfunc(PyObject *m)
+{
+ PyObject *temp = NULL;
+
+ /* Due to cross platform compiler issues the slots must be filled
+ * here. It's required for portability to Windows without requiring
+ * C++. */
+ Str_Type_slots[0].pfunc = &PyUnicode_Type;
+
+ /* Add a custom type */
+ temp = PyType_FromSpec(&Example_Type_spec);
+ if (temp == NULL)
+ goto fail;
+ if (PyModule_AddObject(m, "Example", temp) != 0)
+ goto fail;
+
+ /* Add an exception type */
+ temp = PyErr_NewException("_testimportexec.error", NULL, NULL);
+ if (temp == NULL)
+ goto fail;
+ if (PyModule_AddObject(m, "error", temp) != 0)
+ goto fail;
+
+ /* Add Str */
+ temp = PyType_FromSpec(&Str_Type_spec);
+ if (temp == NULL)
+ goto fail;
+ if (PyModule_AddObject(m, "Str", temp) != 0)
+ goto fail;
+
+ if (PyModule_AddIntConstant(m, "int_const", 1969) != 0)
+ goto fail;
+
+ if (PyModule_AddStringConstant(m, "str_const", "something different") != 0)
+ goto fail;
+
+ return 0;
+ fail:
+ return -1;
+}
+
+/* Helper for module definitions; there'll be a lot of them */
+#define TEST_MODULE_DEF(name, slots, methods) { \
+ PyModuleDef_HEAD_INIT, /* m_base */ \
+ name, /* m_name */ \
+ PyDoc_STR("Test module " name), /* m_doc */ \
+ 0, /* m_size */ \
+ methods, /* m_methods */ \
+ slots, /* m_slots */ \
+ NULL, /* m_traverse */ \
+ NULL, /* m_clear */ \
+ NULL, /* m_free */ \
+}
+
+PyModuleDef_Slot main_slots[] = {
+ {Py_mod_exec, execfunc},
+ {0, NULL},
+};
+
+static PyModuleDef main_def = TEST_MODULE_DEF("main", main_slots, testexport_methods);
+
+PyMODINIT_FUNC
+PyInit__testmultiphase(PyObject *spec)
+{
+ return PyModuleDef_Init(&main_def);
+}
+
+
+/**** Importing a non-module object ****/
+
+static PyModuleDef def_nonmodule;
+static PyModuleDef def_nonmodule_with_methods;
+
+/* Create a SimpleNamespace(three=3) */
+static PyObject*
+createfunc_nonmodule(PyObject *spec, PyModuleDef *def)
+{
+ PyObject *dct, *ns, *three;
+
+ if (def != &def_nonmodule && def != &def_nonmodule_with_methods) {
+ PyErr_SetString(PyExc_SystemError, "def does not match");
+ return NULL;
+ }
+
+ dct = PyDict_New();
+ if (dct == NULL)
+ return NULL;
+
+ three = PyLong_FromLong(3);
+ if (three == NULL) {
+ Py_DECREF(dct);
+ return NULL;
+ }
+ PyDict_SetItemString(dct, "three", three);
+ Py_DECREF(three);
+
+ ns = _PyNamespace_New(dct);
+ Py_DECREF(dct);
+ return ns;
+}
+
+static PyModuleDef_Slot slots_create_nonmodule[] = {
+ {Py_mod_create, createfunc_nonmodule},
+ {0, NULL},
+};
+
+static PyModuleDef def_nonmodule = TEST_MODULE_DEF(
+ "_testmultiphase_nonmodule", slots_create_nonmodule, NULL);
+
+PyMODINIT_FUNC
+PyInit__testmultiphase_nonmodule(PyObject *spec)
+{
+ return PyModuleDef_Init(&def_nonmodule);
+}
+
+PyDoc_STRVAR(nonmodule_bar_doc,
+"bar(i,j)\n\
+\n\
+Return the difference of i - j.");
+
+static PyObject *
+nonmodule_bar(PyObject *self, PyObject *args)
+{
+ long i, j;
+ long res;
+ if (!PyArg_ParseTuple(args, "ll:bar", &i, &j))
+ return NULL;
+ res = i - j;
+ return PyLong_FromLong(res);
+}
+
+static PyMethodDef nonmodule_methods[] = {
+ {"bar", nonmodule_bar, METH_VARARGS, nonmodule_bar_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyModuleDef def_nonmodule_with_methods = TEST_MODULE_DEF(
+ "_testmultiphase_nonmodule_with_methods", slots_create_nonmodule, nonmodule_methods);
+
+PyMODINIT_FUNC
+PyInit__testmultiphase_nonmodule_with_methods(PyObject *spec)
+{
+ return PyModuleDef_Init(&def_nonmodule_with_methods);
+}
+
+/**** Non-ASCII-named modules ****/
+
+static PyModuleDef def_nonascii_latin = { \
+ PyModuleDef_HEAD_INIT, /* m_base */
+ "_testmultiphase_nonascii_latin", /* m_name */
+ PyDoc_STR("Module named in Czech"), /* m_doc */
+ 0, /* m_size */
+ NULL, /* m_methods */
+ NULL, /* m_slots */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL, /* m_free */
+};
+
+PyMODINIT_FUNC
+PyInitU__testmultiphase_zkouka_naten_evc07gi8e(PyObject *spec)
+{
+ return PyModuleDef_Init(&def_nonascii_latin);
+}
+
+static PyModuleDef def_nonascii_kana = { \
+ PyModuleDef_HEAD_INIT, /* m_base */
+ "_testmultiphase_nonascii_kana", /* m_name */
+ PyDoc_STR("Module named in Japanese"), /* m_doc */
+ 0, /* m_size */
+ NULL, /* m_methods */
+ NULL, /* m_slots */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL, /* m_free */
+};
+
+PyMODINIT_FUNC
+PyInitU_eckzbwbhc6jpgzcx415x(PyObject *spec)
+{
+ return PyModuleDef_Init(&def_nonascii_kana);
+}
+
+/*** Module with a single-character name ***/
+
+PyMODINIT_FUNC
+PyInit_x(PyObject *spec)
+{
+ return PyModuleDef_Init(&main_def);
+}
+
+/**** Testing NULL slots ****/
+
+static PyModuleDef null_slots_def = TEST_MODULE_DEF(
+ "_testmultiphase_null_slots", NULL, NULL);
+
+PyMODINIT_FUNC
+PyInit__testmultiphase_null_slots(PyObject *spec)
+{
+ return PyModuleDef_Init(&null_slots_def);
+}
+
+/**** Problematic modules ****/
+
+static PyModuleDef_Slot slots_bad_large[] = {
+ {_Py_mod_LAST_SLOT + 1, NULL},
+ {0, NULL},
+};
+
+static PyModuleDef def_bad_large = TEST_MODULE_DEF(
+ "_testmultiphase_bad_slot_large", slots_bad_large, NULL);
+
+PyMODINIT_FUNC
+PyInit__testmultiphase_bad_slot_large(PyObject *spec)
+{
+ return PyModuleDef_Init(&def_bad_large);
+}
+
+static PyModuleDef_Slot slots_bad_negative[] = {
+ {-1, NULL},
+ {0, NULL},
+};
+
+static PyModuleDef def_bad_negative = TEST_MODULE_DEF(
+ "_testmultiphase_bad_slot_negative", slots_bad_negative, NULL);
+
+PyMODINIT_FUNC
+PyInit__testmultiphase_bad_slot_negative(PyObject *spec)
+{
+ return PyModuleDef_Init(&def_bad_negative);
+}
+
+static PyModuleDef def_create_int_with_state = { \
+ PyModuleDef_HEAD_INIT, /* m_base */
+ "create_with_state", /* m_name */
+ PyDoc_STR("Not a PyModuleObject object, but requests per-module state"),
+ 10, /* m_size */
+ NULL, /* m_methods */
+ slots_create_nonmodule, /* m_slots */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL, /* m_free */
+};
+
+PyMODINIT_FUNC
+PyInit__testmultiphase_create_int_with_state(PyObject *spec)
+{
+ return PyModuleDef_Init(&def_create_int_with_state);
+}
+
+
+static PyModuleDef def_negative_size = { \
+ PyModuleDef_HEAD_INIT, /* m_base */
+ "negative_size", /* m_name */
+ PyDoc_STR("PyModuleDef with negative m_size"),
+ -1, /* m_size */
+ NULL, /* m_methods */
+ slots_create_nonmodule, /* m_slots */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL, /* m_free */
+};
+
+PyMODINIT_FUNC
+PyInit__testmultiphase_negative_size(PyObject *spec)
+{
+ return PyModuleDef_Init(&def_negative_size);
+}
+
+
+static PyModuleDef uninitialized_def = TEST_MODULE_DEF("main", main_slots, testexport_methods);
+
+PyMODINIT_FUNC
+PyInit__testmultiphase_export_uninitialized(PyObject *spec)
+{
+ return (PyObject*) &uninitialized_def;
+}
+
+PyMODINIT_FUNC
+PyInit__testmultiphase_export_null(PyObject *spec)
+{
+ return NULL;
+}
+
+PyMODINIT_FUNC
+PyInit__testmultiphase_export_raise(PyObject *spec)
+{
+ PyErr_SetString(PyExc_SystemError, "bad export function");
+ return NULL;
+}
+
+PyMODINIT_FUNC
+PyInit__testmultiphase_export_unreported_exception(PyObject *spec)
+{
+ PyErr_SetString(PyExc_SystemError, "bad export function");
+ return PyModuleDef_Init(&main_def);
+}
+
+static PyObject*
+createfunc_null(PyObject *spec, PyModuleDef *def)
+{
+ return NULL;
+}
+
+PyModuleDef_Slot slots_create_null[] = {
+ {Py_mod_create, createfunc_null},
+ {0, NULL},
+};
+
+static PyModuleDef def_create_null = TEST_MODULE_DEF(
+ "_testmultiphase_create_null", slots_create_null, NULL);
+
+PyMODINIT_FUNC
+PyInit__testmultiphase_create_null(PyObject *spec)
+{
+ return PyModuleDef_Init(&def_create_null);
+}
+
+static PyObject*
+createfunc_raise(PyObject *spec, PyModuleDef *def)
+{
+ PyErr_SetString(PyExc_SystemError, "bad create function");
+ return NULL;
+}
+
+static PyModuleDef_Slot slots_create_raise[] = {
+ {Py_mod_create, createfunc_raise},
+ {0, NULL},
+};
+
+static PyModuleDef def_create_raise = TEST_MODULE_DEF(
+ "_testmultiphase_create_null", slots_create_raise, NULL);
+
+PyMODINIT_FUNC
+PyInit__testmultiphase_create_raise(PyObject *spec)
+{
+ return PyModuleDef_Init(&def_create_raise);
+}
+
+static PyObject*
+createfunc_unreported_exception(PyObject *spec, PyModuleDef *def)
+{
+ PyErr_SetString(PyExc_SystemError, "bad create function");
+ return PyModule_New("foo");
+}
+
+static PyModuleDef_Slot slots_create_unreported_exception[] = {
+ {Py_mod_create, createfunc_unreported_exception},
+ {0, NULL},
+};
+
+static PyModuleDef def_create_unreported_exception = TEST_MODULE_DEF(
+ "_testmultiphase_create_unreported_exception", slots_create_unreported_exception, NULL);
+
+PyMODINIT_FUNC
+PyInit__testmultiphase_create_unreported_exception(PyObject *spec)
+{
+ return PyModuleDef_Init(&def_create_unreported_exception);
+}
+
+static PyModuleDef_Slot slots_nonmodule_with_exec_slots[] = {
+ {Py_mod_create, createfunc_nonmodule},
+ {Py_mod_exec, execfunc},
+ {0, NULL},
+};
+
+static PyModuleDef def_nonmodule_with_exec_slots = TEST_MODULE_DEF(
+ "_testmultiphase_nonmodule_with_exec_slots", slots_nonmodule_with_exec_slots, NULL);
+
+PyMODINIT_FUNC
+PyInit__testmultiphase_nonmodule_with_exec_slots(PyObject *spec)
+{
+ return PyModuleDef_Init(&def_nonmodule_with_exec_slots);
+}
+
+static int
+execfunc_err(PyObject *mod)
+{
+ return -1;
+}
+
+static PyModuleDef_Slot slots_exec_err[] = {
+ {Py_mod_exec, execfunc_err},
+ {0, NULL},
+};
+
+static PyModuleDef def_exec_err = TEST_MODULE_DEF(
+ "_testmultiphase_exec_err", slots_exec_err, NULL);
+
+PyMODINIT_FUNC
+PyInit__testmultiphase_exec_err(PyObject *spec)
+{
+ return PyModuleDef_Init(&def_exec_err);
+}
+
+static int
+execfunc_raise(PyObject *spec)
+{
+ PyErr_SetString(PyExc_SystemError, "bad exec function");
+ return -1;
+}
+
+static PyModuleDef_Slot slots_exec_raise[] = {
+ {Py_mod_exec, execfunc_raise},
+ {0, NULL},
+};
+
+static PyModuleDef def_exec_raise = TEST_MODULE_DEF(
+ "_testmultiphase_exec_raise", slots_exec_raise, NULL);
+
+PyMODINIT_FUNC
+PyInit__testmultiphase_exec_raise(PyObject *mod)
+{
+ return PyModuleDef_Init(&def_exec_raise);
+}
+
+static int
+execfunc_unreported_exception(PyObject *mod)
+{
+ PyErr_SetString(PyExc_SystemError, "bad exec function");
+ return 0;
+}
+
+static PyModuleDef_Slot slots_exec_unreported_exception[] = {
+ {Py_mod_exec, execfunc_unreported_exception},
+ {0, NULL},
+};
+
+static PyModuleDef def_exec_unreported_exception = TEST_MODULE_DEF(
+ "_testmultiphase_exec_unreported_exception", slots_exec_unreported_exception, NULL);
+
+PyMODINIT_FUNC
+PyInit__testmultiphase_exec_unreported_exception(PyObject *spec)
+{
+ return PyModuleDef_Init(&def_exec_unreported_exception);
+}
+
+/*** Helper for imp test ***/
+
+static PyModuleDef imp_dummy_def = TEST_MODULE_DEF("imp_dummy", main_slots, testexport_methods);
+
+PyMODINIT_FUNC
+PyInit_imp_dummy(PyObject *spec)
+{
+ return PyModuleDef_Init(&imp_dummy_def);
+}
diff --git a/lib_pypy/_testmultiphase.py b/lib_pypy/_testmultiphase.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_testmultiphase.py
@@ -0,0 +1,18 @@
+import imp
+import os
+
+try:
+ import cpyext
+except ImportError:
+ raise ImportError("No module named '_testmultiphase'")
+import _pypy_testcapi
+cfile = '_testmultiphase.c'
+thisdir = os.path.dirname(__file__)
+output_dir = _pypy_testcapi.get_hashed_dir(os.path.join(thisdir, cfile))
+try:
+ fp, filename, description = imp.find_module('_test_multiphase', path=[output_dir])
+ with fp:
+ imp.load_module('_testmultiphase', fp, filename, description)
+except ImportError:
+ print('could not find _testmultiphase in %s' % output_dir)
+ _pypy_testcapi.compile_shared('_testmultiphase.c', '_testmultiphase', output_dir)
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
@@ -22,12 +22,27 @@
linklibs = ['tcl', 'tk']
libdirs = []
else:
- for _ver in ['', '8.6', '8.5', '']:
+ # On some Linux distributions, the tcl and tk libraries are
+ # stored in /usr/include, so we must check this case also
+ libdirs = []
+ found = False
+ for _ver in ['', '8.6', '8.5']:
incdirs = ['/usr/include/tcl' + _ver]
linklibs = ['tcl' + _ver, 'tk' + _ver]
- libdirs = []
if os.path.isdir(incdirs[0]):
+ found = True
break
+ if not found:
+ for _ver in ['8.6', '8.5', '']:
+ incdirs = []
+ linklibs = ['tcl' + _ver, 'tk' + _ver]
+ if os.path.isfile(''.join(['/usr/lib/lib', linklibs[1], '.so'])):
+ found = True
+ break
+ if not found:
+ sys.stderr.write("*** TCL libraries not found! Falling back...\n")
+ incdirs = []
+ linklibs = ['tcl', 'tk']
config_ffi = FFI()
config_ffi.cdef("""
diff --git a/lib_pypy/cffi.egg-info/PKG-INFO b/lib_pypy/cffi.egg-info/PKG-INFO
--- a/lib_pypy/cffi.egg-info/PKG-INFO
+++ b/lib_pypy/cffi.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: cffi
-Version: 1.11.0
+Version: 1.11.1
Summary: Foreign Function Interface for Python calling C code.
Home-page: http://cffi.readthedocs.org
Author: Armin Rigo, Maciej Fijalkowski
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,8 +4,8 @@
from .api import FFI
from .error import CDefError, FFIError, VerificationError, VerificationMissing
-__version__ = "1.11.0"
-__version_info__ = (1, 11, 0)
+__version__ = "1.11.1"
+__version_info__ = (1, 11, 1)
# The verifier module file names are based on the CRC32 of a string that
# contains the following version number. It may be older than __version__
diff --git a/lib_pypy/cffi/_cffi_include.h b/lib_pypy/cffi/_cffi_include.h
--- a/lib_pypy/cffi/_cffi_include.h
+++ b/lib_pypy/cffi/_cffi_include.h
@@ -95,6 +95,7 @@
#define _cffi_from_c_ulong PyLong_FromUnsignedLong
#define _cffi_from_c_longlong PyLong_FromLongLong
#define _cffi_from_c_ulonglong PyLong_FromUnsignedLongLong
+#define _cffi_from_c__Bool PyBool_FromLong
#define _cffi_to_c_double PyFloat_AsDouble
#define _cffi_to_c_float PyFloat_AsDouble
diff --git a/lib_pypy/cffi/_embedding.h b/lib_pypy/cffi/_embedding.h
--- a/lib_pypy/cffi/_embedding.h
+++ b/lib_pypy/cffi/_embedding.h
@@ -1,7 +1,12 @@
/***** Support code for embedding *****/
-#if defined(_MSC_VER)
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if defined(_WIN32)
# define CFFI_DLLEXPORT __declspec(dllexport)
#elif defined(__GNUC__)
# define CFFI_DLLEXPORT __attribute__((visibility("default")))
@@ -242,7 +247,7 @@
if (f != NULL && f != Py_None) {
PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME
- "\ncompiled with cffi version: 1.11.0"
+ "\ncompiled with cffi version: 1.11.1"
"\n_cffi_backend module: ", f);
modules = PyImport_GetModuleDict();
mod = PyDict_GetItemString(modules, "_cffi_backend");
@@ -525,3 +530,7 @@
#undef cffi_compare_and_swap
#undef cffi_write_barrier
#undef cffi_read_barrier
+
+#ifdef __cplusplus
+}
+#endif
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
@@ -394,12 +394,17 @@
replace_with = ' ' + replace_with
return self._backend.getcname(cdecl, replace_with)
- def gc(self, cdata, destructor):
+ def gc(self, cdata, destructor, size=0):
"""Return a new cdata object that points to the same
data. Later, when this new cdata object is garbage-collected,
'destructor(old_cdata_object)' will be called.
+
+ The optional 'size' gives an estimate of the size, used to
+ trigger the garbage collection more eagerly. So far only used
+ on PyPy. It tells the GC that the returned object keeps alive
+ roughly 'size' bytes of external memory.
"""
- return self._backend.gcp(cdata, destructor)
+ return self._backend.gcp(cdata, destructor, size)
def _get_cached_btype(self, type):
assert self._lock.acquire(False) is False
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
@@ -1002,7 +1002,7 @@
_weakref_cache_ref = None
- def gcp(self, cdata, destructor):
+ def gcp(self, cdata, destructor, size=0):
if self._weakref_cache_ref is None:
import weakref
class MyRef(weakref.ref):
diff --git a/lib_pypy/cffi/recompiler.py b/lib_pypy/cffi/recompiler.py
--- a/lib_pypy/cffi/recompiler.py
+++ b/lib_pypy/cffi/recompiler.py
@@ -412,6 +412,9 @@
prnt(' }')
prnt(' p[0] = (const void *)0x%x;' % self._version)
prnt(' p[1] = &_cffi_type_context;')
+ prnt('#if PY_MAJOR_VERSION >= 3')
+ prnt(' return NULL;')
+ prnt('#endif')
prnt('}')
# on Windows, distutils insists on putting init_cffi_xyz in
# 'export_symbols', so instead of fighting it, just give up and
@@ -578,7 +581,7 @@
def _convert_expr_from_c(self, tp, var, context):
if isinstance(tp, model.BasePrimitiveType):
- if tp.is_integer_type():
+ if tp.is_integer_type() and tp.name != '_Bool':
return '_cffi_from_c_int(%s, %s)' % (var, tp.name)
elif isinstance(tp, model.UnknownFloatType):
return '_cffi_from_c_double(%s)' % (var,)
diff --git a/lib_pypy/cffi/vengine_cpy.py b/lib_pypy/cffi/vengine_cpy.py
--- a/lib_pypy/cffi/vengine_cpy.py
+++ b/lib_pypy/cffi/vengine_cpy.py
@@ -296,7 +296,7 @@
def _convert_expr_from_c(self, tp, var, context):
if isinstance(tp, model.PrimitiveType):
- if tp.is_integer_type():
+ if tp.is_integer_type() and tp.name != '_Bool':
return '_cffi_from_c_int(%s, %s)' % (var, tp.name)
elif tp.name != 'long double':
return '_cffi_from_c_%s(%s)' % (tp.name.replace(' ', '_'), var)
@@ -872,6 +872,7 @@
#define _cffi_from_c_ulong PyLong_FromUnsignedLong
#define _cffi_from_c_longlong PyLong_FromLongLong
#define _cffi_from_c_ulonglong PyLong_FromUnsignedLongLong
+#define _cffi_from_c__Bool PyBool_FromLong
#define _cffi_to_c_double PyFloat_AsDouble
#define _cffi_to_c_float PyFloat_AsDouble
diff --git a/lib_pypy/pyrepl/historical_reader.py b/lib_pypy/pyrepl/historical_reader.py
--- a/lib_pypy/pyrepl/historical_reader.py
+++ b/lib_pypy/pyrepl/historical_reader.py
@@ -17,7 +17,7 @@
# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-from pyrepl import reader, commands
+from pyrepl import reader, commands, input
from pyrepl.reader import Reader as R
isearch_keymap = tuple(
@@ -215,7 +215,6 @@
isearch_forwards, isearch_backwards, operate_and_get_next]:
self.commands[c.__name__] = c
self.commands[c.__name__.replace('_', '-')] = c
- from pyrepl import input
self.isearch_trans = input.KeymapTranslator(
isearch_keymap, invalid_cls=isearch_end,
character_cls=isearch_add_character)
diff --git a/lib_pypy/pyrepl/reader.py b/lib_pypy/pyrepl/reader.py
--- a/lib_pypy/pyrepl/reader.py
+++ b/lib_pypy/pyrepl/reader.py
@@ -239,6 +239,10 @@
def __init__(self, console):
self.buffer = []
+ # Enable the use of `insert` without a `prepare` call - necessary to
+ # facilitate the tab completion hack implemented for
+ # <https://bugs.python.org/issue25660>.
+ self.pos = 0
self.ps1 = "->> "
self.ps2 = "/>> "
self.ps3 = "|.. "
More information about the pypy-commit
mailing list