Author: Richard Plangger <[email protected]>
Branch: vmprof-native
Changeset: r90790:dd7413118eca
Date: 2017-03-22 11:45 -0300
http://bitbucket.org/pypy/pypy/changeset/dd7413118eca/
Log: merge default
diff --git a/.hgignore b/.hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -80,5 +80,6 @@
.hypothesis/
^release/
^rpython/_cache$
+^\.cache$
pypy/module/cppyy/.+/*\.pcm
diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -34,3 +34,5 @@
050d84dd78997f021acf0e133934275d63547cc0 release-pypy2.7-v5.4.1
0e2d9a73f5a1818d0245d75daccdbe21b2d5c3ef release-pypy2.7-v5.4.1
aff251e543859ce4508159dd9f1a82a2f553de00 release-pypy2.7-v5.6.0
+fa3249d55d15b9829e1be69cdf45b5a44cec902d release-pypy2.7-v5.7.0
+b16a4363e930f6401bceb499b9520955504c6cb0 release-pypy3.5-v5.7.0
diff --git a/README.rst b/README.rst
--- a/README.rst
+++ b/README.rst
@@ -27,14 +27,19 @@
Building
========
-build with:
+First switch to or download the correct branch. The basic choices are
+``default`` for Python 2.7 and, for Python 3.X, the corresponding py3.X
+branch (e.g. ``py3.5``).
+
+Build with:
.. code-block:: console
$ rpython/bin/rpython -Ojit pypy/goal/targetpypystandalone.py
-This ends up with ``pypy-c`` binary in the main pypy directory. We suggest
-to use virtualenv with the resulting pypy-c as the interpreter; you can
-find more details about various installation schemes here:
+This ends up with a ``pypy-c`` or ``pypy3-c`` binary in the main pypy
+directory. We suggest to use virtualenv with the resulting
+pypy-c/pypy3-c as the interpreter; you can find more details about
+various installation schemes here:
http://doc.pypy.org/en/latest/install.html
diff --git a/lib-python/2.7/sysconfig.py b/lib-python/2.7/sysconfig.py
--- a/lib-python/2.7/sysconfig.py
+++ b/lib-python/2.7/sysconfig.py
@@ -29,8 +29,8 @@
'pypy': {
'stdlib': '{base}/lib-{implementation_lower}/{py_version_short}',
'platstdlib': '{base}/lib-{implementation_lower}/{py_version_short}',
- 'purelib': '{base}/lib-{implementation_lower}/{py_version_short}',
- 'platlib': '{base}/lib-{implementation_lower}/{py_version_short}',
+ 'purelib': '{base}/site-packages',
+ 'platlib': '{base}/site-packages',
'include': '{base}/include',
'platinclude': '{base}/include',
'scripts': '{base}/bin',
diff --git a/lib-python/2.7/weakref.py b/lib-python/2.7/weakref.py
--- a/lib-python/2.7/weakref.py
+++ b/lib-python/2.7/weakref.py
@@ -36,9 +36,9 @@
except ImportError:
def _delitem_if_value_is(d, key, value):
try:
- if self.data[key] is value: # fall-back: there is a potential
+ if d[key] is value: # fall-back: there is a potential
# race condition in multithreaded programs HERE
- del self.data[key]
+ del d[key]
except KeyError:
pass
diff --git a/pypy/doc/build.rst b/pypy/doc/build.rst
--- a/pypy/doc/build.rst
+++ b/pypy/doc/build.rst
@@ -110,22 +110,22 @@
apt-get install gcc make libffi-dev pkg-config libz-dev libbz2-dev \
libsqlite3-dev libncurses-dev libexpat1-dev libssl-dev libgdbm-dev \
- tk-dev libgc-dev \
+ tk-dev libgc-dev python-cffi \
liblzma-dev # For lzma on PyPy3.
On Fedora::
dnf install gcc make libffi-devel pkgconfig zlib-devel bzip2-devel \
sqlite-devel ncurses-devel expat-devel openssl-devel tk-devel \
- gdbm-devel \
+ gdbm-devel python-cffi\
xz-devel # For lzma on PyPy3.
On SLES11::
zypper install gcc make python-devel pkg-config \
zlib-devel libopenssl-devel libbz2-devel sqlite3-devel \
- libexpat-devel libffi-devel python-curses \
- xz-devel # For lzma on PyPy3.
+ libexpat-devel libffi-devel python-curses python-cffi \
+ xz-devel # For lzma on PyPy3.
(XXX plus the SLES11 version of libgdbm-dev and tk-dev)
On Mac OS X, most of these build-time dependencies are installed alongside
diff --git a/pypy/doc/release-v5.7.0.rst b/pypy/doc/release-v5.7.0.rst
--- a/pypy/doc/release-v5.7.0.rst
+++ b/pypy/doc/release-v5.7.0.rst
@@ -2,23 +2,27 @@
PyPy2.7 and PyPy3.5 v5.7 - two in one release
=============================================
-We have released PyPy2.7 and a beta-quality PyPy3.5 v5.7.
+The PyPy team is proud to release both PyPy2.7 v5.7 (an interpreter supporting
+Python v2.7 syntax), and a beta-quality PyPy3.5 v5.7 (an interpreter for Python
+v3.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
-PyPy 3.5 (our first in the 3.5 series) includes the upstream stdlib version
+PyPy3.5 (our first in the 3.5 series) includes the upstream stdlib version
3.5.3.
We continue to make incremental improvements to our C-API
-compatibility layer (cpyext). PyPy2 can now import and run many c-extension
-packages, among the most notable are numpy, cython, and pandas. Performance may
+compatibility layer (cpyext). PyPy2 can now import and run many C-extension
+packages, among the most notable are Numpy, Cython, and Pandas. Performance may
be slower than CPython, especially for frequently-called short C functions.
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 proceeds at a good pace on the PyPy3.5
version due to a grant_ from the Mozilla Foundation, hence our first 3.5.3 beta
-release. Thanks Mozilla !!! While we do not pass all tests, asyncio works and
+release. Thanks Mozilla !!! While we do not pass all tests yet, asyncio works
and
as `these benchmarks show`_ it already gives a nice speed bump.
-We also backported the ``f""`` formatting from 3.6 (as an expection; otherwise
+We also backported the ``f""`` formatting from 3.6 (as an exception; otherwise
"PyPy3.5" supports the Python 3.5 language).
CFFI_ has been updated to 1.10, improving an already great package for
@@ -65,7 +69,7 @@
We also welcome developers of other `dynamic languages`_ to see what RPython
can do for them.
-This release supports:
+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)
@@ -80,63 +84,60 @@
.. _`dynamic languages`: http://rpython.readthedocs.io/en/latest/examples.html
Highlights of the PyPy2.7, cpyext, and RPython changes (since 5.6 released
Nov, 2016)
-=============================================================================================
+=====================================================================================
See also issues that were resolved_
* New features and cleanups
* update the format of the PYPYLOG file and improvements to vmprof
- * improve the consistency of RPython annotation unions
- * emit more sysconfig values for downstream cextension packages
- * add PyAnySet_Check, PyModule_GetName, PyWeakref_Check*,
- _PyImport_{Acquire,Release}Lock, PyGen_Check*, PyOS_AfterFork,
- * add translation option --keepgoing to continue after the first
AnnotationError
+ * emit more sysconfig values for downstream cextension packages including
+ properly setting purelib and platlib to site-packages
+ * add ``PyAnySet_Check``, ``PyModule_GetName``, ``PyWeakref_Check*``,
+ ``_PyImport_{Acquire,Release}Lock``, ``PyGen_Check*``, ``PyOS_AfterFork``,
* detect and raise on recreation of a PyPy object from a PyObject during
tp_dealloc
* refactor and clean up poor handling of unicode exposed in work on py3.5
- * builtin cppyy_ supports C++ 11, 14, etc. via cling (reflex has been
removed)
- * add translation time --disable_entrypoints option for embedding PyPy
together
- with another RPython VM
- * adapt ``weakref`` according to Python issue #19542, will be in CPython
2.7.14
+ * builtin module cppyy_ supports C++ 11, 14, etc. via cling (reflex has been
removed)
+ * adapt ``weakref`` according to CPython issue #19542_, will be in CPython
2.7.14
* support translations with cpyext and the Boehm GC (for special cases like
- revdb
+ RevDB_
* implement ``StringBuffer.get_raw_address`` for the buffer protocol, it is
now possible to obtain the address of any readonly object without pinning
it
* refactor the initialization code in translating cpyext
- * fix ``"".replace("", "x", num)`` to give the same result as CPython
* use a cffi-style C parser to create rffi objects in cpyext, now the
- translating python must have cffi available
- * add a rpython implementation of siphash24, allow choosing hash algorithm
- randomizing the seed
- * make ``attach_gdb`` work on Windows (with Visual Studio Debugger)
+ translating Python must have either ``cffi`` or ``pycparser`` available
* implement ``move_to_end(last=True/False)`` on RPython ordered dicts, make
available as ``__pypy__.move_to_end`` and, on py3.5,
``OrderedDict.move_to_end()``
* remove completely RPython ``space.wrap`` in a major cleanup, differentiate
between ``space.newtext`` and ``space.newbytes`` on py3.5
- * improve shadowstack to where it is now the default in place of asmgcc
+ * any uncaught RPython exception in the interpreter is turned into a
+ SystemError (rather than a segfault)
+ * add translation time --disable_entrypoints option for embedding PyPy
together
+ with another RPython VM
+
* Bug Fixes
- * any uncaught RPython exception in the interpreter is turned into a
- SystemError (rather than a segfault)
+ * fix ``"".replace("", "x", num)`` to give the same result as CPython
* create log files without the executable bit
- * disable clock_gettime() on OS/X, since we support 10.11 and it was only
+ * disable ``clock_gettime()`` on OS/X, since we support 10.11 and it was only
added in 10.12
- * support HAVE_FSTATVFS which was unintentionally always false
- * fix user-created C-API heaptype, issue #2434
- * fix PyDict_Update is not actually the same as dict.update
- * assign tp_doc on PyTypeObject and tie it to the app-level __doc__ attribute
- issue #2446
+ * support ``HAVE_FSTATVFS`` which was unintentionally always false
+ * fix user-created C-API heaptype, issue #2434_
+ * fix ``PyDict_Update`` is not actually the same as ``dict.update``
+ * assign ``tp_doc`` on ``PyTypeObject`` and tie it to the app-level
``__doc__`` attribute
+ issue #2446_
* clean up memory leaks around ``PyObject_GetBuffer``,
``PyMemoryView_GET_BUFFER``,
``PyMemoryView_FromBuffer``, and ``PyBuffer_Release``
- * improve support for creating c-extension objects from app-level classes,
- filling more slots especially ``tp_new`` and ``tp_dealloc``
- * add rstack.stack_almost_full() and use it to avoid stack overflow due to
- the JIT where possible
- * fix for ctypes.c_bool returning bool restype issue #2475
+ * improve support for creating C-extension objects from app-level classes,
+ filling more slots, especially ``tp_new`` and ``tp_dealloc``
+ * fix for ``ctypes.c_bool`` returning ``bool`` restype, issue #2475_
* fix in corner cases with the GIL and C-API functions
+ * allow overriding thread.local.__init__ in a subclass, issue #2501_
+ * allow ``PyClass_New`` to be called with NULL as the first arguemnt, issue
#2504_
+
* Performance improvements:
@@ -158,17 +159,28 @@
information across failing guards
* add optimized "zero-copy" path for ``io.FileIO.readinto``
+* RPython improvements
+
+ * improve the consistency of RPython annotation unions
+ * add translation option --keepgoing to continue after the first
AnnotationError
+ * improve shadowstack to where it is now the default in place of asmgcc
+ * add a rpython implementation of siphash24, allow choosing hash algorithm
+ randomizing the seed
+ * add rstack.stack_almost_full() and use it to avoid stack overflow due to
+ the JIT where possible
+
Highlights of the PyPy3.5 release (since 5.5 alpha released Oct, 2016)
-=========================================================
+==========================================================================
-Development moved from the py3k branch to the py3.5 branch in the pypy
bitbucket repo
+Development moved from the py3k branch to the py3.5 branch in the PyPy
bitbucket repo.
* New features
- * this first PyPy3.5 release implements much, but not all, of Python 3.5.3
+ * this first PyPy3.5 release implements most of Python 3.5.3, exceptions are
listed below
* PEP 456 allowing secure and interchangable hash algorithms
* use cryptography_'s cffi backend for SSL
+
* Bug Fixes
* implement fixes for some CPython issues that arose since the last release
@@ -176,12 +188,21 @@
* Performance improvements:
- * do not create a list whenever descr_new of a bytesobject is called
- *
- *
- *
+ * do not create a list whenever ``descr_new`` of a ``bytesobject`` is called
+
+* The following features of Python 3.5 are not implemented yet in PyPy:
+
+ * PEP 442: Safe object finalization
+ * PEP 489: Multi-phase extension module initialization
.. _resolved: whatsnew-pypy2-5.7.0.html
+.. _19542: https://bugs.python.org/issue19542
+.. _2434:
https://bitbucket.org/pypy/pypy/issues/2434/support-pybind11-in-conjunction-with-pypys
+.. _2446:
https://bitbucket.org/pypy/pypy/issues/2446/cpyext-tp_doc-field-not-reflected-on
+.. _2475: https://bitbucket.org/pypy/pypy/issues/2475
+.. _2501: https://bitbucket.org/pypy/pypy/issues/2501
+.. _2504: https://bitbucket.org/pypy/pypy/issues/2504
+.. _RevDB: https://bitbucket.org/pypy/revdb
.. _cryptography: https://cryptography.io
.. _cppyy: cppyy.html
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
@@ -48,3 +48,4 @@
w_modules_dict = space.sys.get('modules')
space.setitem(w_modules_dict, w_name, module)
space.setitem(w_modules_dict, space.newtext(name + '.lib'), lib)
+ return module
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
@@ -1469,10 +1469,6 @@
copy_header_files(cts, trunk_include, use_micronumpy)
-def _load_from_cffi(space, name, path, initptr):
- from pypy.module._cffi_backend import cffi1_module
- cffi1_module.load_cffi1_module(space, name, path, initptr)
-
@unwrap_spec(path='text', name='text')
def load_extension_module(space, path, name):
# note: this is used both to load CPython-API-style C extension
@@ -1505,11 +1501,11 @@
pass
else:
try:
- _load_from_cffi(space, name, path, initptr)
+ from pypy.module._cffi_backend import cffi1_module
+ return cffi1_module.load_cffi1_module(space, name, path,
initptr)
except:
rdynload.dlclose(dll)
raise
- return
#
if space.config.objspace.usemodules.cpyext:
also_look_for = 'init%s' % (basename,)
@@ -1518,8 +1514,7 @@
except KeyError:
pass
else:
- load_cpyext_module(space, name, path, dll, initptr)
- return
+ return load_cpyext_module(space, name, path, dll, initptr)
if look_for is not None:
look_for += ' or ' + also_look_for
else:
@@ -1535,9 +1530,10 @@
space.getbuiltinmodule("cpyext") # mandatory to init cpyext
state = space.fromcache(State)
- if state.find_extension(name, path) is not None:
+ w_mod = state.find_extension(name, path)
+ if w_mod is not None:
rdynload.dlclose(dll)
- return
+ return w_mod
old_context = state.package_context
state.package_context = name, path
try:
@@ -1546,7 +1542,8 @@
state.check_and_raise_exception()
finally:
state.package_context = old_context
- state.fixup_extension(name, path)
+ w_mod = state.fixup_extension(name, path)
+ return w_mod
@specialize.ll()
def generic_cpy_call(space, func, *args):
diff --git a/pypy/module/cpyext/classobject.py
b/pypy/module/cpyext/classobject.py
--- a/pypy/module/cpyext/classobject.py
+++ b/pypy/module/cpyext/classobject.py
@@ -39,6 +39,8 @@
@cpython_api([PyObject, PyObject, PyObject], PyObject)
def PyClass_New(space, w_bases, w_dict, w_name):
+ if w_bases is None:
+ w_bases = space.newtuple([])
w_classobj = space.gettypefor(W_ClassObject)
return space.call_function(w_classobj,
w_name, w_bases, w_dict)
diff --git a/pypy/module/cpyext/modsupport.py b/pypy/module/cpyext/modsupport.py
--- a/pypy/module/cpyext/modsupport.py
+++ b/pypy/module/cpyext/modsupport.py
@@ -10,6 +10,14 @@
from pypy.module.cpyext.state import State
from pypy.interpreter.error import oefmt
+@cpython_api([rffi.CCHARP], PyObject)
+def PyModule_New(space, name):
+ """
+ Return a new module object with the __name__ attribute set to name.
+ Only the module's __doc__ and __name__ attributes are filled in;
+ the caller is responsible for providing a __file__ attribute."""
+ return Module(space, space.newtext(rffi.charp2str(name)))
+
#@cpython_api([rffi.CCHARP], PyObject)
def PyImport_AddModule(space, name):
"""Return the module object corresponding to a module name. The name
argument
diff --git a/pypy/module/cpyext/state.py b/pypy/module/cpyext/state.py
--- a/pypy/module/cpyext/state.py
+++ b/pypy/module/cpyext/state.py
@@ -165,6 +165,7 @@
w_dict = w_mod.getdict(space)
w_copy = space.call_method(w_dict, 'copy')
self.extensions[path] = w_copy
+ return w_mod
def _rawrefcount_perform(space):
diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py
--- a/pypy/module/cpyext/stubs.py
+++ b/pypy/module/cpyext/stubs.py
@@ -1365,13 +1365,6 @@
"""
raise NotImplementedError
-@cpython_api([rffi.CCHARP], PyObject)
-def PyModule_New(space, name):
- """Return a new module object with the __name__ attribute set to name.
Only
- the module's __doc__ and __name__ attributes are filled in; the caller is
- responsible for providing a __file__ attribute."""
- raise NotImplementedError
-
@cpython_api([PyObject], rffi.CCHARP)
def PyModule_GetFilename(space, module):
"""Return the name of the file from which module was loaded using module's
diff --git a/pypy/module/cpyext/test/test_classobject.py
b/pypy/module/cpyext/test/test_classobject.py
--- a/pypy/module/cpyext/test/test_classobject.py
+++ b/pypy/module/cpyext/test/test_classobject.py
@@ -77,3 +77,15 @@
class C:
pass
assert module.get_classtype() is type(C)
+
+ def test_pyclass_new_no_bases(self):
+ module = self.import_extension('foo', [
+ ("new_foo", "METH_O",
+ """
+ return PyClass_New(NULL, PyDict_New(), args);
+ """)])
+ FooClass = module.new_foo("FooClass")
+ class Cls1:
+ pass
+ assert type(FooClass) is type(Cls1)
+ assert FooClass.__bases__ == Cls1.__bases__
diff --git a/pypy/module/cpyext/test/test_module.py
b/pypy/module/cpyext/test/test_module.py
--- a/pypy/module/cpyext/test/test_module.py
+++ b/pypy/module/cpyext/test/test_module.py
@@ -1,8 +1,15 @@
+from pypy.module.cpyext.modsupport import PyModule_New
from pypy.module.cpyext.test.test_api import BaseApiTest
from rpython.rtyper.lltypesystem import rffi
class TestModuleObject(BaseApiTest):
+ def test_module_new(self, space):
+ with rffi.scoped_str2charp('testname') as buf:
+ w_mod = PyModule_New(space, buf)
+ assert space.eq_w(space.getattr(w_mod, space.newtext('__name__')),
+ space.newtext('testname'))
+
def test_module_getname(self, space, api):
w_sys = space.wrap(space.sys)
p = api.PyModule_GetName(w_sys)
diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py
--- a/pypy/module/imp/importing.py
+++ b/pypy/module/imp/importing.py
@@ -616,7 +616,7 @@
from pypy.module.cpyext.api import load_extension_module
log_pyverbose(space, 1, "import %s # from %s\n" %
(modulename, filename))
- load_extension_module(space, filename, modulename)
+ return load_extension_module(space, filename, modulename)
# NB. cpyext.api.load_extension_module() can also delegate to _cffi_backend
@jit.dont_look_inside
@@ -680,8 +680,8 @@
pass
return w_mod
elif find_info.modtype == C_EXTENSION and has_so_extension(space):
- load_c_extension(space, find_info.filename,
space.text_w(w_modulename))
- return check_sys_modules(space, w_modulename)
+ return load_c_extension(space, find_info.filename,
+ space.text_w(w_modulename))
except OperationError:
w_mods = space.sys.get('modules')
space.call_method(w_mods, 'pop', w_modulename, space.w_None)
diff --git a/pypy/module/imp/interp_imp.py b/pypy/module/imp/interp_imp.py
--- a/pypy/module/imp/interp_imp.py
+++ b/pypy/module/imp/interp_imp.py
@@ -136,8 +136,8 @@
def load_dynamic(space, w_modulename, filename, w_file=None):
if not importing.has_so_extension(space):
raise oefmt(space.w_ImportError, "Not implemented")
- importing.load_c_extension(space, filename, space.text_w(w_modulename))
- return importing.check_sys_modules(space, w_modulename)
+ return importing.load_c_extension(space, filename,
+ space.text_w(w_modulename))
def new_module(space, w_name):
return Module(space, w_name, add_package=False)
diff --git a/pypy/module/thread/os_local.py b/pypy/module/thread/os_local.py
--- a/pypy/module/thread/os_local.py
+++ b/pypy/module/thread/os_local.py
@@ -1,6 +1,7 @@
import weakref
from rpython.rlib import jit
from pypy.interpreter.baseobjspace import W_Root
+from pypy.interpreter.error import oefmt
from pypy.interpreter.executioncontext import ExecutionContext
from pypy.interpreter.typedef import (TypeDef, interp2app, GetSetProperty,
descr_get_dict)
@@ -74,18 +75,20 @@
return w_dict
def descr_local__new__(space, w_subtype, __args__):
+ from pypy.objspace.std.typeobject import _precheck_for_new
+ w_subtype = _precheck_for_new(space, w_subtype)
+ if __args__.arguments_w or __args__.keywords:
+ w_parent_init, _ = space.lookup_in_type_where(w_subtype,
'__init__')
+ if w_parent_init is space.w_object:
+ raise oefmt(space.w_TypeError,
+ "Initialization arguments are not supported")
local = space.allocate_instance(Local, w_subtype)
Local.__init__(local, space, __args__)
return local
- def descr_local__init__(self, space):
- # No arguments allowed
- pass
-
Local.typedef = TypeDef("thread._local",
__doc__ = "Thread-local data",
__new__ = interp2app(Local.descr_local__new__.im_func),
- __init__ = interp2app(Local.descr_local__init__),
__dict__ = GetSetProperty(descr_get_dict, cls=Local),
)
diff --git a/pypy/module/thread/test/test_local.py
b/pypy/module/thread/test/test_local.py
--- a/pypy/module/thread/test/test_local.py
+++ b/pypy/module/thread/test/test_local.py
@@ -72,6 +72,19 @@
assert seen1 == [1, 2, 3, 4, 5]
assert tags == ['???']
+ def test_local_init2(self):
+ import thread
+
+ class A(object):
+ def __init__(self, n):
+ assert n == 42
+ self.n = n
+ class X(thread._local, A):
+ pass
+
+ x = X(42)
+ assert x.n == 42
+
def test_local_setdict(self):
import thread
x = thread._local()
diff --git a/pypy/module/zipimport/interp_zipimport.py
b/pypy/module/zipimport/interp_zipimport.py
--- a/pypy/module/zipimport/interp_zipimport.py
+++ b/pypy/module/zipimport/interp_zipimport.py
@@ -263,11 +263,18 @@
if compiled:
w_result = self.import_pyc_file(space, fullname, fname,
buf, pkgpath)
- if w_result is not None:
- return w_result
+ if w_result is None:
+ continue
else:
- return self.import_py_file(space, fullname, fname,
+ w_result = self.import_py_file(space, fullname, fname,
buf, pkgpath)
+ if space.sys.get_flag('verbose') >= 1:
+ w_stderr = space.sys.get('stderr')
+ message = "import %s # loaded from Zip %s%s%s\n" % (
+ fullname, self.filename, os.path.sep, fname)
+ space.call_method(w_stderr, "write",
+ space.newtext(message))
+ return w_result
except:
w_mods = space.sys.get('modules')
space.call_method(w_mods, 'pop', space.newtext(fullname),
space.w_None)
diff --git a/pypy/objspace/std/dictmultiobject.py
b/pypy/objspace/std/dictmultiobject.py
--- a/pypy/objspace/std/dictmultiobject.py
+++ b/pypy/objspace/std/dictmultiobject.py
@@ -1049,6 +1049,8 @@
else:
return d.pop(key, w_default)
elif self._never_equal_to(space.type(w_key)):
+ if w_default is not None:
+ return w_default
raise KeyError
else:
self.switch_to_object_strategy(w_dict)
diff --git a/pypy/objspace/std/test/test_dictmultiobject.py
b/pypy/objspace/std/test/test_dictmultiobject.py
--- a/pypy/objspace/std/test/test_dictmultiobject.py
+++ b/pypy/objspace/std/test/test_dictmultiobject.py
@@ -161,7 +161,7 @@
w_d.initialize_content([(w(1), wb("a")), (w(2), wb("b"))])
w_l = self.space.call_method(w_d, "keys")
assert sorted(self.space.listview_int(w_l)) == [1,2]
-
+
# make sure that .keys() calls newlist_bytes for string dicts
def not_allowed(*args):
assert False, 'should not be called'
@@ -174,7 +174,7 @@
# XXX: it would be nice if the test passed without monkeypatch.undo(),
# but we need space.newlist_unicode for it
- monkeypatch.undo()
+ monkeypatch.undo()
w_d = self.space.newdict()
w_d.initialize_content([(w(u"a"), w(1)), (w(u"b"), w(6))])
w_l = self.space.call_method(w_d, "keys")
@@ -223,6 +223,10 @@
assert len(dd) == 1
raises(KeyError, dd.pop, 33)
+ assert d.pop("abc", None) is None
+ raises(KeyError, d.pop, "abc")
+ assert len(d) == 2
+
def test_has_key(self):
d = {1: 2, 3: 4}
assert d.has_key(1)
@@ -1466,4 +1470,3 @@
fakespace = FakeSpace()
d = fakespace.newdict(module=True)
assert type(d.get_strategy()) is BytesDictStrategy
-
diff --git a/pypy/tool/release/repackage.sh b/pypy/tool/release/repackage.sh
--- a/pypy/tool/release/repackage.sh
+++ b/pypy/tool/release/repackage.sh
@@ -1,6 +1,6 @@
# Edit these appropriately before running this script
maj=5
-min=6
+min=7
rev=0
branchname=release-pypy2.7-5.x # ==OR== release-$maj.x # ==OR==
release-$maj.$min.x
tagname=release-pypy2.7-v$maj.$min.$rev # ==OR== release-$maj.$min
diff --git a/rpython/rlib/rthread.py b/rpython/rlib/rthread.py
--- a/rpython/rlib/rthread.py
+++ b/rpython/rlib/rthread.py
@@ -429,7 +429,11 @@
gc._trace_callback(callback, arg, p + offset)
llop.threadlocalref_release(lltype.Void)
_lambda_trace_tlref = lambda: _trace_tlref
- TRACETLREF = lltype.GcStruct('TRACETLREF')
+ # WAAAH obscurity: can't use a name that may be non-unique,
+ # otherwise the types compare equal, even though we call
+ # register_custom_trace_hook() to register different trace
+ # functions...
+ TRACETLREF = lltype.GcStruct('TRACETLREF%d' % unique_id)
_tracetlref_obj = lltype.malloc(TRACETLREF, immortal=True)
@staticmethod
diff --git a/rpython/rlib/rurandom.py b/rpython/rlib/rurandom.py
--- a/rpython/rlib/rurandom.py
+++ b/rpython/rlib/rurandom.py
@@ -99,8 +99,11 @@
eci = eci.merge(ExternalCompilationInfo(includes=['linux/random.h']))
class CConfig:
_compilation_info_ = eci
- GRND_NONBLOCK = rffi_platform.ConstantInteger('GRND_NONBLOCK')
+ GRND_NONBLOCK = rffi_platform.DefinedConstantInteger(
+ 'GRND_NONBLOCK')
globals().update(rffi_platform.configure(CConfig))
+ if GRND_NONBLOCK is None:
+ GRND_NONBLOCK = 0x0001 # from linux/random.h
# On Linux, use the syscall() function because the GNU libc doesn't
# expose the Linux getrandom() syscall yet.
diff --git a/rpython/rlib/test/test_rthread.py
b/rpython/rlib/test/test_rthread.py
--- a/rpython/rlib/test/test_rthread.py
+++ b/rpython/rlib/test/test_rthread.py
@@ -262,15 +262,23 @@
py.test.skip("no __thread support here")
class FooBar(object):
- pass
+ def __init__(self, a, b):
+ self.lst = [a, b]
t = ThreadLocalReference(FooBar)
+ t2 = ThreadLocalReference(FooBar)
def tset():
- x1 = FooBar()
+ x1 = FooBar(40, 2)
t.set(x1)
return weakref.ref(x1)
tset._dont_inline_ = True
+ def t2set():
+ x1 = FooBar(50, 3)
+ t2.set(x1)
+ return weakref.ref(x1)
+ t2set._dont_inline_ = True
+
class WrFromThread:
pass
wr_from_thread = WrFromThread()
@@ -279,22 +287,30 @@
config = objectmodel.fetch_translated_config()
assert t.automatic_keepalive(config) is True
wr = tset()
- import gc; gc.collect() # 'x1' should not be collected
- x2 = t.get()
+ wr2 = t2set()
+ import gc; gc.collect() # the two 'x1' should not be collected
+ x1 = t.get()
+ assert x1 is not None
+ assert wr() is not None
+ assert wr() is x1
+ assert x1.lst == [40, 2]
+ x2 = t2.get()
assert x2 is not None
- assert wr() is not None
- assert wr() is x2
- return wr
+ assert wr2() is not None
+ assert wr2() is x2
+ assert x2.lst == [50, 3]
+ return wr, wr2
def thread_entry_point():
- wr = f()
+ wr, wr2 = f()
wr_from_thread.wr = wr
+ wr_from_thread.wr2 = wr2
wr_from_thread.seen = True
def main():
wr_from_thread.seen = False
start_new_thread(thread_entry_point, ())
- wr1 = f()
+ wr1, wr2 = f()
count = 0
while True:
time.sleep(0.5)
@@ -302,10 +318,15 @@
break
count += 1
assert wr_from_thread.seen is True
- wr2 = wr_from_thread.wr
- import gc; gc.collect() # wr2() should be collected here
+ wr_other_1 = wr_from_thread.wr
+ wr_other_2 = wr_from_thread.wr2
+ import gc; gc.collect() # wr_other_*() should be collected
here
assert wr1() is not None # this thread, still running
- assert wr2() is None # other thread, not running any more
+ assert wr2() is not None # this thread, still running
+ assert wr_other_1() is None # other thread, not running any more
+ assert wr_other_2() is None # other thread, not running any more
+ assert wr1().lst == [40, 2]
+ assert wr2().lst == [50, 3]
return 42
extra_options = {'no__thread': no__thread, 'shared': True}
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit