Author: Wim Lavrijsen <wlavrij...@lbl.gov> Branch: cppyy-packaging Changeset: r92596:a5393d11a343 Date: 2017-10-03 15:46 -0700 http://bitbucket.org/pypy/pypy/changeset/a5393d11a343/
Log: merge default into branch diff too long, truncating to 2000 out of 9976 lines 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_ziesch...@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_ziesch...@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 reub...@gmail.com + Stanisław Halik Julien Phalip Roman Podoliaka Eli Stevens 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/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/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_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 @@ -142,6 +142,10 @@ ptr._buffer = tp._ffiarray(1, autofree=True) ptr._buffer[0] = obj._buffer result = ptr + elif isinstance(obj, bytes): + result = tp() + result._buffer[0] = buffer(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 & 0x00000000000000FFL) << 56) | \ + ((value & 0x000000000000FF00L) << 40) | \ + ((value & 0x0000000000FF0000L) << 24) | \ + ((value & 0x00000000FF000000L) << 8) | \ + ((value & 0x000000FF00000000L) >> 8) | \ + ((value & 0x0000FF0000000000L) >> 24) | \ + ((value & 0x00FF000000000000L) >> 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) @@ -271,6 +319,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,19 +241,27 @@ 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/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -116,10 +116,20 @@ @builtinify def dump(obj, file, protocol=None): + if protocol > HIGHEST_PROTOCOL: + # use cPickle error message, not pickle.py one + raise ValueError("pickle protocol %d asked for; " + "the highest available protocol is %d" % ( + protocol, HIGHEST_PROTOCOL)) Pickler(file, protocol).dump(obj) @builtinify def dumps(obj, protocol=None): + if protocol > HIGHEST_PROTOCOL: + # use cPickle error message, not pickle.py one + raise ValueError("pickle protocol %d asked for; " + "the highest available protocol is %d" % ( + protocol, HIGHEST_PROTOCOL)) file = StringIO() Pickler(file, protocol).dump(obj) return file.getvalue() 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/_embedding.h b/lib_pypy/cffi/_embedding.h --- a/lib_pypy/cffi/_embedding.h +++ b/lib_pypy/cffi/_embedding.h @@ -247,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"); 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( @@ -214,7 +214,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/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -71,6 +71,8 @@ working_modules.remove("_cppyy") # not tested on win32 if "faulthandler" in working_modules: working_modules.remove("faulthandler") # missing details + if "_vmprof" in working_modules: + working_modules.remove("_vmprof") # FIXME: missing details # The _locale module is needed by site.py on Windows default_modules.add("_locale") diff --git a/pypy/doc/build.rst b/pypy/doc/build.rst --- a/pypy/doc/build.rst +++ b/pypy/doc/build.rst @@ -119,8 +119,15 @@ To run untranslated tests, you need the Boehm garbage collector libgc. -On Debian and Ubuntu, this is the command to install all build-time -dependencies:: +On recent Debian and Ubuntu (like 17.04), this is the command to install +all build-time dependencies:: + + apt-get install gcc make libffi-dev pkg-config zlib1g-dev libbz2-dev \ + libsqlite3-dev libncurses5-dev libexpat1-dev libssl-dev libgdbm-dev \ + tk-dev libgc-dev python-cffi \ + liblzma-dev libncursesw5-dev # these two only needed on PyPy3 + +On older Debian and Ubuntu (12.04 to 16.04):: apt-get install gcc make libffi-dev pkg-config libz-dev libbz2-dev \ libsqlite3-dev libncurses-dev libexpat1-dev libssl-dev libgdbm-dev \ diff --git a/pypy/doc/contributor.rst b/pypy/doc/contributor.rst --- a/pypy/doc/contributor.rst +++ b/pypy/doc/contributor.rst @@ -27,8 +27,8 @@ Wim Lavrijsen Eric van Riet Paap Richard Emslie + Remi Meier Alexander Schremmer - Remi Meier Dan Villiom Podlaski Christiansen Lukas Diekmann Sven Hager @@ -69,6 +69,7 @@ Michael Foord Stephan Diehl Stefano Rivera + Jean-Paul Calderone Stefan Schwarzer Tomek Meka Valentino Volonghi @@ -77,14 +78,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 @@ -123,6 +123,7 @@ Stefan H. Muller Tim Felgentreff Eugene Oden + Dodan Mihai Jeff Terrace Henry Mason Vasily Kuznetsov @@ -149,11 +150,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ś @@ -161,6 +164,7 @@ Victor Stinner Andrews Medina Aaron Iles + p_ziesch...@yahoo.de Toby Watson Daniel Patrick Stuart Williams @@ -171,6 +175,7 @@ Michael Cheng Mikael Schönenberg Stanislaw Halik + Mihnea Saracin Berkin Ilbeyi Gasper Zejn Faye Zhao @@ -181,14 +186,12 @@ Jonathan David Riehl Beatrice During Alex Perry - p_ziesch...@yahoo.de Robert Zaremba Alan McIntyre Alexander Sedov Vaibhav Sood Reuben Cummings Attila Gobi - Alecsandru Patrascu Christopher Pope Tristan Arthur Christian Tismer @@ -210,7 +213,6 @@ Jacek Generowicz Sylvain Thenault Jakub Stasiak - Stefan Beyer Andrew Dalke Alejandro J. Cura Vladimir Kryachko @@ -242,6 +244,7 @@ Christoph Gerum Miguel de Val Borro Artur Lisiecki + afteryu Toni Mattis Laurens Van Houtven Bobby Impollonia @@ -272,6 +275,7 @@ Anna Katrina Dominguez Kim Jin Su Amber Brown + Anthony Sottile Nate Bragg Ben Darnell Juan Francisco Cantero Hurtado @@ -292,12 +296,14 @@ Mike Bayer Rodrigo Araújo Daniil Yarancev + Min RK OlivierBlanvillain Jonas Pfannschmidt Zearin Andrey Churin Dan Crosta reub...@gmail.com + Stanisław Halik Julien Phalip Roman Podoliaka Eli Stevens diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -429,7 +429,8 @@ * the ``__builtins__`` name is always referencing the ``__builtin__`` module, never a dictionary as it sometimes is in CPython. Assigning to - ``__builtins__`` has no effect. + ``__builtins__`` has no effect. (For usages of tools like + RestrictedPython, see `issue #2653`_.) * directly calling the internal magic methods of a few built-in types with invalid arguments may have a slightly different result. For @@ -535,7 +536,12 @@ or ``float`` subtypes. Currently PyPy does not support the ``__class__`` attribute assignment for any non heaptype subtype. +* In PyPy, module and class dictionaries are optimized under the assumption + that deleting attributes from them are rare. Because of this, e.g. + ``del foo.bar`` where ``foo`` is a module (or class) that contains the + function ``bar``, is significantly slower than CPython. + .. _`is ignored in PyPy`: http://bugs.python.org/issue14621 .. _`little point`: http://events.ccc.de/congress/2012/Fahrplan/events/5152.en.html .. _`#2072`: https://bitbucket.org/pypy/pypy/issue/2072/ - +.. _`issue #2653`: https://bitbucket.org/pypy/pypy/issues/2653/ diff --git a/pypy/doc/index-of-release-notes.rst b/pypy/doc/index-of-release-notes.rst --- a/pypy/doc/index-of-release-notes.rst +++ b/pypy/doc/index-of-release-notes.rst @@ -6,6 +6,7 @@ .. toctree:: + release-v5.9.0.rst release-v5.8.0.rst release-v5.7.1.rst release-v5.7.0.rst diff --git a/pypy/doc/index-of-whatsnew.rst b/pypy/doc/index-of-whatsnew.rst --- a/pypy/doc/index-of-whatsnew.rst +++ b/pypy/doc/index-of-whatsnew.rst @@ -7,6 +7,7 @@ .. toctree:: whatsnew-head.rst + whatsnew-pypy2-5.9.0.rst whatsnew-pypy2-5.8.0.rst whatsnew-pypy2-5.7.0.rst whatsnew-pypy2-5.6.0.rst @@ -36,6 +37,7 @@ .. toctree:: whatsnew-pypy3-head.rst + whatsnew-pypy3-5.9.0.rst whatsnew-pypy3-5.8.0.rst whatsnew-pypy3-5.7.0.rst diff --git a/pypy/doc/release-v5.9.0.rst b/pypy/doc/release-v5.9.0.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/release-v5.9.0.rst @@ -0,0 +1,217 @@ +===================================== +PyPy2.7 and PyPy3.5 v5.9 dual release +===================================== + +The PyPy team is proud to release both PyPy2.7 v5.9 (an interpreter supporting +Python 2.7 syntax), and a beta-quality PyPy3.5 v5.9 (an interpreter for Python +3.5 syntax). The two releases are both based on much the same codebase, thus +the dual release. Note that PyPy3.5 supports Linux 64bit only for now. + +This new PyPy2.7 release includes the upstream stdlib version 2.7.13, and +PyPy3.5 includes the upstream stdlib version 3.5.3. + +NumPy and Pandas now work on PyPy2.7 (together with Cython 0.27.1). Issues +that appeared as excessive memory +use were cleared up and other incompatibilities were resolved. The C-API +compatibility layer does slow down code which crosses the python-c interface +often, we have ideas on how it could be improved, and still recommend +using pure python on PyPy or interfacing via CFFI_. Many other modules +based on C-API exentions now work on PyPy as well. + +Cython 0.27.1 (released very recently) supports more projects with PyPy, both +on PyPy2.7 and PyPy3.5 beta. Note version **0.27.1** is now the minimum +version that supports this version of PyPy, due to some interactions with +updated C-API interface code. + +We optimized the JSON parser for recurring string keys, which should decrease +memory use to 50% and increase parsing speed by up to 15% for large JSON files +with many repeating dictionary keys (which is quite common). + +CFFI_, which is part of the PyPy release, has been updated to 1.11.1, +improving an already great package for interfacing with C. CFFI now supports +complex arguments in API mode, as well as ``char16_t`` and ``char32_t`` and has +improved support for callbacks. + +Please let us know if your use case is slow, we have ideas how to make things +faster but need real-world examples (not micro-benchmarks) of problematic code. + +Work sponsored by a Mozilla grant_ continues on PyPy3.5; numerous fixes from +CPython were ported to PyPy. Of course the bug fixes and performance enhancements +mentioned above are part of both PyPy2.7 and PyPy3.5 beta. + +As always, this release fixed many other issues and bugs raised by the +growing community of PyPy users. We strongly recommend updating. + +You can download the v5.9 releases here: + + http://pypy.org/download.html + +We would like to thank our donors for the continued support of the PyPy +project. + +We would also like to thank our contributors and +encourage new people to join the project. PyPy has many +layers and we need help with all of them: `PyPy`_ and `RPython`_ documentation +improvements, tweaking popular `modules`_ to run on pypy, or general `help`_ +with making RPython's JIT even better. + +.. _vmprof: http://vmprof.readthedocs.io +.. _CFFI: https://cffi.readthedocs.io/en/latest/whatsnew.html +.. _grant: https://morepypy.blogspot.com/2016/08/pypy-gets-funding-from-mozilla-for.html +.. _`PyPy`: index.html +.. _`RPython`: https://rpython.readthedocs.org +.. _`modules`: project-ideas.html#make-more-python-modules-pypy-friendly +.. _`help`: project-ideas.html + +What is PyPy? +============= + +PyPy is a very compliant Python interpreter, almost a drop-in replacement for +CPython 2.7 and CPython 3.5. It's fast (`PyPy and CPython 2.7.x`_ performance comparison) +due to its integrated tracing JIT compiler. + +We also welcome developers of other `dynamic languages`_ to see what RPython +can do for them. + +The PyPy 2.7 release supports: + + * **x86** machines on most common operating systems + (Linux 32/64 bits, Mac OS X 64 bits, Windows 32 bits, OpenBSD, FreeBSD) + + * newer **ARM** hardware (ARMv6 or ARMv7, with VFPv3) running Linux, + + * big- and little-endian variants of **PPC64** running Linux, + + * **s390x** running Linux + +.. _`PyPy and CPython 2.7.x`: http://speed.pypy.org +.. _`dynamic languages`: http://rpython.readthedocs.io/en/latest/examples.html + +Highlights of the PyPy2.7, cpyext, and RPython changes (since 5.8 released June, 2017) +====================================================================================== + +See also issues that were resolved_ + +Note that these are also merged into PyPy 3.5 + +* New features and cleanups + + * Add support for ``PyFrozenSet_New``, ``PyObject_HashNotImplemented``, + ``PyObject_Print(NULL, ...)``, ``PyObject_RichCompareBool(a, a, ...)``, + ``PyType_IS_GC`` (does nothing), ``PyUnicode_FromFormat`` + * ctypes ``char_p`` and ``unichar_p`` indexing now CPython compatible + * ``gcdump`` now reports largest object + * More complete support in the ``_curses`` CFFI module + * Add cPickle.Unpickler.find_global (issue 1853_) + * Fix ``PyErr_Fetch`` + ``PyErr_NormalizeException`` with no exception set + * Simplify ``gc.get_referrers()`` to return the opposite of ``gc.get_referents()`` + * Update RevDB to version pypy2.7-v5.6.2 + * Previously, ``instance.method`` would return always the same bound method + object, when gotten from the same instance (as far as ``is`` and ``id()`` + can tell). CPython doesn't do that. Now PyPy, like CPython, returns a + different bound method object every time. For ``type.method``, PyPy2 still + returns always the same *unbound* method object; CPython does it for built-in + types but not for user-defined types + * Link to disable PaX protection for the JIT when needed + * Update build instructions and an rarely used Makefile + * Recreate support for using leakfinder in cpyext tests which had suffered + bit-rot, disable due to many false positives + * Add more functionality to ``sysconfig`` + * Added ``_swappedbytes_`` support for ``ctypes.Structure`` + * Better support the ``inspect`` module on ``frames`` + +* Bug Fixes + + * Fix issue 2592_ - cpyext ``PyListObject.pop``, ``pop_end`` must return a value + * Implement ``PyListOjbect.getstorage_copy`` + * Fix for ``reversed(dictproxy)`` issue 2601_ + * Fix for duplicate names in ctypes' ``_fields__``, issue 2621_ + * Update built-in ``pyexpat`` module on win32 to use UTF-8 version not UTF-16 + * ``gc.get_objects`` now handles objects with finalizers more consistently + * Fixed memory leak in ``SSLContext.getpeercert`` returning validated + certificates and ``SSLContext.get_ca_certs(binary_mode=True)`` + (_get_crl_dp) `CPython issue 29738`_ + +* Performance improvements: + + * Improve performance of ``bytearray.extend`` by rewriting portions in app-level + * Optimize list accesses with constant indexes better by retaining more + information about them + * Add a jit driver for ``array.count`` and ``array.index`` + * Improve information retained in a bridge wrt ``array`` + * Move some dummy CAPI functions and ``Py*_Check`` functions from RPython into + pure C macros + * In the fast ``zip(intlist1, intlist2)`` implementation, don't wrap and unwrap + all the ints + * Cache string keys that occur in JSON dicts, as they are likely to repeat + +* RPython improvements + + * Do not preallocate a RPython list if we only know an upper bound on its size + * Issue 2590_: fix the bounds in the GC when allocating a lot of objects with finalizers + * Replace magical NOT RPYTHON comment with a decorator + * Implement ``socket.sendmsg()``/``.recvmsg()`` for py3.5 + * Add ``memory_pressure`` for ``_SSLSocket`` objects + +* Degredations + + * Disable vmprof on win32, due to upstream changes that break the internal ``_vmprof`` module + +.. _here: cpython_differences.html +.. _1853: https://bitbucket.org/pypy/pypy/issues/1853 +.. _2592: https://bitbucket.org/pypy/pypy/issues/2592 +.. _2590: https://bitbucket.org/pypy/pypy/issues/2590 +.. _2621: https://bitbucket.org/pypy/pypy/issues/2621 + +Highlights of the PyPy3.5 release (since 5.8 beta released June 2017) +====================================================================== + +* New features + + * Add support for ``_PyNamespace_New``, ``PyMemoryView_FromMemory``, + ``Py_EnterRecursiveCall`` raising RecursionError, ``PyObject_LengthHint``, + ``PyUnicode_FromKindAndData``, ``PyDict_SetDefault``, ``PyGenObject``, + ``PyGenObject``, ``PyUnicode_Substring``, ``PyLong_FromUnicodeObject`` + * Implement ``PyType_FromSpec`` (PEP 384) and fix issues with PEP 489 support + * Support the new version of ``os.stat()`` on win32 + * Use ``stat3()`` on Posix + * Accept buffer objects as filenames, except for `oslistdir`` + * Make slices of array ``memoryview`` s usable as writable buffers if contiguous + * Better handling of ``'%s'`` formatting for byte strings which might be utf-8 encoded + * Update the macros ``Py_DECREF`` and similar to use the CPython 3.5 version + * Ensure that ``mappingproxy`` is recognised as a mapping, not a sequence + * Enable PGO for CLang + * Rework ``cppyy`` packaging and rename the backend to ``_cppyy`` + * Support for libressl 2.5.4 + * Mirror CPython ``classmethod __reduce__`` which fixes pickling test + * Use utf-8 for ``readline`` history file + * Allow assigning ``'__class__'`` between ``ModuleType`` and its subclasses + * Add async slot functions in cpyext + +* Bug Fixes + + * Try to make ``openssl`` CFFI bindings more general and future-proof + * Better support ``importlib`` by only listing built-in modules in ``sys.builtin`` + * Add ``memory_pressure`` to large CFFI allocations in ``_lzma``, issue 2579_ + * Fix for ``reversed(mapping object)`` issue 2601_ + * Fixing regression with non-started generator receiving non-``None``, should + always raise ``TypeError`` + * ``itertools.islice``: use same logic as CPython, fixes 2643_ + +* Performance improvements: + + * + +* The following features of Python 3.5 are not implemented yet in PyPy: + + * PEP 442: Safe object finalization + +.. _resolved: whatsnew-pypy2-5.9.0.html +.. _2579: https://bitbucket.org/pypy/pypy/issues/2579 +.. _2601: https://bitbucket.org/pypy/pypy/issues/2601 +.. _2643: https://bitbucket.org/pypy/pypy/issues/2643 +.. _CPython issue 29738: https://bugs.python.org/issue29738 + +Please update, and continue to help us make PyPy better. + +Cheers diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -1,62 +1,8 @@ -========================== -What's new in PyPy2.7 5.9+ -========================== - -.. this is a revision shortly after release-pypy2.7-v5.8.0 -.. startrev: 558bd00b3dd8 - -In previous versions of PyPy, ``instance.method`` would return always -the same bound method object, when gotten out of the same instance (as -far as ``is`` and ``id()`` can tell). CPython doesn't do that. Now -PyPy, like CPython, returns a different bound method object every time. -For ``type.method``, PyPy2 still returns always the same *unbound* -method object; CPython does it for built-in types but not for -user-defined types. - -.. branch: cffi-complex -.. branch: cffi-char16-char32 - -The two ``cffi-*`` branches are part of the upgrade to cffi 1.11. - -.. branch: ctypes_char_indexing - -Indexing into char* behaves differently than CPython - -.. branch: vmprof-0.4.8 - -Improve and fix issues with vmprof - -.. branch: issue-2592 - -CPyext PyListObject.pop must return the value - -.. branch: cpyext-hash_notimpl - -If ``tp_hash`` is ``PyObject_HashNotImplemented``, set ``obj.__dict__['__hash__']`` to None - -.. branch: cppyy-packaging - -Renaming of ``cppyy`` to ``_cppyy``. -The former is now an external package installable with ``pip install cppyy``. - -.. branch: Enable_PGO_for_clang - -.. branch: nopax - -At the end of translation, run ``attr -q -s pax.flags -V m`` on -PAX-enabled systems on the produced binary. This seems necessary -because PyPy uses a JIT. - -.. branch: pypy_bytearray - -Improve ``bytearray`` performance (backported from py3.5) - -.. branch: gc-del-limit-growth - -Fix the bounds in the GC when allocating a lot of objects with finalizers, -fixes issue #2590 - -.. branch: arrays-force-less - -Small improvement to optimize list accesses with constant indexes better by -throwing away information about them less eagerly. +=========================== +What's new in PyPy2.7 5.10+ +=========================== + +.. this is a revision shortly after release-pypy2.7-v5.9.0 +.. startrev:d56dadcef996 + + diff --git a/pypy/doc/whatsnew-pypy2-5.9.0.rst b/pypy/doc/whatsnew-pypy2-5.9.0.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/whatsnew-pypy2-5.9.0.rst @@ -0,0 +1,96 @@ +========================= +What's new in PyPy2.7 5.9 +========================= + +.. this is a revision shortly after release-pypy2.7-v5.8.0 +.. startrev: 558bd00b3dd8 + +In previous versions of PyPy, ``instance.method`` would return always +the same bound method object, when gotten out of the same instance (as +far as ``is`` and ``id()`` can tell). CPython doesn't do that. Now +PyPy, like CPython, returns a different bound method object every time. +For ``type.method``, PyPy2 still returns always the same *unbound* +method object; CPython does it for built-in types but not for +user-defined types. + +.. branch: cffi-complex +.. branch: cffi-char16-char32 + +The two ``cffi-*`` branches are part of the upgrade to cffi 1.11. + +.. branch: ctypes_char_indexing + +Indexing into char* behaves differently than CPython + +.. branch: vmprof-0.4.8 + +Improve and fix issues with vmprof + +.. branch: issue-2592 + +CPyext PyListObject.pop must return the value + +.. branch: cpyext-hash_notimpl + +If ``tp_hash`` is ``PyObject_HashNotImplemented``, set ``obj.__dict__['__hash__']`` to None + +.. branch: cppyy-packaging + +Renaming of ``cppyy`` to ``_cppyy``. +The former is now an external package installable with ``pip install cppyy``. + +.. branch: Enable_PGO_for_clang + +.. branch: nopax + +At the end of translation, run ``attr -q -s pax.flags -V m`` on +PAX-enabled systems on the produced binary. This seems necessary +because PyPy uses a JIT. + +.. branch: pypy_bytearray + +Improve ``bytearray`` performance (backported from py3.5) + +.. branch: gc-del-limit-growth + +Fix the bounds in the GC when allocating a lot of objects with finalizers, +fixes issue #2590 + +.. branch: arrays-force-less + +Small improvement to optimize list accesses with constant indexes better by +throwing away information about them less eagerly. + + +.. branch: getarrayitem-into-bridges + +More information is retained into a bridge: knowledge about the content of +arrays (at fixed indices) is stored in guards (and thus available at the +beginning of bridges). Also, some better feeding of information about known +fields of constant objects into bridges. + +.. branch: cpyext-leakchecking + +Add support for leakfinder in cpyext tests (disabled for now, due to too many +failures). + +.. branch: pypy_swappedbytes + +Added ``_swappedbytes_`` support for ``ctypes.Structure`` + +.. branch: pycheck-macros + +Convert many Py*_Check cpyext functions into macros, like CPython. + +.. branch: py_ssize_t + +Explicitly use Py_ssize_t as the Signed type in pypy c-api + +.. branch: cpyext-jit + +Differentiate the code to call METH_NOARGS, METH_O and METH_VARARGS in cpyext: +this allows to write specialized code which is much faster than previous +completely generic version. Moreover, let the JIT to look inside the cpyext +module: the net result is that cpyext calls are up to 7x faster. However, this +is true only for very simple situations: in all real life code, we are still +much slower than CPython (more optimizations to come) diff --git a/pypy/doc/whatsnew-pypy3-5.9.0.rst b/pypy/doc/whatsnew-pypy3-5.9.0.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/whatsnew-pypy3-5.9.0.rst @@ -0,0 +1,7 @@ +======================= +What's new in PyPy3 5.9 +======================= + +.. this is the revision after release-pypy3.5-5.8 +.. startrev: afbf09453369 + diff --git a/pypy/doc/whatsnew-pypy3-head.rst b/pypy/doc/whatsnew-pypy3-head.rst --- a/pypy/doc/whatsnew-pypy3-head.rst +++ b/pypy/doc/whatsnew-pypy3-head.rst @@ -1,7 +1,7 @@ ========================= -What's new in PyPy3 5.7+ +What's new in PyPy3 5.9+ ========================= -.. this is the revision after release-pypy3.3-5.7.x was branched -.. startrev: afbf09453369 +.. this is the revision after release-pypy3.5-5.9 +.. startrev: be41e3ac0a29 diff --git a/pypy/doc/windows.rst b/pypy/doc/windows.rst --- a/pypy/doc/windows.rst +++ b/pypy/doc/windows.rst @@ -114,12 +114,15 @@ INCLUDE, LIB and PATH (for DLLs) environment variables appropriately. -Abridged method (for -Ojit builds using Visual Studio 2008) ------------------------------------------------------------ +Abridged method (using Visual Studio 2008) +------------------------------------------ Download the versions of all the external packages from +https://bitbucket.org/pypy/pypy/downloads/local_59.zip +(for post-5.8 builds) with sha256 checksum +``6344230e90ab7a9cb84efbae1ba22051cdeeb40a31823e0808545b705aba8911`` https://bitbucket.org/pypy/pypy/downloads/local_5.8.zip -(for post-5.7.1 builds) with sha256 checksum +(to reproduce 5.8 builds) with sha256 checksum ``fbe769bf3a4ab6f5a8b0a05b61930fc7f37da2a9a85a8f609cf5a9bad06e2554`` or https://bitbucket.org/pypy/pypy/downloads/local_2.4.zip (for 2.4 release and later) or @@ -135,8 +138,8 @@ Now you should be good to go. If you choose this method, you do not need to download/build anything else. -Nonabrided method (building from scratch) ------------------------------------------ +Nonabridged method (building from scratch) +------------------------------------------ If you want to, you can rebuild everything from scratch by continuing. @@ -209,17 +212,85 @@ The expat XML parser ~~~~~~~~~~~~~~~~~~~~ -Download the source code of expat on sourceforge: -https://github.com/libexpat/libexpat/releases and extract it in the base directory. -Version 2.1.1 is known to pass tests. Then open the project file ``expat.dsw`` -with Visual Studio; follow the instruction for converting the project files, -switch to the "Release" configuration, use the ``expat_static`` project, -reconfigure the runtime for Multi-threaded DLL (/MD) and build. Do the same for -the ``expat`` project to build the ``expat.dll`` (for tests via ll2ctypes) +CPython compiles expat from source as part of the build. PyPy uses the same +code base, but expects to link to a static lib of expat. Here are instructions +to reproduce the static lib in version 2.2.4. -Then, copy the file ``win32\bin\release\libexpat.lib`` into -LIB, and both ``lib\expat.h`` and ``lib\expat_external.h`` in -INCLUDE, and ``win32\bin\release\libexpat.dll`` into PATH. +Download the source code of expat: https://github.com/libexpat/libexpat. +``git checkout`` the proper tag, in this case ``R_2_2_4``. Run +``vcvars.bat`` to set up the visual compiler tools, and CD into the source +directory. Create a file ``stdbool.h`` with the content + +.. code-block:: c + + #pragma once + + #define false 0 + #define true 1 + + #define bool int + +and put it in a place on the ``INCLUDE`` path, or create it in the local +directory and add ``.`` to the ``INCLUDE`` path:: + + SET INCLUDE=%INCLUDE%;. + +Then compile all the ``*.c`` file into ``*.obj``:: + + cl.exe /nologo /MD /O2 *c /c + rem for debug + cl.exe /nologo /MD /O0 /Ob0 /Zi *c /c + +You may need to move some variable declarations to the beginning of the +function, to be compliant with C89 standard. Here is the diff for version 2.2.4 + +.. code-block:: diff + + diff --git a/expat/lib/xmltok.c b/expat/lib/xmltok.c + index 007aed0..a2dcaad 100644 + --- a/expat/lib/xmltok.c + +++ b/expat/lib/xmltok.c + @@ -399,19 +399,21 @@ utf8_toUtf8(const ENCODING *UNUSED_P(enc), + /* Avoid copying partial characters (due to limited space). */ + const ptrdiff_t bytesAvailable = fromLim - *fromP; + const ptrdiff_t bytesStorable = toLim - *toP; + + const char * fromLimBefore; + + ptrdiff_t bytesToCopy; + if (bytesAvailable > bytesStorable) { + fromLim = *fromP + bytesStorable; + output_exhausted = true; + } + + /* Avoid copying partial characters (from incomplete input). */ + - const char * const fromLimBefore = fromLim; + + fromLimBefore = fromLim; + align_limit_to_full_utf8_characters(*fromP, &fromLim); + if (fromLim < fromLimBefore) { + input_incomplete = true; + } + + - const ptrdiff_t bytesToCopy = fromLim - *fromP; + + bytesToCopy = fromLim - *fromP; + memcpy((void *)*toP, (const void *)*fromP, (size_t)bytesToCopy); + *fromP += bytesToCopy; + *toP += bytesToCopy; + + +Create ``libexpat.lib`` (for translation) and ``libexpat.dll`` (for tests):: + + cl /LD *.obj libexpat.def /Felibexpat.dll + rem for debug + rem cl /LDd /Zi *.obj libexpat.def /Felibexpat.dll + + rem this will override the export library created in the step above + rem but tests do not need the export library, they load the dll dynamically + lib *.obj /out:libexpat.lib + +Then, copy + +- ``libexpat.lib`` into LIB +- both ``lib\expat.h`` and ``lib\expat_external.h`` in INCLUDE +- ``libexpat.dll`` into PATH The OpenSSL library @@ -363,7 +434,7 @@ It is probably not too much work if the goal is only to get a translated PyPy executable, and to run all tests before translation. But you need to start somewhere, and you should start with some tests in -rpython/translator/c/test/, like ``test_standalone.py`` and +``rpython/translator/c/test/``, like ``test_standalone.py`` and ``test_newgc.py``: try to have them pass on top of CPython64/64. Keep in mind that this runs small translations, and some details may go @@ -373,7 +444,7 @@ should be something like ``long long``. What is more generally needed is to review all the C files in -rpython/translator/c/src for the word ``long``, because this means a +``rpython/translator/c/src`` for the word ``long``, because this means a 32-bit integer even on Win64. Replace it with ``Signed`` most of the times. You can replace one with the other without breaking anything on any other platform, so feel free to. diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1,4 +1,5 @@ import sys +import py from rpython.rlib.cache import Cache from rpython.tool.uid import HUGEVAL_BYTES @@ -1338,8 +1339,22 @@ self.setitem(w_globals, w_key, self.builtin) return statement.exec_code(self, w_globals, w_locals) + @not_rpython + def appdef(self, source): + '''Create interp-level function object from app-level source. + + The source should be in the same format as for space.appexec(): + """(foo, bar): return 'baz'""" + ''' + source = source.lstrip() + assert source.startswith('('), "incorrect header in:\n%s" % (source,) + source = py.code.Source("def anonymous%s\n" % source) + w_glob = self.newdict(module=True) + self.exec_(str(source), w_glob, w_glob) + return self.getitem(w_glob, self.newtext('anonymous')) + @specialize.arg(2) - def appexec(self, posargs_w, source): + def appexec(self, posargs_w, source, cache=True): """ return value from executing given source at applevel. The source must look like '''(x, y): @@ -1347,7 +1362,11 @@ return result ''' """ - w_func = self.fromcache(AppExecCache).getorbuild(source) + if cache: + w_func = self.fromcache(AppExecCache).getorbuild(source) + else: + # NB: since appdef() is not-RPython, using cache=False also is. + w_func = self.appdef(source) args = Arguments(self, list(posargs_w)) return self.call_args(w_func, args) @@ -1423,7 +1442,7 @@ length = 1 return start, stop, step, length - def getindex_w(self, w_obj, w_exception, objdescr=None): + def getindex_w(self, w_obj, w_exception, objdescr=None, errmsg=None): """Return w_obj.__index__() as an RPython int. If w_exception is None, silently clamp in case of overflow; else raise w_exception. @@ -1433,8 +1452,10 @@ except OperationError as err: if objdescr is None or not err.match(self, self.w_TypeError): raise - raise oefmt(self.w_TypeError, "%s must be an integer, not %T", - objdescr, w_obj) + if errmsg is None: + errmsg = " must be an integer" + raise oefmt(self.w_TypeError, "%s%s, not %T", + objdescr, errmsg, w_obj) try: # allow_conversion=False it's not really necessary because the # return type of __index__ is already checked by space.index(), @@ -1610,12 +1631,15 @@ # return text_w(w_obj) or None return None if self.is_none(w_obj) else self.text_w(w_obj) + @specialize.argtype(1) def bytes_w(self, w_obj): """ Takes an application level :py:class:`bytes` (on PyPy2 this equals `str`) and returns a rpython byte string. """ + assert w_obj is not None return w_obj.str_w(self) + @specialize.argtype(1) def text_w(self, w_obj): """ PyPy2 takes either a :py:class:`str` and returns a rpython byte string, or it takes an :py:class:`unicode` @@ -1625,6 +1649,7 @@ On PyPy3 it takes a :py:class:`str` and it will return an utf-8 encoded rpython string. """ + assert w_obj is not None return w_obj.str_w(self) @not_rpython # tests only; should be replaced with bytes_w or text_w @@ -1667,12 +1692,14 @@ if len(string) != 1: raise oefmt(self.w_ValueError, "string must be of size 1") return string[0] - value = self.getindex_w(w_obj, None) + value = self.getindex_w(w_obj, None, "", + "an integer or string of size 1 is required") if not 0 <= value < 256: # this includes the OverflowError in case the long is too large raise oefmt(self.w_ValueError, "byte must be in range(0, 256)") return chr(value) + @specialize.argtype(1) def int_w(self, w_obj, allow_conversion=True): """ Unwrap an app-level int object into an interpret-level int. @@ -1685,26 +1712,35 @@ If allow_conversion=False, w_obj needs to be an app-level int or a subclass. """ + assert w_obj is not None return w_obj.int_w(self, allow_conversion) + @specialize.argtype(1) def int(self, w_obj): + assert w_obj is not None return w_obj.int(self) + @specialize.argtype(1) def uint_w(self, w_obj): + assert w_obj is not None return w_obj.uint_w(self) + @specialize.argtype(1) def bigint_w(self, w_obj, allow_conversion=True): """ Like int_w, but return a rlib.rbigint object and call __long__ if allow_conversion is True. """ + assert w_obj is not None return w_obj.bigint_w(self, allow_conversion) + @specialize.argtype(1) def float_w(self, w_obj, allow_conversion=True): """ Like int_w, but return an interp-level float and call __float__ if allow_conversion is True. """ + assert w_obj is not None return w_obj.float_w(self, allow_conversion) def realtext_w(self, w_obj): @@ -1714,7 +1750,9 @@ raise oefmt(self.w_TypeError, "argument must be a string") return self.bytes_w(w_obj) + @specialize.argtype(1) def unicode_w(self, w_obj): + assert w_obj is not None return w_obj.unicode_w(self) def unicode0_w(self, w_obj): @@ -1739,7 +1777,9 @@ # This is here mostly just for gateway.int_unwrapping_space_method(). return bool(self.int_w(w_obj)) + @specialize.argtype(1) def ord(self, w_obj): + assert w_obj is not None return w_obj.ord(self) # This is all interface for gateway.py. @@ -1926,15 +1966,7 @@ class AppExecCache(SpaceCache): @not_rpython def build(cache, source): - space = cache.space - # XXX will change once we have our own compiler - import py - source = source.lstrip() - assert source.startswith('('), "incorrect header in:\n%s" % (source,) - source = py.code.Source("def anonymous%s\n" % source) - w_glob = space.newdict(module=True) - space.exec_(str(source), w_glob, w_glob) - return space.getitem(w_glob, space.newtext('anonymous')) + return cache.space.appdef(source) # Table describing the regular part of the interface of object spaces, diff --git a/pypy/interpreter/test/test_typedef.py b/pypy/interpreter/test/test_typedef.py --- a/pypy/interpreter/test/test_typedef.py +++ b/pypy/interpreter/test/test_typedef.py @@ -419,3 +419,7 @@ def f(): return x assert f.__closure__[0].cell_contents is x + + def test_get_with_none_arg(self): + raises(TypeError, type.__dict__['__mro__'].__get__, None) + raises(TypeError, type.__dict__['__mro__'].__get__, None, None) diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -297,6 +297,8 @@ if (space.is_w(w_obj, space.w_None) and not space.is_w(w_cls, space.type(space.w_None))): #print self, w_obj, w_cls + if space.is_w(w_cls, space.w_None): + raise oefmt(space.w_TypeError, "__get__(None, None) is invalid") return self else: try: diff --git a/pypy/module/__builtin__/descriptor.py b/pypy/module/__builtin__/descriptor.py --- a/pypy/module/__builtin__/descriptor.py +++ b/pypy/module/__builtin__/descriptor.py @@ -16,24 +16,31 @@ def descr_init(self, space, w_starttype, w_obj_or_type=None): if space.is_none(w_obj_or_type): w_type = None # unbound super object - w_obj_or_type = space.w_None + w_obj_or_type = None else: w_type = _super_check(space, w_starttype, w_obj_or_type) self.w_starttype = w_starttype self.w_objtype = w_type - self.w_self = w_obj_or_type + self.w_self = w_obj_or_type # may be None def descr_repr(self, space): if self.w_objtype is not None: objtype_name = "<%s object>" % self.w_objtype.getname(space) else: objtype_name = 'NULL' + if self.w_starttype is not None: + starttype_name = self.w_starttype.getname(space) + else: + starttype_name = 'NULL' return space.newtext("<super: <class '%s'>, %s>" % ( - self.w_starttype.getname(space), objtype_name)) + starttype_name, objtype_name)) def get(self, space, w_obj, w_type=None): - if self.w_self is None or space.is_w(w_obj, space.w_None): + if self.w_self is not None or space.is_w(w_obj, space.w_None): return self + if self.w_starttype is None: + raise oefmt(space.w_TypeError, + "__get__(x) is invalid on an uninitialized instance of 'super'") else: # if type(self) is W_Super: # XXX write a fast path for this common case @@ -45,6 +52,7 @@ # only use a special logic for bound super objects and not for # getting the __class__ of the super object itself. if self.w_objtype is not None and name != '__class__': + assert self.w_starttype is not None w_value = space.lookup_in_type_starting_at(self.w_objtype, self.w_starttype, name) @@ -54,10 +62,9 @@ return w_value # Only pass 'obj' param if this is instance-mode super # (see CPython sourceforge id #743627) - if self.w_self is self.w_objtype: + w_obj = self.w_self + if w_obj is None or w_obj is self.w_objtype: w_obj = space.w_None - else: - w_obj = self.w_self return space.get_and_call_function(w_get, w_value, w_obj, self.w_objtype) # fallback to object.__getattribute__() @@ -115,7 +122,11 @@ _immutable_fields_ = ["w_fget", "w_fset", "w_fdel"] def __init__(self, space): - pass + self.w_fget = space.w_None + self.w_fset = space.w_None + self.w_fdel = space.w_None + self.w_doc = space.w_None + self.getter_doc = False @unwrap_spec(w_fget=WrappedDefault(None), w_fset=WrappedDefault(None), diff --git a/pypy/module/__builtin__/test/test_descriptor.py b/pypy/module/__builtin__/test/test_descriptor.py --- a/pypy/module/__builtin__/test/test_descriptor.py +++ b/pypy/module/__builtin__/test/test_descriptor.py @@ -280,6 +280,22 @@ assert repr(A()).endswith('>!') assert repr(super(A, A())) == "<super: <class 'A'>, <A object>>" + def test_super_get_corner_case(self): + class A(object): + pass + s1 = super(A, A()) + assert s1.__get__(42) is s1 + assert s1.__get__(42, int) is s1 + s2 = super(A) + assert s2.__get__(None, "anything") is s2 + # + assert s1.__get__(None, "anything") is s1 + raises(TypeError, s2.__get__, 42) + raises(TypeError, s2.__get__, 42, int) + a = A() + assert s2.__get__(a).__self__ is a + assert s1.__get__(a) is s1 + def test_property_docstring(self): assert property.__doc__.startswith('property') @@ -411,3 +427,35 @@ assert x.y == 42 del x.x assert x.z == 42 + + def test_uninitialized_property(self): + p = property.__new__(property) + raises(AttributeError, p.__get__, 42) + raises(AttributeError, p.__set__, 42, None) + raises(AttributeError, p.__delete__, 42) + assert repr(p).startswith("<property object at ") + assert p.fget is p.fset is p.fdel is p.__doc__ is None + # + lst = [] + p.deleter(lst.append).__delete__(42) + assert lst == [42] + # + lst = [] + p.getter(lst.append).__get__(43) + assert lst == [43] + # + lst = [] + p.setter(lambda x, y: lst.append((x, y))).__set__(44, 45) + assert lst == [(44, 45)] + + def test_uninitialized_super(self): + s = super.__new__(super) + assert repr(s) == "<super: <class 'NULL'>, NULL>" + assert s.__thisclass__ is s.__self__ is s.__self_class__ is None + assert s.__get__(None, "anything") is s + raises(TypeError, s.__get__, 42) + raises(TypeError, s.__get__, int) + raises(TypeError, s.__get__, type(None)) + raises(AttributeError, "s.abcde") + raises(AttributeError, "s.abcde = 42") + raises(AttributeError, "del s.abcde") diff --git a/pypy/module/_cffi_backend/__init__.py b/pypy/module/_cffi_backend/__init__.py --- a/pypy/module/_cffi_backend/__init__.py +++ b/pypy/module/_cffi_backend/__init__.py @@ -3,7 +3,7 @@ from rpython.rlib import rdynload, clibffi from rpython.rtyper.lltypesystem import rffi -VERSION = "1.11.0" +VERSION = "1.11.1" FFI_DEFAULT_ABI = clibffi.FFI_DEFAULT_ABI try: diff --git a/pypy/module/_cffi_backend/cffi1_module.py b/pypy/module/_cffi_backend/cffi1_module.py --- a/pypy/module/_cffi_backend/cffi1_module.py +++ b/pypy/module/_cffi_backend/cffi1_module.py @@ -1,4 +1,5 @@ from rpython.rtyper.lltypesystem import lltype, rffi +from rpython.rlib import jit from pypy.interpreter.error import oefmt from pypy.interpreter.module import Module @@ -15,7 +16,7 @@ INITFUNCPTR = lltype.Ptr(lltype.FuncType([rffi.VOIDPP], lltype.Void)) - +@jit.dont_look_inside def load_cffi1_module(space, name, path, initptr): # This is called from pypy.module.cpyext.api.load_extension_module() from pypy.module._cffi_backend.call_python import get_ll_cffi_call_python diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -156,10 +156,11 @@ class W_CTypePtrBase(W_CTypePtrOrArray): # base class for both pointers and pointers-to-functions - _attrs_ = ['is_void_ptr', 'is_voidchar_ptr'] - _immutable_fields_ = ['is_void_ptr', 'is_voidchar_ptr'] + _attrs_ = ['is_void_ptr', 'is_voidchar_ptr', 'is_onebyte_ptr'] + _immutable_fields_ = ['is_void_ptr', 'is_voidchar_ptr', 'is_onebyte_ptr'] is_void_ptr = False is_voidchar_ptr = False + is_onebyte_ptr = False def convert_to_object(self, cdata): ptrdata = rffi.cast(rffi.CCHARPP, cdata)[0] @@ -179,12 +180,20 @@ if self.is_void_ptr or other.is_void_ptr: pass # cast from or to 'void *' elif self.is_voidchar_ptr or other.is_voidchar_ptr: - space = self.space - msg = ("implicit cast from '%s' to '%s' " - "will be forbidden in the future (check that the types " - "are as you expect; use an explicit ffi.cast() if they " - "are correct)" % (other.name, self.name)) - space.warn(space.newtext(msg), space.w_UserWarning) + # for backward compatibility, accept "char *" as either + # source of target. This is not what C does, though, + # so emit a warning that will eventually turn into an + # error. The warning is turned off if both types are + # pointers to single bytes. + if self.is_onebyte_ptr and other.is_onebyte_ptr: + pass # no warning + else: + space = self.space + msg = ("implicit cast from '%s' to '%s' " + "will be forbidden in the future (check that the types " + "are as you expect; use an explicit ffi.cast() if they " + "are correct)" % (other.name, self.name)) + space.warn(space.newtext(msg), space.w_UserWarning) else: raise self._convert_error("compatible pointer", w_ob) @@ -214,6 +223,7 @@ self.is_void_ptr = isinstance(ctitem, ctypevoid.W_CTypeVoid) self.is_voidchar_ptr = (self.is_void_ptr or isinstance(ctitem, ctypeprim.W_CTypePrimitiveChar)) + self.is_onebyte_ptr = (ctitem.size == 1) W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem) def newp(self, w_init, allocator): diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -1,7 +1,7 @@ # ____________________________________________________________ import sys -assert __version__ == "1.11.0", ("This test_c.py file is for testing a version" +assert __version__ == "1.11.1", ("This test_c.py file is for testing a version" " of cffi that differs from the one that we" " get from 'import _cffi_backend'") if sys.version_info < (3,): @@ -2099,7 +2099,8 @@ if sys.platform.startswith("linux"): BWChar = new_primitive_type("wchar_t") assert sizeof(BWChar) == 4 - assert int(cast(BWChar, -1)) == -1 # signed, on linux + # wchar_t is often signed on Linux, but not always (e.g. on ARM) + assert int(cast(BWChar, -1)) in (-1, 4294967295) def test_char16(): BChar16 = new_primitive_type("char16_t") @@ -3903,9 +3904,11 @@ BCharP = new_pointer_type(new_primitive_type("char")) BIntP = new_pointer_type(new_primitive_type("int")) BVoidP = new_pointer_type(new_void_type()) + BUCharP = new_pointer_type(new_primitive_type("unsigned char")) z1 = cast(BCharP, 0) z2 = cast(BIntP, 0) z3 = cast(BVoidP, 0) + z4 = cast(BUCharP, 0) with warnings.catch_warnings(record=True) as w: newp(new_pointer_type(BIntP), z1) # warn assert len(w) == 1 @@ -3919,6 +3922,12 @@ assert len(w) == 2 newp(new_pointer_type(BIntP), z3) # fine assert len(w) == 2 + newp(new_pointer_type(BCharP), z4) # fine (ignore signedness here) + assert len(w) == 2 + newp(new_pointer_type(BUCharP), z1) # fine (ignore signedness here) + assert len(w) == 2 + newp(new_pointer_type(BUCharP), z3) # fine + assert len(w) == 2 # check that the warnings are associated with lines in this file assert w[1].lineno == w[0].lineno + 4 diff --git a/pypy/module/_csv/interp_csv.py b/pypy/module/_csv/interp_csv.py --- a/pypy/module/_csv/interp_csv.py +++ b/pypy/module/_csv/interp_csv.py @@ -29,10 +29,15 @@ return default return space.is_true(w_src) -def _get_int(space, w_src, default): +def _get_int(space, w_src, default, attrname): if w_src is None: return default - return space.int_w(w_src) + try: + return space.int_w(w_src) + except OperationError as e: + if e.match(space, space.w_TypeError): + raise oefmt(space.w_TypeError, '"%s" must be an int', attrname) + raise def _get_str(space, w_src, default, attrname): if w_src is None: @@ -100,7 +105,7 @@ dialect.escapechar = _get_char(space, w_escapechar, '\0', 'escapechar') dialect.lineterminator = _get_str(space, w_lineterminator, '\r\n', 'lineterminator') dialect.quotechar = _get_char(space, w_quotechar, '"', 'quotechar') - tmp_quoting = _get_int(space, w_quoting, QUOTE_MINIMAL) + tmp_quoting = _get_int(space, w_quoting, QUOTE_MINIMAL, 'quoting') dialect.skipinitialspace = _get_bool(space, w_skipinitialspace, False) dialect.strict = _get_bool(space, w_strict, False) diff --git a/pypy/module/_csv/test/test_dialect.py b/pypy/module/_csv/test/test_dialect.py --- a/pypy/module/_csv/test/test_dialect.py +++ b/pypy/module/_csv/test/test_dialect.py @@ -65,7 +65,8 @@ name = attempt[0] for value in attempt[1:]: kwargs = {name: value} - raises(TypeError, _csv.register_dialect, 'foo1', **kwargs) + exc_info = raises(TypeError, _csv.register_dialect, 'foo1', **kwargs) + assert name in exc_info.value.args[0] exc_info = raises(TypeError, _csv.register_dialect, 'foo1', lineterminator=4) assert exc_info.value.args[0] == '"lineterminator" must be a string' diff --git a/pypy/module/_multiprocessing/interp_win32.py b/pypy/module/_multiprocessing/interp_win32.py --- a/pypy/module/_multiprocessing/interp_win32.py +++ b/pypy/module/_multiprocessing/interp_win32.py @@ -109,6 +109,7 @@ raise wrap_windowserror(space, rwin32.lastSavedWindowsError()) def GetLastError(space): + """NOTE: don't use this. See issue #2658""" return space.newint(rwin32.GetLastError_saved()) # __________________________________________________________ diff --git a/pypy/module/_multiprocessing/test/test_connection.py b/pypy/module/_multiprocessing/test/test_connection.py --- a/pypy/module/_multiprocessing/test/test_connection.py +++ b/pypy/module/_multiprocessing/test/test_connection.py @@ -12,6 +12,7 @@ 'itertools', 'select', 'struct', 'binascii']} if sys.platform == 'win32': spaceconfig['usemodules'].append('_rawffi') + spaceconfig['usemodules'].append('_cffi_backend') else: spaceconfig['usemodules'].append('fcntl') @@ -39,6 +40,10 @@ class BaseConnectionTest(object): def test_connection(self): + import sys + # if not translated, for win32 + if not hasattr(sys, 'executable'): + sys.executable = 'from test_connection.py' rhandle, whandle = self.make_pair() whandle.send_bytes("abc") @@ -50,6 +55,10 @@ assert obj == obj2 def test_poll(self): + import sys + # if not translated, for win32 + if not hasattr(sys, 'executable'): + sys.executable = 'from test_connection.py' rhandle, whandle = self.make_pair() assert rhandle.poll() == False @@ -64,6 +73,10 @@ def test_read_into(self): import array, multiprocessing + import sys + # if not translated, for win32 + if not hasattr(sys, 'executable'): + sys.executable = 'from test_connection.py' rhandle, whandle = self.make_pair() obj = [1, 2.0, "hello"] @@ -81,6 +94,7 @@ } if sys.platform == 'win32': spaceconfig['usemodules'].append('_rawffi') + spaceconfig['usemodules'].append('_cffi_backend') def setup_class(cls): if sys.platform != "win32": @@ -109,6 +123,7 @@ } if sys.platform == 'win32': spaceconfig['usemodules'].append('_rawffi') + spaceconfig['usemodules'].append('_cffi_backend') else: spaceconfig['usemodules'].append('fcntl') diff --git a/pypy/module/_pypyjson/interp_decoder.py b/pypy/module/_pypyjson/interp_decoder.py --- a/pypy/module/_pypyjson/interp_decoder.py +++ b/pypy/module/_pypyjson/interp_decoder.py @@ -1,6 +1,6 @@ import sys from rpython.rlib.rstring import StringBuilder -from rpython.rlib.objectmodel import specialize, always_inline +from rpython.rlib.objectmodel import specialize, always_inline, r_dict from rpython.rlib import rfloat, runicode from rpython.rtyper.lltypesystem import lltype, rffi from pypy.interpreter.error import oefmt @@ -42,6 +42,22 @@ ll_res.chars[i] = cast_primitive(UniChar, ch) return hlunicode(ll_res) +def slice_eq(a, b): + (ll_chars1, start1, length1, _) = a + (ll_chars2, start2, length2, _) = b + if length1 != length2: + return False + j = start2 + for i in range(start1, start1 + length1): + if ll_chars1[i] != ll_chars2[j]: + return False + j += 1 _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit