Author: Carl Friedrich Bolz <cfb...@gmx.de> Branch: better-storesink Changeset: r87173:3744e806c6b1 Date: 2016-09-16 15:10 +0200 http://bitbucket.org/pypy/pypy/changeset/3744e806c6b1/
Log: merge default diff too long, truncating to 2000 out of 218021 lines diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -27,3 +27,9 @@ 40497617ae91caa1a394d8be6f9cd2de31cb0628 release-pypy3.3-v5.2 c09c19272c990a0611b17569a0085ad1ab00c8ff release-pypy2.7-v5.3 7e8df3df96417c16c2d55b41352ec82c9c69c978 release-pypy2.7-v5.3.1 +68bb3510d8212ae9efb687e12e58c09d29e74f87 release-pypy2.7-v5.4.0 +68bb3510d8212ae9efb687e12e58c09d29e74f87 release-pypy2.7-v5.4.0 +77392ad263504df011ccfcabf6a62e21d04086d0 release-pypy2.7-v5.4.0 +050d84dd78997f021acf0e133934275d63547cc0 release-pypy2.7-v5.4.1 +050d84dd78997f021acf0e133934275d63547cc0 release-pypy2.7-v5.4.1 +0e2d9a73f5a1818d0245d75daccdbe21b2d5c3ef release-pypy2.7-v5.4.1 diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -74,6 +74,7 @@ Seo Sanghyeon Ronny Pfannschmidt Justin Peel + Raffael Tfirst David Edelsohn Anders Hammarquist Jakub Gustak @@ -117,7 +118,6 @@ Wenzhu Man John Witulski Laurence Tratt - Raffael Tfirst Ivan Sichmann Freitas Greg Price Dario Bertini @@ -141,6 +141,7 @@ tav Taavi Burns Georg Brandl + Nicolas Truessel Bert Freudenberg Stian Andreassen Wanja Saatkamp @@ -211,6 +212,7 @@ Vaibhav Sood Alan McIntyre Alexander Sedov + p_ziesch...@yahoo.de Attila Gobi Jasper.Schulz Christopher Pope @@ -221,6 +223,7 @@ Arjun Naik Valentina Mukhamedzhanova Stefano Parmesan + touilleMan Alexis Daboville Jens-Uwe Mager Carl Meyer @@ -229,12 +232,14 @@ Gabriel Lukas Vacek Kunal Grover + Aaron Gallagher Andrew Dalke Sylvain Thenault Jakub Stasiak Nathan Taylor Vladimir Kryachko Omer Katz + Mark Williams Jacek Generowicz Alejandro J. Cura Jacob Oscarson @@ -355,12 +360,15 @@ yasirs Michael Chermside Anna Ravencroft + pizi Andrey Churin Dan Crosta + Eli Stevens Tobias Diaz Julien Phalip Roman Podoliaka Dan Loewenherz + werat Heinrich-Heine University, Germany Open End AB (formerly AB Strakt), Sweden diff --git a/_pytest/python.py b/_pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -498,7 +498,10 @@ """ Collector for test methods. """ def collect(self): if hasinit(self.obj): - pytest.skip("class %s.%s with __init__ won't get collected" % ( + # XXX used to be skip(), but silently skipping classes + # XXX just because they have been written long ago is + # XXX imho a very, very, very bad idea + pytest.fail("class %s.%s with __init__ won't get collected" % ( self.obj.__module__, self.obj.__name__, )) 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 @@ -122,22 +122,24 @@ """Dummy method to let some easy_install packages that have optional C speedup components. """ + def customize(executable, flags): + command = compiler.executables[executable] + flags + setattr(compiler, executable, command) + if compiler.compiler_type == "unix": compiler.compiler_so.extend(['-O2', '-fPIC', '-Wimplicit']) compiler.shared_lib_extension = get_config_var('SO') if "CPPFLAGS" in os.environ: cppflags = shlex.split(os.environ["CPPFLAGS"]) - compiler.compiler.extend(cppflags) - compiler.compiler_so.extend(cppflags) - compiler.linker_so.extend(cppflags) + for executable in ('compiler', 'compiler_so', 'linker_so'): + customize(executable, cppflags) if "CFLAGS" in os.environ: cflags = shlex.split(os.environ["CFLAGS"]) - compiler.compiler.extend(cflags) - compiler.compiler_so.extend(cflags) - compiler.linker_so.extend(cflags) + for executable in ('compiler', 'compiler_so', 'linker_so'): + customize(executable, cflags) if "LDFLAGS" in os.environ: ldflags = shlex.split(os.environ["LDFLAGS"]) - compiler.linker_so.extend(ldflags) + customize('linker_so', ldflags) from sysconfig_cpython import ( 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 @@ -167,7 +167,7 @@ else: return self.value - def __buffer__(self): + def __buffer__(self, flags): return buffer(self._buffer) def _get_b_base(self): 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 @@ -342,7 +342,7 @@ thisarg = cast(thisvalue, POINTER(POINTER(c_void_p))) keepalives, newargs, argtypes, outargs, errcheckargs = ( self._convert_args(argtypes, args[1:], kwargs)) - newargs.insert(0, thisvalue.value) + newargs.insert(0, thisarg) argtypes.insert(0, c_void_p) else: thisarg = None 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.8.0 +Version: 1.8.3 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, CDefError, FFIError from .ffiplatform import VerificationError, VerificationMissing -__version__ = "1.8.0" -__version_info__ = (1, 8, 0) +__version__ = "1.8.3" +__version_info__ = (1, 8, 3) # 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 @@ -1,4 +1,20 @@ #define _CFFI_ + +/* We try to define Py_LIMITED_API before including Python.h. + + Mess: we can only define it if Py_DEBUG, Py_TRACE_REFS and + Py_REF_DEBUG are not defined. This is a best-effort approximation: + we can learn about Py_DEBUG from pyconfig.h, but it is unclear if + the same works for the other two macros. Py_DEBUG implies them, + but not the other way around. +*/ +#ifndef _CFFI_USE_EMBEDDING +# include <pyconfig.h> +# if !defined(Py_DEBUG) && !defined(Py_TRACE_REFS) && !defined(Py_REF_DEBUG) +# define Py_LIMITED_API +# endif +#endif + #include <Python.h> #ifdef __cplusplus extern "C" { 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 @@ -233,7 +233,7 @@ f = PySys_GetObject((char *)"stderr"); if (f != NULL && f != Py_None) { PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME - "\ncompiled with cffi version: 1.8.0" + "\ncompiled with cffi version: 1.8.3" "\n_cffi_backend module: ", f); modules = PyImport_GetModuleDict(); mod = PyDict_GetItemString(modules, "_cffi_backend"); 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 @@ -652,7 +652,7 @@ recompile(self, module_name, source, c_file=filename, call_c_compiler=False, **kwds) - def compile(self, tmpdir='.', verbose=0, target=None): + def compile(self, tmpdir='.', verbose=0, target=None, debug=None): """The 'target' argument gives the final file name of the compiled DLL. Use '*' to force distutils' choice, suitable for regular CPython C API modules. Use a file name ending in '.*' @@ -669,7 +669,7 @@ module_name, source, source_extension, kwds = self._assigned_source return recompile(self, module_name, source, tmpdir=tmpdir, target=target, source_extension=source_extension, - compiler_verbose=verbose, **kwds) + compiler_verbose=verbose, debug=debug, **kwds) def init_once(self, func, tag): # Read _init_once_cache[tag], which is either (False, lock) if 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 @@ -997,29 +997,43 @@ assert onerror is None # XXX not implemented return BType(source, error) + _weakref_cache_ref = None + def gcp(self, cdata, destructor): - BType = self.typeof(cdata) + if self._weakref_cache_ref is None: + import weakref + class MyRef(weakref.ref): + def __eq__(self, other): + myref = self() + return self is other or ( + myref is not None and myref is other()) + def __ne__(self, other): + return not (self == other) + def __hash__(self): + try: + return self._hash + except AttributeError: + self._hash = hash(self()) + return self._hash + self._weakref_cache_ref = {}, MyRef + weak_cache, MyRef = self._weakref_cache_ref if destructor is None: - if not (hasattr(BType, '_gcp_type') and - BType._gcp_type is BType): + try: + del weak_cache[MyRef(cdata)] + except KeyError: raise TypeError("Can remove destructor only on a object " "previously returned by ffi.gc()") - cdata._destructor = None return None - try: - gcp_type = BType._gcp_type - except AttributeError: - class CTypesDataGcp(BType): - __slots__ = ['_orig', '_destructor'] - def __del__(self): - if self._destructor is not None: - self._destructor(self._orig) - gcp_type = BType._gcp_type = CTypesDataGcp - new_cdata = self.cast(gcp_type, cdata) - new_cdata._orig = cdata - new_cdata._destructor = destructor + def remove(k): + cdata, destructor = weak_cache.pop(k, (None, None)) + if destructor is not None: + destructor(cdata) + + new_cdata = self.cast(self.typeof(cdata), cdata) + assert new_cdata is not cdata + weak_cache[MyRef(new_cdata, remove)] = (cdata, destructor) return new_cdata typeof = type diff --git a/lib_pypy/cffi/ffiplatform.py b/lib_pypy/cffi/ffiplatform.py --- a/lib_pypy/cffi/ffiplatform.py +++ b/lib_pypy/cffi/ffiplatform.py @@ -21,12 +21,12 @@ allsources.append(os.path.normpath(src)) return Extension(name=modname, sources=allsources, **kwds) -def compile(tmpdir, ext, compiler_verbose=0): +def compile(tmpdir, ext, compiler_verbose=0, debug=None): """Compile a C extension module using distutils.""" saved_environ = os.environ.copy() try: - outputfilename = _build(tmpdir, ext, compiler_verbose) + outputfilename = _build(tmpdir, ext, compiler_verbose, debug) outputfilename = os.path.abspath(outputfilename) finally: # workaround for a distutils bugs where some env vars can @@ -36,7 +36,7 @@ os.environ[key] = value return outputfilename -def _build(tmpdir, ext, compiler_verbose=0): +def _build(tmpdir, ext, compiler_verbose=0, debug=None): # XXX compact but horrible :-( from distutils.core import Distribution import distutils.errors, distutils.log @@ -44,6 +44,9 @@ dist = Distribution({'ext_modules': [ext]}) dist.parse_config_files() options = dist.get_option_dict('build_ext') + if debug is None: + debug = sys.flags.debug + options['debug'] = ('ffiplatform', debug) options['force'] = ('ffiplatform', True) options['build_lib'] = ('ffiplatform', tmpdir) options['build_temp'] = ('ffiplatform', tmpdir) 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 @@ -275,8 +275,8 @@ def write_c_source_to_f(self, f, preamble): self._f = f prnt = self._prnt - if self.ffi._embedding is None: - prnt('#define Py_LIMITED_API') + if self.ffi._embedding is not None: + prnt('#define _CFFI_USE_EMBEDDING') # # first the '#include' (actually done by inlining the file's content) lines = self._rel_readlines('_cffi_include.h') @@ -515,7 +515,7 @@ tovar, errcode) return # - elif isinstance(tp, (model.StructOrUnion, model.EnumType)): + elif isinstance(tp, model.StructOrUnionOrEnum): # a struct (not a struct pointer) as a function argument self._prnt(' if (_cffi_to_c((char *)&%s, _cffi_type(%d), %s) < 0)' % (tovar, self._gettypenum(tp), fromvar)) @@ -572,7 +572,7 @@ elif isinstance(tp, model.ArrayType): return '_cffi_from_c_pointer((char *)%s, _cffi_type(%d))' % ( var, self._gettypenum(model.PointerType(tp.item))) - elif isinstance(tp, model.StructType): + elif isinstance(tp, model.StructOrUnion): if tp.fldnames is None: raise TypeError("'%s' is used as %s, but is opaque" % ( tp._get_c_name(), context)) @@ -1431,7 +1431,7 @@ def recompile(ffi, module_name, preamble, tmpdir='.', call_c_compiler=True, c_file=None, source_extension='.c', extradir=None, - compiler_verbose=1, target=None, **kwds): + compiler_verbose=1, target=None, debug=None, **kwds): if not isinstance(module_name, str): module_name = module_name.encode('ascii') if ffi._windows_unicode: @@ -1467,7 +1467,8 @@ if target != '*': _patch_for_target(patchlist, target) os.chdir(tmpdir) - outputfilename = ffiplatform.compile('.', ext, compiler_verbose) + outputfilename = ffiplatform.compile('.', ext, + compiler_verbose, debug) finally: os.chdir(cwd) _unpatch_meths(patchlist) diff --git a/lib_pypy/cffi/setuptools_ext.py b/lib_pypy/cffi/setuptools_ext.py --- a/lib_pypy/cffi/setuptools_ext.py +++ b/lib_pypy/cffi/setuptools_ext.py @@ -69,16 +69,36 @@ else: _add_c_module(dist, ffi, module_name, source, source_extension, kwds) +def _set_py_limited_api(Extension, kwds): + """ + Add py_limited_api to kwds if setuptools >= 26 is in use. + Do not alter the setting if it already exists. + Setuptools takes care of ignoring the flag on Python 2 and PyPy. + """ + if 'py_limited_api' not in kwds: + import setuptools + try: + setuptools_major_version = int(setuptools.__version__.partition('.')[0]) + if setuptools_major_version >= 26: + kwds['py_limited_api'] = True + except ValueError: # certain development versions of setuptools + # If we don't know the version number of setuptools, we + # try to set 'py_limited_api' anyway. At worst, we get a + # warning. + kwds['py_limited_api'] = True + return kwds def _add_c_module(dist, ffi, module_name, source, source_extension, kwds): from distutils.core import Extension - from distutils.command.build_ext import build_ext + # We are a setuptools extension. Need this build_ext for py_limited_api. + from setuptools.command.build_ext import build_ext from distutils.dir_util import mkpath from distutils import log from cffi import recompiler allsources = ['$PLACEHOLDER'] allsources.extend(kwds.pop('sources', [])) + kwds = _set_py_limited_api(Extension, kwds) ext = Extension(name=module_name, sources=allsources, **kwds) def make_mod(tmpdir, pre_run=None): 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 @@ -308,7 +308,7 @@ elif isinstance(tp, model.ArrayType): return '_cffi_from_c_pointer((char *)%s, _cffi_type(%d))' % ( var, self._gettypenum(model.PointerType(tp.item))) - elif isinstance(tp, model.StructType): + elif isinstance(tp, model.StructOrUnion): if tp.fldnames is None: raise TypeError("'%s' is used as %s, but is opaque" % ( tp._get_c_name(), context)) diff --git a/lib_pypy/gdbm.py b/lib_pypy/gdbm.py --- a/lib_pypy/gdbm.py +++ b/lib_pypy/gdbm.py @@ -137,6 +137,8 @@ lib.gdbm_sync(self.__ll_dbm) def open(filename, flags='r', mode=0666): + if isinstance(filename, unicode): + filename = filename.encode() if flags[0] == 'r': iflags = lib.GDBM_READER elif flags[0] == 'w': diff --git a/pypy/doc/conf.py b/pypy/doc/conf.py --- a/pypy/doc/conf.py +++ b/pypy/doc/conf.py @@ -58,16 +58,16 @@ # General information about the project. project = u'PyPy' -copyright = u'2015, The PyPy Project' +copyright = u'2016, The PyPy Project' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '4.0' +version = '5.4' # The full version, including alpha/beta/rc tags. -release = '4.0.0' +release = '5.4.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/pypy/doc/config/translation.profopt.txt b/pypy/doc/config/translation.profopt.txt --- a/pypy/doc/config/translation.profopt.txt +++ b/pypy/doc/config/translation.profopt.txt @@ -3,3 +3,14 @@ RPython program) to gather profile data. Example for pypy-c: "-c 'from richards import main;main(); from test import pystone; pystone.main()'" + +NOTE: be aware of what this does in JIT-enabled executables. What it +does is instrument and later optimize the C code that happens to run in +the example you specify, ignoring any execution of the JIT-generated +assembler. That means that you have to choose the example wisely. If +it is something that will just generate assembler and stay there, there +is little value. If it is something that exercises heavily library +routines that are anyway written in C, then it will optimize that. Most +interesting would be something that causes a lot of JIT-compilation, +like running a medium-sized test suite several times in a row, in order +to optimize the warm-up in general. diff --git a/pypy/doc/contributor.rst b/pypy/doc/contributor.rst --- a/pypy/doc/contributor.rst +++ b/pypy/doc/contributor.rst @@ -44,6 +44,7 @@ Seo Sanghyeon Ronny Pfannschmidt Justin Peel + Raffael Tfirst David Edelsohn Anders Hammarquist Jakub Gustak @@ -87,7 +88,6 @@ Wenzhu Man John Witulski Laurence Tratt - Raffael Tfirst Ivan Sichmann Freitas Greg Price Dario Bertini @@ -111,6 +111,7 @@ tav Taavi Burns Georg Brandl + Nicolas Truessel Bert Freudenberg Stian Andreassen Wanja Saatkamp @@ -181,6 +182,7 @@ Vaibhav Sood Alan McIntyre Alexander Sedov + p_ziesch...@yahoo.de Attila Gobi Jasper.Schulz Christopher Pope @@ -191,6 +193,7 @@ Arjun Naik Valentina Mukhamedzhanova Stefano Parmesan + touilleMan Alexis Daboville Jens-Uwe Mager Carl Meyer @@ -199,12 +202,14 @@ Gabriel Lukas Vacek Kunal Grover + Aaron Gallagher Andrew Dalke Sylvain Thenault Jakub Stasiak Nathan Taylor Vladimir Kryachko Omer Katz + Mark Williams Jacek Generowicz Alejandro J. Cura Jacob Oscarson @@ -325,9 +330,12 @@ yasirs Michael Chermside Anna Ravencroft + pizi Andrey Churin Dan Crosta + Eli Stevens Tobias Diaz Julien Phalip Roman Podoliaka Dan Loewenherz + werat 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,8 @@ .. toctree:: + release-pypy2.7-v5.4.1.rst + release-pypy2.7-v5.4.0.rst release-pypy2.7-v5.3.1.rst release-pypy2.7-v5.3.0.rst release-5.1.1.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.4.0.rst whatsnew-pypy2-5.3.1.rst whatsnew-pypy2-5.3.0.rst whatsnew-5.1.0.rst diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst --- a/pypy/doc/project-ideas.rst +++ b/pypy/doc/project-ideas.rst @@ -57,7 +57,7 @@ -------------- Our cpyext C-API compatiblity layer can now run upstream NumPy unmodified. -Release PyPy2.7-v5.3 still fails about 200 of the ~6000 test in the NumPy +Release PyPy2.7-v5.4 still fails about 60 of the ~6000 test in the NumPy test suite. We could use help analyzing the failures and fixing them either as patches to upstream NumPy, or as fixes to PyPy. diff --git a/pypy/doc/release-pypy2.7-v5.4.0.rst b/pypy/doc/release-pypy2.7-v5.4.0.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/release-pypy2.7-v5.4.0.rst @@ -0,0 +1,218 @@ +============ +PyPy2.7 v5.4 +============ + +We have released PyPy2.7 v5.4, a little under two months after PyPy2.7 v5.3. +This new PyPy2.7 release includes incremental improvements to our C-API +compatability layer (cpyext), enabling us to pass over 99% of the upstream +numpy `test suite`_. We updated built-in cffi_ support to version 1.8, +which now supports the "limited API" mode for c-extensions on +CPython >=3.2. + +We improved tooling for the PyPy JIT_, and expanded VMProf +support to OpenBSD and Dragon Fly BSD + +As always, this release fixed many issues and bugs raised by the +growing community of PyPy users. We strongly recommend updating. + +You can download the PyPy2.7 v5.4 release 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. + +.. _`test suite`: https://bitbucket.org/pypy/pypy/wiki/Adventures%20in%20cpyext%20compatibility +.. _cffi: https://cffi.readthedocs.org +.. _JIT: https://morepypy.blogspot.com.au/2016/08/pypy-tooling-upgrade-jitviewer-and.html +.. _`PyPy`: http://doc.pypy.org +.. _`RPython`: https://rpython.readthedocs.org +.. _`modules`: http://doc.pypy.org/en/latest/project-ideas.html#make-more-python-modules-pypy-friendly +.. _`help`: http://doc.pypy.org/en/latest/project-ideas.html + +What is PyPy? +============= + +PyPy is a very compliant Python interpreter, almost a drop-in replacement for +CPython 2.7. 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. + +This 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://pypyjs.org + +Other Highlights (since 5.3 released in June 2016) +========================================================= + +* New features: + + * Add `sys.{get,set}dlopenflags` + + * Improve CPython compatibility of 'is' for small and empty strings + + * Support for rgc.FinalizerQueue in the Boehm garbage collector + + * (RPython) support spawnv() if it is called in C `_spawnv` on windows + + * Fill in more slots when creating a PyTypeObject from a W_TypeObject, + like `__hex__`, `__sub__`, `__pow__` + + * Copy CPython's logic more closely for `isinstance()` and + `issubclass()` as well as `type.__instancecheck__()` and + `type.__subclasscheck__()` + + * Expose the name of CDLL objects + + * Rewrite the win32 dependencies of `subprocess` to use cffi + instead of ctypes + + * Improve the `JIT logging`_ facitilities + + * (RPython) make int * string work + + * Allocate all RPython strings with one extra byte, normally + unused. This now allows `ffi.from_buffer(string)` in CFFI with + no copy + + * Adds a new commandline option `-X track-resources` that will + produce a `ResourceWarning` when the GC closes a file or socket. + The traceback for the place where the file or socket was allocated + is given as well, which aids finding places where `close()` is + missing + + * Add missing `PyObject_Realloc`, `PySequence_GetSlice` + + * `type.__dict__` now returns a `dict_proxy` object, like on CPython. + Previously it returned what looked like a regular dict object (but + it was already read-only) + + * (RPython) add `rposix.{get,set}_inheritable()`, needed by Python 3.5 + + * (RPython) add `rposix_scandir` portably, needed for Python 3.5 + + * Increased but incomplete support for memoryview attributes (format, + itemsize, ...) which also adds support for `PyMemoryView_FromObject` + +* Bug Fixes + + * Reject `mkdir()` in read-only sandbox filesystems + + * Add include guards to pymem.h to enable c++ compilation + + * Fix build breakage on OpenBSD and FreeBSD + + * Support OpenBSD, Dragon Fly BSD in VMProf + + * Fix for `bytearray('').replace('a', 'ab')` for empty strings + + * Sync internal state before calling `PyFile_AsFile()` + + * Allow writing to a char* from `PyString_AsString()` until it is + forced, also refactor `PyStringObject` to look like CPython's + and allow subclassing `PyString_Type` and `PyUnicode_Type` + + * Rpython rffi's socket(2) wrapper did not preserve errno + + * Refactor `PyTupleObject` to look like CPython's and allow + subclassing `PyTuple_Type` + + * Allow c-level assignment to a function pointer in a C-API + user-defined type after calling PyTypeReady by retrieving + a pointer to the function via offsets + rather than storing the function pointer itself + + * Use `madvise(MADV_FREE)`, or if that doesn't exist + `MADV_DONTNEED` on freed arenas to release memory back to the + OS for resource monitoring + + * Fix overflow detection in conversion of float to 64-bit integer + in timeout argument to various thread/threading primitives + + * Fix win32 outputting `\r\r\n` in some cases + + * Make `hash(-1)` return -2, as CPython does, and fix all the + ancilary places this matters + + * Fix `PyNumber_Check()` to behave more like CPython + + * (VMProf) Try hard to not miss any Python-level frame in the + captured stacks, even if there is metainterp or blackhole interp + involved. Also fix the stacklet (greenlet) support + + * Fix a critical JIT bug where `raw_malloc` -equivalent functions + lost the additional flags + + * Fix the mapdict cache for subclasses of builtin types that + provide a dict + + * Issues reported with our previous release were resolved_ after + reports from users on our issue tracker at + https://bitbucket.org/pypy/pypy/issues or on IRC at #pypy + +* Performance improvements: + + * Add a before_call()-like equivalent before a few operations like + `malloc_nursery`, to move values from registers into other registers + instead of to the stack. + + * More tightly pack the stack when calling with `release gil` + + * Support `int_floordiv()`, `int_mod()` in the JIT more efficiently + and add `rarithmetic.int_c_div()`, `rarithmetic.int_c_mod()` as + explicit interfaces. Clarify that `int_floordiv()` does python-style + rounding, unlike `llop.int_floordiv()`. + + * Use `ll_assert` (more often) in incminimark + + * (Testing) Simplify handling of interp-level tests and make it + more forward-compatible. Don't use interp-level RPython + machinery to test building app-level extensions in cpyext + + * Constant-fold `ffi.offsetof("structname", "fieldname")` in cffi + backend + + * Avoid a case in the JIT, where successive guard failures in + the same Python function end up as successive levels of + RPython functions, eventually exhausting the stack, while at + app-level the traceback is very short + + * Check for NULL returns from calls to the raw-malloc and raise, + rather than a guard + + * Improve `socket.recvfrom()` so that it copies less if possible + + * When generating C code, inline `goto` to blocks with only one + predecessor, generating less lines of code + + * When running the final backend-optimization phase before emitting + C code, constant-fold calls to we_are_jitted to return False. This + makes the generated C code a few percent smaller + + * Refactor the `uid_t/gid_t` handling in `rlib.rposix` and in + `interp_posix.py`, based on the clean-up of CPython 2.7.x + +.. _`JIT logging`: https://morepypy.blogspot.com/2016/08/pypy-tooling-upgrade-jitviewer-and.html +.. _resolved: http://doc.pypy.org/en/latest/whatsnew-5.4.0.html + +Please update, and continue to help us make PyPy better. + +Cheers diff --git a/pypy/doc/release-pypy2.7-v5.4.1.rst b/pypy/doc/release-pypy2.7-v5.4.1.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/release-pypy2.7-v5.4.1.rst @@ -0,0 +1,64 @@ +========== +PyPy 5.4.1 +========== + +We have released a bugfix for PyPy2.7-v5.4.0, released last week, +due to the following issues: + + * Update list of contributors in documentation and LICENSE file, + this was unfortunately left out of 5.4.0. My apologies to the new + contributors + + * Allow tests run with ``-A`` to find ``libm.so`` even if it is a script not a + dynamically loadable file + + * Bump ``sys.setrecursionlimit()`` when translating PyPy, for translating with CPython + + * Tweak a float comparison with 0 in ``backendopt.inline`` to avoid rounding errors + + * Fix for an issue for translating the sandbox + + * Fix for and issue where ``unicode.decode('utf8', 'custom_replace')`` messed up + the last byte of a unicode string sometimes + + * Update built-in cffi_ to version 1.8.1 + + * Explicitly detect that we found as-yet-unsupported OpenSSL 1.1, and crash + translation with a message asking for help porting it + + * Fix a regression where a PyBytesObject was forced (converted to a RPython + object) when not required, reported as issue #2395 + +Thanks to those who reported the issues. + +What is PyPy? +============= + +PyPy is a very compliant Python interpreter, almost a drop-in replacement for +CPython 2.7. 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. + +This release supports: + + * **x86** machines on most common operating systems + (Linux 32/64, Mac OS X 64, Windows 32, OpenBSD, FreeBSD), + + * newer **ARM** hardware (ARMv6 or ARMv7, with VFPv3) running Linux, + + * big- and little-endian variants of **PPC64** running Linux, + + * **s390x** running Linux + +.. _cffi: https://cffi.readthedocs.io +.. _`PyPy and CPython 2.7.x`: http://speed.pypy.org +.. _`dynamic languages`: http://pypyjs.org + +Please update, and continue to help us make PyPy better. + +Cheers + +The PyPy Team + 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,146 +1,18 @@ ========================== -What's new in PyPy2.7 5.3+ +What's new in PyPy2.7 5.4+ ========================== -.. this is a revision shortly after release-pypy2.7-v5.3 -.. startrev: 873218a739f1 +.. this is a revision shortly after release-pypy2.7-v5.4 +.. startrev: 522736f816dc -.. 418b05f95db5 -Improve CPython compatibility for ``is``. Now code like ``if x is ():`` -works the same way as it does on CPython. See http://pypy.readthedocs.io/en/latest/cpython_differences.html#object-identity-of-primitive-values-is-and-id . +.. branch: rpython-resync +Backport rpython changes made directly on the py3k and py3.5 branches. -.. pull request #455 -Add sys.{get,set}dlopenflags, for cpyext extensions. +.. branch: buffer-interface +Implement PyObject_GetBuffer, PyMemoryView_GET_BUFFER, and handles memoryviews +in numpypy -.. branch: fix-gen-dfa - -Resolves an issue with the generator script to build the dfa for Python syntax. - -.. branch: z196-support - -Fixes a critical issue in the register allocator and extends support on s390x. -PyPy runs and translates on the s390x revisions z10 (released February 2008, experimental) -and z196 (released August 2010) in addition to zEC12 and z13. -To target e.g. z196 on a zEC12 machine supply CFLAGS="-march=z196" to your shell environment. - -.. branch: s390x-5.3-catchup - -Implement the backend related changes for s390x. - -.. branch: incminimark-ll_assert -.. branch: vmprof-openbsd - -.. branch: testing-cleanup - -Simplify handling of interp-level tests and make it more forward- -compatible. - -.. branch: pyfile-tell -Sync w_file with the c-level FILE* before returning FILE* in PyFile_AsFile - -.. branch: rw-PyString_AS_STRING -Allow rw access to the char* returned from PyString_AS_STRING, also refactor -PyStringObject to look like cpython's and allow subclassing PyString_Type and -PyUnicode_Type - -.. branch: save_socket_errno - -Bug fix: if ``socket.socket()`` failed, the ``socket.error`` did not show -the errno of the failing system call, but instead some random previous -errno. - -.. branch: PyTuple_Type-subclass - -Refactor PyTupleObject to look like cpython's and allow subclassing -PyTuple_Type - -.. branch: call-via-pyobj - -Use offsets from PyTypeObject to find actual c function to call rather than -fixed functions, allows function override after PyType_Ready is called - -.. branch: issue2335 - -Avoid exhausting the stack in the JIT due to successive guard -failures in the same Python function ending up as successive levels of -RPython functions, while at app-level the traceback is very short - -.. branch: use-madv-free - -Try harder to memory to the OS. See e.g. issue #2336. Note that it does -not show up as a reduction of the VIRT column in ``top``, and the RES -column might also not show the reduction, particularly on Linux >= 4.5 or -on OS/X: it uses MADV_FREE, which only marks the pages as returnable to -the OS if the memory is low. - -.. branch: cpyext-slotdefs2 - -Fill in more slots when creating a PyTypeObject from a W_TypeObject -More slots are still TBD, like tp_print and richcmp - -.. branch: json-surrogates - -Align json module decode with the cpython's impl, fixes issue 2345 - -.. branch: issue2343 - -Copy CPython's logic more closely for handling of ``__instancecheck__()`` -and ``__subclasscheck__()``. Fixes issue 2343. - -.. branch: msvcrt-cffi - -Rewrite the Win32 dependencies of 'subprocess' to use cffi instead -of ctypes. This avoids importing ctypes in many small programs and -scripts, which in turn avoids enabling threads (because ctypes -creates callbacks at import time, and callbacks need threads). - -.. branch: new-jit-log - -The new logging facility that integrates with and adds features to vmprof.com. - -.. branch: jitlog-32bit - -Resolve issues to use the new logging facility on a 32bit system - -.. branch: ep2016sprint - -Trying harder to make hash(-1) return -2, like it does on CPython - -.. branch: jitlog-exact-source-lines - -Log exact line positions in debug merge points. - -.. branch: null_byte_after_str - -Allocate all RPython strings with one extra byte, normally unused. -It is used to hold a final zero in case we need some ``char *`` -representation of the string, together with checks like ``not -can_move()`` or object pinning. Main new thing that this allows: -``ffi.from_buffer(string)`` in CFFI. Additionally, and most -importantly, CFFI calls that take directly a string as argument don't -copy the string any more---this is like CFFI on CPython. - -.. branch: resource_warning - -Add a new command line option -X track-resources which will produce -ResourceWarnings when the GC closes unclosed files and sockets. - -.. branch: cpyext-realloc - -Implement PyObject_Realloc - -.. branch: inline-blocks - -Improve a little bit the readability of the generated C code - -.. branch: improve-vmprof-testing - -Improved vmprof support: now tries hard to not miss any Python-level -frame in the captured stacks, even if there is the metainterp or -blackhole interp involved. Also fix the stacklet (greenlet) support. - -.. branch: py2-mappingproxy - -``type.__dict__`` now returns a ``dict_proxy`` object, like on CPython. -Previously it returned what looked like a regular dict object (but it -was already read-only). +.. branch: force-virtual-state +Improve merging of virtual states in the JIT in order to avoid jumping to the +preamble. Accomplished by allocating virtual objects where non-virtuals are +expected. diff --git a/pypy/doc/whatsnew-pypy2-5.4.0.rst b/pypy/doc/whatsnew-pypy2-5.4.0.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/whatsnew-pypy2-5.4.0.rst @@ -0,0 +1,165 @@ +========================= +What's new in PyPy2.7 5.4 +========================= + +.. this is a revision shortly after release-pypy2.7-v5.3 +.. startrev: 873218a739f1 + +.. 418b05f95db5 +Improve CPython compatibility for ``is``. Now code like ``if x is ():`` +works the same way as it does on CPython. See http://pypy.readthedocs.io/en/latest/cpython_differences.html#object-identity-of-primitive-values-is-and-id . + +.. pull request #455 +Add sys.{get,set}dlopenflags, for cpyext extensions. + +.. branch: fix-gen-dfa + +Resolves an issue with the generator script to build the dfa for Python syntax. + +.. branch: z196-support + +Fixes a critical issue in the register allocator and extends support on s390x. +PyPy runs and translates on the s390x revisions z10 (released February 2008, experimental) +and z196 (released August 2010) in addition to zEC12 and z13. +To target e.g. z196 on a zEC12 machine supply CFLAGS="-march=z196" to your shell environment. + +.. branch: s390x-5.3-catchup + +Implement the backend related changes for s390x. + +.. branch: incminimark-ll_assert +.. branch: vmprof-openbsd + +.. branch: testing-cleanup + +Simplify handling of interp-level tests and make it more forward- +compatible. + +.. branch: pyfile-tell +Sync w_file with the c-level FILE* before returning FILE* in PyFile_AsFile + +.. branch: rw-PyString_AS_STRING +Allow rw access to the char* returned from PyString_AS_STRING, also refactor +PyStringObject to look like cpython's and allow subclassing PyString_Type and +PyUnicode_Type + +.. branch: save_socket_errno + +Bug fix: if ``socket.socket()`` failed, the ``socket.error`` did not show +the errno of the failing system call, but instead some random previous +errno. + +.. branch: PyTuple_Type-subclass + +Refactor PyTupleObject to look like cpython's and allow subclassing +PyTuple_Type + +.. branch: call-via-pyobj + +Use offsets from PyTypeObject to find actual c function to call rather than +fixed functions, allows function override after PyType_Ready is called + +.. branch: issue2335 + +Avoid exhausting the stack in the JIT due to successive guard +failures in the same Python function ending up as successive levels of +RPython functions, while at app-level the traceback is very short + +.. branch: use-madv-free + +Try harder to memory to the OS. See e.g. issue #2336. Note that it does +not show up as a reduction of the VIRT column in ``top``, and the RES +column might also not show the reduction, particularly on Linux >= 4.5 or +on OS/X: it uses MADV_FREE, which only marks the pages as returnable to +the OS if the memory is low. + +.. branch: cpyext-slotdefs2 + +Fill in more slots when creating a PyTypeObject from a W_TypeObject +More slots are still TBD, like tp_print and richcmp + +.. branch: json-surrogates + +Align json module decode with the cpython's impl, fixes issue 2345 + +.. branch: issue2343 + +Copy CPython's logic more closely for handling of ``__instancecheck__()`` +and ``__subclasscheck__()``. Fixes issue 2343. + +.. branch: msvcrt-cffi + +Rewrite the Win32 dependencies of 'subprocess' to use cffi instead +of ctypes. This avoids importing ctypes in many small programs and +scripts, which in turn avoids enabling threads (because ctypes +creates callbacks at import time, and callbacks need threads). + +.. branch: new-jit-log + +The new logging facility that integrates with and adds features to vmprof.com. + +.. branch: jitlog-32bit + +Resolve issues to use the new logging facility on a 32bit system + +.. branch: ep2016sprint + +Trying harder to make hash(-1) return -2, like it does on CPython + +.. branch: jitlog-exact-source-lines + +Log exact line positions in debug merge points. + +.. branch: null_byte_after_str + +Allocate all RPython strings with one extra byte, normally unused. +It is used to hold a final zero in case we need some ``char *`` +representation of the string, together with checks like ``not +can_move()`` or object pinning. Main new thing that this allows: +``ffi.from_buffer(string)`` in CFFI. Additionally, and most +importantly, CFFI calls that take directly a string as argument don't +copy the string any more---this is like CFFI on CPython. + +.. branch: resource_warning + +Add a new command line option -X track-resources which will produce +ResourceWarnings when the GC closes unclosed files and sockets. + +.. branch: cpyext-realloc + +Implement PyObject_Realloc + +.. branch: inline-blocks + +Improve a little bit the readability of the generated C code + +.. branch: improve-vmprof-testing + +Improved vmprof support: now tries hard to not miss any Python-level +frame in the captured stacks, even if there is the metainterp or +blackhole interp involved. Also fix the stacklet (greenlet) support. + +.. branch: py2-mappingproxy + +``type.__dict__`` now returns a ``dict_proxy`` object, like on CPython. +Previously it returned what looked like a regular dict object (but it +was already read-only). + + +.. branch: const-fold-we-are-jitted + +Reduce the size of the generated C code by constant-folding ``we_are_jitted`` +in non-jitcode. + +.. branch: memoryview-attributes + +Support for memoryview attributes (format, itemsize, ...). +Extends the cpyext emulation layer. + +.. branch: redirect-assembler-jitlog + +Log more information to properly rebuild the redirected traces in jitviewer. + +.. branch: cpyext-subclass + +Copy Py_TPFLAGS_CHECKTYPES, Py_TPFLAGS_HAVE_INPLACEOPS when inheriting diff --git a/pypy/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py --- a/pypy/goal/targetpypystandalone.py +++ b/pypy/goal/targetpypystandalone.py @@ -239,6 +239,10 @@ raise Exception("Cannot use the --output option with PyPy " "when --shared is on (it is by default). " "See issue #1971.") + if config.translation.profopt is not None: + raise Exception("Cannot use the --profopt option " + "when --shared is on (it is by default). " + "See issue #2398.") if sys.platform == 'win32': libdir = thisdir.join('..', '..', 'libs') libdir.ensure(dir=1) diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -208,7 +208,8 @@ def buffer_w(self, space, flags): w_impl = space.lookup(self, '__buffer__') if w_impl is not None: - w_result = space.get_and_call_function(w_impl, self) + w_result = space.get_and_call_function(w_impl, self, + space.newint(flags)) if space.isinstance_w(w_result, space.w_buffer): return w_result.buffer_w(space, flags) raise BufferInterfaceNotFound @@ -216,7 +217,8 @@ def readbuf_w(self, space): w_impl = space.lookup(self, '__buffer__') if w_impl is not None: - w_result = space.get_and_call_function(w_impl, self) + w_result = space.get_and_call_function(w_impl, self, + space.newint(space.BUF_FULL_RO)) if space.isinstance_w(w_result, space.w_buffer): return w_result.readbuf_w(space) raise BufferInterfaceNotFound @@ -224,7 +226,8 @@ def writebuf_w(self, space): w_impl = space.lookup(self, '__buffer__') if w_impl is not None: - w_result = space.get_and_call_function(w_impl, self) + w_result = space.get_and_call_function(w_impl, self, + space.newint(space.BUF_FULL)) if space.isinstance_w(w_result, space.w_buffer): return w_result.writebuf_w(space) raise BufferInterfaceNotFound @@ -232,7 +235,8 @@ def charbuf_w(self, space): w_impl = space.lookup(self, '__buffer__') if w_impl is not None: - w_result = space.get_and_call_function(w_impl, self) + w_result = space.get_and_call_function(w_impl, self, + space.newint(space.BUF_FULL_RO)) if space.isinstance_w(w_result, space.w_buffer): return w_result.charbuf_w(space) raise BufferInterfaceNotFound @@ -1424,6 +1428,9 @@ BUF_FORMAT = 0x0004 BUF_ND = 0x0008 BUF_STRIDES = 0x0010 | BUF_ND + BUF_C_CONTIGUOUS = 0x0020 | BUF_STRIDES + BUF_F_CONTIGUOUS = 0x0040 | BUF_STRIDES + BUF_ANY_CONTIGUOUS = 0x0080 | BUF_STRIDES BUF_INDIRECT = 0x0100 | BUF_STRIDES BUF_CONTIG_RO = BUF_ND @@ -1967,6 +1974,7 @@ 'ZeroDivisionError', 'RuntimeWarning', 'PendingDeprecationWarning', + 'UserWarning', ] if sys.platform.startswith("win"): 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 @@ -23,6 +23,14 @@ self.w_objtype = w_type self.w_self = w_obj_or_type + 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' + return space.wrap("<super: <class '%s'>, %s>" % ( + self.w_starttype.getname(space), 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): return self @@ -84,7 +92,10 @@ 'super', __new__ = generic_new_descr(W_Super), __init__ = interp2app(W_Super.descr_init), + __repr__ = interp2app(W_Super.descr_repr), __thisclass__ = interp_attrproperty_w("w_starttype", W_Super), + __self__ = interp_attrproperty_w("w_self", W_Super), + __self_class__ = interp_attrproperty_w("w_objtype", W_Super), __getattribute__ = interp2app(W_Super.getattribute), __get__ = interp2app(W_Super.get), __doc__ = """\ diff --git a/pypy/module/__builtin__/interp_classobj.py b/pypy/module/__builtin__/interp_classobj.py --- a/pypy/module/__builtin__/interp_classobj.py +++ b/pypy/module/__builtin__/interp_classobj.py @@ -38,6 +38,8 @@ class W_ClassObject(W_Root): + _immutable_fields_ = ['bases_w?[*]', 'w_dict?'] + def __init__(self, space, w_name, bases, w_dict): self.name = space.str_w(w_name) make_sure_not_resized(bases) @@ -75,6 +77,7 @@ "__bases__ items must be classes") self.bases_w = bases_w + @jit.unroll_safe def is_subclass_of(self, other): assert isinstance(other, W_ClassObject) if self is other: @@ -313,7 +316,7 @@ # This method ignores the instance dict and the __getattr__. # Returns None if not found. assert isinstance(name, str) - w_value = self.w_class.lookup(space, name) + w_value = jit.promote(self.w_class).lookup(space, name) if w_value is None: return None w_descr_get = space.lookup(w_value, '__get__') 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 @@ -250,6 +250,24 @@ assert super(B, B()).__thisclass__ is B assert super(A, B()).__thisclass__ is A + def test_super_self_selfclass(self): + class A(object): + pass + class B(A): + pass + b = B() + assert super(A, b).__self__ is b + assert super(A).__self__ is None + assert super(A, b).__self_class__ is B + assert super(A).__self_class__ is None + + def test_super_repr(self): + class A(object): + def __repr__(self): + return super(A, self).__repr__() + '!' + assert repr(A()).endswith('>!') + assert repr(super(A, A())) == "<super: <class 'A'>, <A object>>" + def test_property_docstring(self): assert property.__doc__.startswith('property') 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, entrypoint from rpython.rtyper.lltypesystem import rffi -VERSION = "1.8.0" +VERSION = "1.8.3" FFI_DEFAULT_ABI = clibffi.FFI_DEFAULT_ABI try: diff --git a/pypy/module/_cffi_backend/ctypearray.py b/pypy/module/_cffi_backend/ctypearray.py --- a/pypy/module/_cffi_backend/ctypearray.py +++ b/pypy/module/_cffi_backend/ctypearray.py @@ -11,7 +11,7 @@ from rpython.rlib.rarithmetic import ovfcheck from pypy.module._cffi_backend import cdataobj -from pypy.module._cffi_backend.ctypeptr import W_CTypePtrOrArray +from pypy.module._cffi_backend.ctypeptr import W_CTypePtrOrArray, W_CTypePointer from pypy.module._cffi_backend import ctypeprim @@ -22,6 +22,7 @@ is_nonfunc_pointer_or_array = True def __init__(self, space, ctptr, length, arraysize, extra): + assert isinstance(ctptr, W_CTypePointer) W_CTypePtrOrArray.__init__(self, space, arraysize, extra, 0, ctptr.ctitem) self.length = length diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -35,8 +35,7 @@ assert isinstance(ellipsis, bool) extra, xpos = self._compute_extra_text(fargs, fresult, ellipsis, abi) size = rffi.sizeof(rffi.VOIDP) - W_CTypePtrBase.__init__(self, space, size, extra, xpos, fresult, - could_cast_anything=False) + W_CTypePtrBase.__init__(self, space, size, extra, xpos, fresult) self.fargs = fargs self.ellipsis = ellipsis self.abi = abi @@ -59,6 +58,16 @@ lltype.free(self.cif_descr, flavor='raw') self.cif_descr = lltype.nullptr(CIF_DESCRIPTION) + def is_unichar_ptr_or_array(self): + return False + + def is_char_or_unichar_ptr_or_array(self): + return False + + def string(self, cdataobj, maxlen): + # Can't use ffi.string() on a function pointer + return W_CType.string(self, cdataobj, maxlen) + def new_ctypefunc_completing_argtypes(self, args_w): space = self.space nargs_declared = len(self.fargs) diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py --- a/pypy/module/_cffi_backend/ctypeobj.py +++ b/pypy/module/_cffi_backend/ctypeobj.py @@ -19,7 +19,6 @@ # XXX this could be improved with an elidable method get_size() # that raises in case it's still -1... - cast_anything = False is_primitive_integer = False is_nonfunc_pointer_or_array = False is_indirect_arg_for_call_python = False diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -120,7 +120,6 @@ class W_CTypePrimitiveChar(W_CTypePrimitiveCharOrUniChar): _attrs_ = [] - cast_anything = True def cast_to_int(self, cdata): return self.space.wrap(ord(cdata[0])) 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 @@ -14,12 +14,11 @@ class W_CTypePtrOrArray(W_CType): - _attrs_ = ['ctitem', 'can_cast_anything', 'accept_str', 'length'] - _immutable_fields_ = ['ctitem', 'can_cast_anything', 'accept_str', 'length'] + _attrs_ = ['ctitem', 'accept_str', 'length'] + _immutable_fields_ = ['ctitem', 'accept_str', 'length'] length = -1 - def __init__(self, space, size, extra, extra_position, ctitem, - could_cast_anything=True): + def __init__(self, space, size, extra, extra_position, ctitem): name, name_position = ctitem.insert_name(extra, extra_position) W_CType.__init__(self, space, size, name, name_position) # this is the "underlying type": @@ -27,10 +26,11 @@ # - for arrays, it is the array item type # - for functions, it is the return type self.ctitem = ctitem - self.can_cast_anything = could_cast_anything and ctitem.cast_anything - self.accept_str = (self.can_cast_anything or - (ctitem.is_primitive_integer and - ctitem.size == rffi.sizeof(lltype.Char))) + self.accept_str = (self.is_nonfunc_pointer_or_array and + (isinstance(ctitem, ctypevoid.W_CTypeVoid) or + isinstance(ctitem, ctypeprim.W_CTypePrimitiveChar) or + (ctitem.is_primitive_integer and + ctitem.size == rffi.sizeof(lltype.Char)))) def is_unichar_ptr_or_array(self): return isinstance(self.ctitem, ctypeprim.W_CTypePrimitiveUniChar) @@ -137,7 +137,10 @@ class W_CTypePtrBase(W_CTypePtrOrArray): # base class for both pointers and pointers-to-functions - _attrs_ = [] + _attrs_ = ['is_void_ptr', 'is_voidchar_ptr'] + _immutable_fields_ = ['is_void_ptr', 'is_voidchar_ptr'] + is_void_ptr = False + is_voidchar_ptr = False def convert_to_object(self, cdata): ptrdata = rffi.cast(rffi.CCHARPP, cdata)[0] @@ -154,7 +157,16 @@ else: raise self._convert_error("compatible pointer", w_ob) if self is not other: - if not (self.can_cast_anything or other.can_cast_anything): + 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.wrap(msg), space.w_UserWarning, stacklevel=1) + else: raise self._convert_error("compatible pointer", w_ob) rffi.cast(rffi.CCHARPP, cdata)[0] = w_ob.unsafe_escaping_ptr() @@ -165,8 +177,8 @@ class W_CTypePointer(W_CTypePtrBase): - _attrs_ = ['is_file', 'cache_array_type', 'is_void_ptr', '_array_types'] - _immutable_fields_ = ['is_file', 'cache_array_type?', 'is_void_ptr'] + _attrs_ = ['is_file', 'cache_array_type', '_array_types'] + _immutable_fields_ = ['is_file', 'cache_array_type?'] kind = "pointer" cache_array_type = None is_nonfunc_pointer_or_array = True @@ -181,6 +193,8 @@ self.is_file = (ctitem.name == "struct _IO_FILE" or ctitem.name == "FILE") self.is_void_ptr = isinstance(ctitem, ctypevoid.W_CTypeVoid) + self.is_voidchar_ptr = (self.is_void_ptr or + isinstance(ctitem, ctypeprim.W_CTypePrimitiveChar)) W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem) def newp(self, w_init, allocator): diff --git a/pypy/module/_cffi_backend/ctypestruct.py b/pypy/module/_cffi_backend/ctypestruct.py --- a/pypy/module/_cffi_backend/ctypestruct.py +++ b/pypy/module/_cffi_backend/ctypestruct.py @@ -105,9 +105,6 @@ return True return False - def _check_only_one_argument_for_union(self, w_ob): - pass - def convert_from_object(self, cdata, w_ob): if not self._copy_from_same(cdata, w_ob): self.convert_struct_from_object(cdata, w_ob, optvarsize=-1) @@ -117,19 +114,24 @@ ) def convert_struct_from_object(self, cdata, w_ob, optvarsize): self.force_lazy_struct() - self._check_only_one_argument_for_union(w_ob) space = self.space if (space.isinstance_w(w_ob, space.w_list) or space.isinstance_w(w_ob, space.w_tuple)): lst_w = space.listview(w_ob) - if len(lst_w) > len(self._fields_list): - raise oefmt(space.w_ValueError, - "too many initializers for '%s' (got %d)", - self.name, len(lst_w)) - for i in range(len(lst_w)): - optvarsize = self._fields_list[i].write_v(cdata, lst_w[i], + j = 0 + for w_obj in lst_w: + try: + while (self._fields_list[j].flags & + W_CField.BF_IGNORE_IN_CTOR): + j += 1 + except IndexError: + raise oefmt(space.w_ValueError, + "too many initializers for '%s' (got %d)", + self.name, len(lst_w)) + optvarsize = self._fields_list[j].write_v(cdata, w_obj, optvarsize) + j += 1 return optvarsize elif space.isinstance_w(w_ob, space.w_dict): @@ -185,14 +187,6 @@ class W_CTypeUnion(W_CTypeStructOrUnion): kind = "union" - def _check_only_one_argument_for_union(self, w_ob): - space = self.space - n = space.int_w(space.len(w_ob)) - if n > 1: - raise oefmt(space.w_ValueError, - "initializer for '%s': %d items given, but only one " - "supported (use a dict if needed)", self.name, n) - class W_CField(W_Root): _immutable_ = True @@ -200,18 +194,21 @@ BS_REGULAR = -1 BS_EMPTY_ARRAY = -2 - def __init__(self, ctype, offset, bitshift, bitsize): + BF_IGNORE_IN_CTOR = 0x01 + + def __init__(self, ctype, offset, bitshift, bitsize, flags): self.ctype = ctype self.offset = offset self.bitshift = bitshift # >= 0: bitshift; or BS_REGULAR/BS_EMPTY_ARRAY self.bitsize = bitsize + self.flags = flags # BF_xxx def is_bitfield(self): return self.bitshift >= 0 - def make_shifted(self, offset): + def make_shifted(self, offset, fflags): return W_CField(self.ctype, offset + self.offset, - self.bitshift, self.bitsize) + self.bitshift, self.bitsize, self.flags | fflags) def read(self, cdata): cdata = rffi.ptradd(cdata, self.offset) @@ -341,5 +338,6 @@ offset = interp_attrproperty('offset', W_CField), bitshift = interp_attrproperty('bitshift', W_CField), bitsize = interp_attrproperty('bitsize', W_CField), + flags = interp_attrproperty('flags', W_CField), ) W_CField.typedef.acceptable_as_base_class = False diff --git a/pypy/module/_cffi_backend/ctypevoid.py b/pypy/module/_cffi_backend/ctypevoid.py --- a/pypy/module/_cffi_backend/ctypevoid.py +++ b/pypy/module/_cffi_backend/ctypevoid.py @@ -7,7 +7,6 @@ class W_CTypeVoid(W_CType): _attrs_ = [] - cast_anything = True kind = "void" def __init__(self, space): diff --git a/pypy/module/_cffi_backend/handle.py b/pypy/module/_cffi_backend/handle.py --- a/pypy/module/_cffi_backend/handle.py +++ b/pypy/module/_cffi_backend/handle.py @@ -32,8 +32,8 @@ @unwrap_spec(w_cdata=cdataobj.W_CData) def from_handle(space, w_cdata): ctype = w_cdata.ctype - if (not isinstance(ctype, ctypeptr.W_CTypePtrOrArray) or - not ctype.can_cast_anything): + if (not isinstance(ctype, ctypeptr.W_CTypePointer) or + not ctype.is_voidchar_ptr): raise oefmt(space.w_TypeError, "expected a 'cdata' object with a 'void *' out of " "new_handle(), got '%s'", ctype.name) diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -345,6 +345,11 @@ if alignment < falign and do_align: alignment = falign # + if is_union and i > 0: + fflags = ctypestruct.W_CField.BF_IGNORE_IN_CTOR + else: + fflags = 0 + # if fbitsize < 0: # not a bitfield: common case @@ -372,7 +377,7 @@ for name, srcfld in ftype._fields_dict.items(): srcfield2names[srcfld] = name for srcfld in ftype._fields_list: - fld = srcfld.make_shifted(boffset // 8) + fld = srcfld.make_shifted(boffset // 8, fflags) fields_list.append(fld) try: fields_dict[srcfield2names[srcfld]] = fld @@ -382,7 +387,8 @@ w_ctype._custom_field_pos = True else: # a regular field - fld = ctypestruct.W_CField(ftype, boffset // 8, bs_flag, -1) + fld = ctypestruct.W_CField(ftype, boffset // 8, bs_flag, -1, + fflags) fields_list.append(fld) fields_dict[fname] = fld @@ -489,7 +495,7 @@ bitshift = 8 * ftype.size - fbitsize- bitshift fld = ctypestruct.W_CField(ftype, field_offset_bytes, - bitshift, fbitsize) + bitshift, fbitsize, fflags) fields_list.append(fld) fields_dict[fname] = fld 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.8.0", ("This test_c.py file is for testing a version" +assert __version__ == "1.8.3", ("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,): @@ -2525,6 +2525,25 @@ assert d[2][1].bitshift == -1 assert d[2][1].bitsize == -1 +def test_nested_anonymous_struct_2(): + BInt = new_primitive_type("int") + BStruct = new_struct_type("struct foo") + BInnerUnion = new_union_type("union bar") + complete_struct_or_union(BInnerUnion, [('a1', BInt, -1), + ('a2', BInt, -1)]) + complete_struct_or_union(BStruct, [('b1', BInt, -1), + ('', BInnerUnion, -1), + ('b2', BInt, -1)]) + assert sizeof(BInnerUnion) == sizeof(BInt) + assert sizeof(BStruct) == sizeof(BInt) * 3 + fields = [(name, fld.offset, fld.flags) for (name, fld) in BStruct.fields] + assert fields == [ + ('b1', 0 * sizeof(BInt), 0), + ('a1', 1 * sizeof(BInt), 0), + ('a2', 1 * sizeof(BInt), 1), + ('b2', 2 * sizeof(BInt), 0), + ] + def test_sizeof_union(): # a union has the largest alignment of its members, and a total size # that is the largest of its items *possibly further aligned* if @@ -3646,3 +3665,27 @@ check_dir(pp, []) check_dir(pp[0], ['a1', 'a2']) check_dir(pp[0][0], ['a1', 'a2']) + +def test_char_pointer_conversion(): + import warnings + assert __version__.startswith(("1.8", "1.9")), ( + "consider turning the warning into an error") + BCharP = new_pointer_type(new_primitive_type("char")) + BIntP = new_pointer_type(new_primitive_type("int")) + BVoidP = new_pointer_type(new_void_type()) + z1 = cast(BCharP, 0) + z2 = cast(BIntP, 0) + z3 = cast(BVoidP, 0) + with warnings.catch_warnings(record=True) as w: + newp(new_pointer_type(BIntP), z1) # warn + assert len(w) == 1 + newp(new_pointer_type(BVoidP), z1) # fine + assert len(w) == 1 + newp(new_pointer_type(BCharP), z2) # warn + assert len(w) == 2 + newp(new_pointer_type(BVoidP), z2) # fine + assert len(w) == 2 + newp(new_pointer_type(BCharP), z3) # fine + assert len(w) == 2 + newp(new_pointer_type(BIntP), z3) # fine + assert len(w) == 2 diff --git a/pypy/module/_cffi_backend/test/test_ffi_obj.py b/pypy/module/_cffi_backend/test/test_ffi_obj.py --- a/pypy/module/_cffi_backend/test/test_ffi_obj.py +++ b/pypy/module/_cffi_backend/test/test_ffi_obj.py @@ -503,3 +503,10 @@ assert ffi.unpack(p+1, 7) == b"bc\x00def\x00" p = ffi.new("int[]", [-123456789]) assert ffi.unpack(p, 1) == [-123456789] + + def test_bug_1(self): + import _cffi_backend as _cffi1_backend + ffi = _cffi1_backend.FFI() + q = ffi.new("char[]", "abcd") + p = ffi.cast("char(*)(void)", q) + raises(TypeError, ffi.string, p) diff --git a/pypy/module/_sre/__init__.py b/pypy/module/_sre/__init__.py --- a/pypy/module/_sre/__init__.py +++ b/pypy/module/_sre/__init__.py @@ -1,4 +1,4 @@ -from pypy.interpreter.mixedmodule import MixedModule +from pypy.interpreter.mixedmodule import MixedModule class Module(MixedModule): @@ -7,7 +7,7 @@ interpleveldefs = { 'CODESIZE': 'space.wrap(interp_sre.CODESIZE)', - 'MAGIC': 'space.wrap(interp_sre.MAGIC)', + 'MAGIC': 'space.newint(20031017)', 'MAXREPEAT': 'space.wrap(interp_sre.MAXREPEAT)', 'compile': 'interp_sre.W_SRE_Pattern', 'getlower': 'interp_sre.w_getlower', diff --git a/pypy/module/_sre/interp_sre.py b/pypy/module/_sre/interp_sre.py --- a/pypy/module/_sre/interp_sre.py +++ b/pypy/module/_sre/interp_sre.py @@ -14,7 +14,7 @@ # Constants and exposed functions from rpython.rlib.rsre import rsre_core -from rpython.rlib.rsre.rsre_char import MAGIC, CODESIZE, MAXREPEAT, getlower, set_unicode_db +from rpython.rlib.rsre.rsre_char import CODESIZE, MAXREPEAT, getlower, set_unicode_db @unwrap_spec(char_ord=int, flags=int) diff --git a/pypy/module/_ssl/test/test_ssl.py b/pypy/module/_ssl/test/test_ssl.py --- a/pypy/module/_ssl/test/test_ssl.py +++ b/pypy/module/_ssl/test/test_ssl.py @@ -450,7 +450,12 @@ # For compatibility assert exc.value.errno == _ssl.SSL_ERROR_WANT_READ finally: - c.shutdown() + try: + c.shutdown() + except _ssl.SSLError: + # If the expected exception was raised, the SSLContext + # can't be shut down yet + pass finally: s.close() diff --git a/pypy/module/_winreg/interp_winreg.py b/pypy/module/_winreg/interp_winreg.py --- a/pypy/module/_winreg/interp_winreg.py +++ b/pypy/module/_winreg/interp_winreg.py @@ -358,9 +358,15 @@ elif typ == rwinreg.REG_SZ or typ == rwinreg.REG_EXPAND_SZ: if not buflen: - return space.wrap("") - s = rffi.charp2strn(rffi.cast(rffi.CCHARP, buf), buflen) - return space.wrap(s) + s = "" + else: + # may or may not have a trailing NULL in the buffer. + buf = rffi.cast(rffi.CCHARP, buf) + if buf[buflen - 1] == '\x00': + buflen -= 1 + s = rffi.charp2strn(buf, buflen) + w_s = space.wrap(s) + return space.call_method(w_s, 'decode', space.wrap('mbcs')) elif typ == rwinreg.REG_MULTI_SZ: if not buflen: @@ -460,7 +466,7 @@ return space.newtuple([ convert_from_regdata(space, databuf, length, retType[0]), - space.wrap(retType[0]), + space.wrap(intmask(retType[0])), ]) @unwrap_spec(subkey=str) @@ -612,7 +618,7 @@ space.wrap(rffi.charp2str(valuebuf)), convert_from_regdata(space, databuf, length, retType[0]), - space.wrap(retType[0]), + space.wrap(intmask(retType[0])), ]) @unwrap_spec(index=int) diff --git a/pypy/module/_winreg/test/test_winreg.py b/pypy/module/_winreg/test/test_winreg.py --- a/pypy/module/_winreg/test/test_winreg.py +++ b/pypy/module/_winreg/test/test_winreg.py @@ -151,6 +151,7 @@ def test_readValues(self): from _winreg import OpenKey, EnumValue, QueryValueEx, EnumKey + from _winreg import REG_SZ, REG_EXPAND_SZ key = OpenKey(self.root_key, self.test_key_name) sub_key = OpenKey(key, "sub_key") index = 0 @@ -164,7 +165,10 @@ assert index == len(self.test_data) for name, value, type in self.test_data: - assert QueryValueEx(sub_key, name) == (value, type) + result = QueryValueEx(sub_key, name) + assert result == (value, type) + if type == REG_SZ or type == REG_EXPAND_SZ: + assert isinstance(result[0], unicode) # not string assert EnumKey(key, 0) == "sub_key" raises(EnvironmentError, EnumKey, key, 1) diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -597,6 +597,18 @@ def getlength(self): return self.array.len * self.array.itemsize + def getformat(self): + return self.array.typecode + + def getitemsize(self): + return self.array.itemsize + + def getndim(self): + return 1 + + def getstrides(self): + return [self.getitemsize()] + def getitem(self, index): array = self.array data = array._charbuf_start() diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py --- a/pypy/module/cpyext/api.py +++ b/pypy/module/cpyext/api.py @@ -119,10 +119,10 @@ constant_names = """ Py_TPFLAGS_READY Py_TPFLAGS_READYING Py_TPFLAGS_HAVE_GETCHARBUFFER -METH_COEXIST METH_STATIC METH_CLASS Py_TPFLAGS_BASETYPE -METH_NOARGS METH_VARARGS METH_KEYWORDS METH_O -Py_TPFLAGS_HEAPTYPE Py_TPFLAGS_HAVE_CLASS -Py_LT Py_LE Py_EQ Py_NE Py_GT Py_GE Py_TPFLAGS_CHECKTYPES +METH_COEXIST METH_STATIC METH_CLASS Py_TPFLAGS_BASETYPE Py_MAX_FMT +METH_NOARGS METH_VARARGS METH_KEYWORDS METH_O Py_TPFLAGS_HAVE_INPLACEOPS +Py_TPFLAGS_HEAPTYPE Py_TPFLAGS_HAVE_CLASS Py_TPFLAGS_HAVE_NEWBUFFER +Py_LT Py_LE Py_EQ Py_NE Py_GT Py_GE Py_TPFLAGS_CHECKTYPES Py_MAX_NDIMS """.split() for name in constant_names: setattr(CConfig_constants, name, rffi_platform.ConstantInteger(name)) @@ -645,10 +645,14 @@ ('format', rffi.CCHARP), ('shape', Py_ssize_tP), ('strides', Py_ssize_tP), + ('_format', rffi.CFixedArray(rffi.UCHAR, Py_MAX_FMT)), + ('_shape', rffi.CFixedArray(Py_ssize_t, Py_MAX_NDIMS)), + ('_strides', rffi.CFixedArray(Py_ssize_t, Py_MAX_NDIMS)), ('suboffsets', Py_ssize_tP), #('smalltable', rffi.CFixedArray(Py_ssize_t, 2)), ('internal', rffi.VOIDP) )) +Py_bufferP = lltype.Ptr(Py_buffer) @specialize.memo() def is_PyObject(TYPE): @@ -976,8 +980,10 @@ py_type_ready(space, get_capsule_type()) INIT_FUNCTIONS.append(init_types) from pypy.module.posix.interp_posix import add_fork_hook - reinit_tls = rffi.llexternal('%sThread_ReInitTLS' % prefix, [], lltype.Void, - compilation_info=eci) + _reinit_tls = rffi.llexternal('%sThread_ReInitTLS' % prefix, [], + lltype.Void, compilation_info=eci) + def reinit_tls(space): + _reinit_tls() add_fork_hook('child', reinit_tls) def init_function(func): diff --git a/pypy/module/cpyext/buffer.py b/pypy/module/cpyext/buffer.py --- a/pypy/module/cpyext/buffer.py +++ b/pypy/module/cpyext/buffer.py @@ -1,41 +1,15 @@ -from pypy.interpreter.error import oefmt -from rpython.rtyper.lltypesystem import rffi, lltype +from rpython.rtyper.lltypesystem import rffi from pypy.module.cpyext.api import ( - cpython_api, CANNOT_FAIL, Py_buffer) + cpython_api, CANNOT_FAIL, Py_TPFLAGS_HAVE_NEWBUFFER) from pypy.module.cpyext.pyobject import PyObject @cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) -def PyObject_CheckBuffer(space, w_obj): +def PyObject_CheckBuffer(space, pyobj): """Return 1 if obj supports the buffer interface otherwise 0.""" - return 0 # the bf_getbuffer field is never filled by cpyext + as_buffer = pyobj.c_ob_type.c_tp_as_buffer + flags = pyobj.c_ob_type.c_tp_flags + if (flags & Py_TPFLAGS_HAVE_NEWBUFFER and as_buffer.c_bf_getbuffer): + return 1 + return 0 _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit