aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatti Picus <matti.picus@gmail.com>2022-02-18 08:20:53 +0200
committerMatti Picus <matti.picus@gmail.com>2022-02-18 08:20:53 +0200
commit498b769a83bd3ddede27e69cea2831bbed3f3192 (patch)
treed2a79ad2f3861ae9ff03597d911e70edda1b0192
parentmake this the non-candidate release (diff)
parentupdate the release note (diff)
downloadpypy-release-pypy2.7-v7.3.8.tar.gz
pypy-release-pypy2.7-v7.3.8.tar.bz2
pypy-release-pypy2.7-v7.3.8.zip
-rw-r--r--.hgtags4
-rw-r--r--lib-python/2.7/test/test_ssl.py65
-rw-r--r--lib_pypy/_cffi_ssl/_stdssl/__init__.py4
-rw-r--r--pypy/doc/release-v7.3.8.rst42
-rw-r--r--pypy/objspace/std/setobject.py255
-rw-r--r--pypy/objspace/std/test/test_setobject.py10
-rw-r--r--pypy/tool/release/check_versions.py11
-rwxr-xr-xpypy/tool/release/repackage.sh21
-rw-r--r--pypy/tool/release/versions.json159
-rw-r--r--rpython/jit/metainterp/test/test_warmspot.py22
-rw-r--r--rpython/jit/metainterp/warmstate.py2
-rw-r--r--rpython/rlib/rfloat.py30
-rw-r--r--rpython/rlib/test/test_rfloat.py8
13 files changed, 460 insertions, 173 deletions
diff --git a/.hgtags b/.hgtags
index aa442b9a7d..4c89793d5e 100644
--- a/.hgtags
+++ b/.hgtags
@@ -133,3 +133,7 @@ cc3911ab8fcd509143c64012cc7067d75ab4b6ac release-pypy3.7-v7.3.6
0e322cb44401d19c73b3c3862bcd86bf56ff69ae release-pypy3.7-v7.3.8rc1
67f1b98040bad2f1241e4e1ebde6051a505f628a release-pypy3.8-v7.3.8rc1
307e102d7222131fee14073e8856df773627186c release-pypy3.9-v7.3.8rc1
+a7534a4d50852c8405687fc62112401cf8b11485 release-pypy2.7-v7.3.8rc2
+11d3d95ae917dba9ba375c3ad4e831ed5d97fb6b release-pypy3.7-v7.3.8rc2
+e093771497da708d5a1bacad367a0d515fde610b release-pypy3.8-v7.3.8rc2
+59025807f35a8a6b2fa7c033836b5949001a6c2a release-pypy3.9-v7.3.8rc2
diff --git a/lib-python/2.7/test/test_ssl.py b/lib-python/2.7/test/test_ssl.py
index 5bfeb8bbd8..57f50cc6ed 100644
--- a/lib-python/2.7/test/test_ssl.py
+++ b/lib-python/2.7/test/test_ssl.py
@@ -30,7 +30,23 @@ HOST = support.HOST
IS_LIBRESSL = ssl.OPENSSL_VERSION.startswith('LibreSSL')
IS_OPENSSL_1_1 = not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0)
IS_OPENSSL_3 = not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (3,)
-
+IS_LIBRESSL = ssl.OPENSSL_VERSION.startswith('LibreSSL')
+IS_OPENSSL_1_1_0 = not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0)
+IS_OPENSSL_1_1_1 = not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (1, 1, 1)
+IS_OPENSSL_3_0_0 = not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (3, 0, 0)
+
+PROTOCOL_TO_TLS_VERSION = {}
+for proto, ver in (
+ ("PROTOCOL_SSLv23", "PROTO_SSLv3"),
+ ("PROTOCOL_TLSv1", "PROTO_TLSv1"),
+ ("PROTOCOL_TLSv1_1", "PROTO_TLSv1_1"),
+):
+ try:
+ proto = getattr(ssl, proto)
+ ver = getattr(ssl.ver)
+ except AttributeError:
+ continue
+ PROTOCOL_TO_TLS_VERSION[proto] = ver
def data_file(*name):
return os.path.join(os.path.dirname(__file__), *name)
@@ -85,6 +101,34 @@ OP_SINGLE_DH_USE = getattr(ssl, "OP_SINGLE_DH_USE", 0)
OP_SINGLE_ECDH_USE = getattr(ssl, "OP_SINGLE_ECDH_USE", 0)
OP_CIPHER_SERVER_PREFERENCE = getattr(ssl, "OP_CIPHER_SERVER_PREFERENCE", 0)
OP_ENABLE_MIDDLEBOX_COMPAT = getattr(ssl, "OP_ENABLE_MIDDLEBOX_COMPAT", 0)
+OP_IGNORE_UNEXPECTED_EOF = getattr(ssl, "OP_IGNORE_UNEXPECTED_EOF", 0)
+
+# Ubuntu has patched OpenSSL and changed behavior of security level 2
+# see https://bugs.python.org/issue41561#msg389003
+def is_ubuntu():
+ try:
+ # Assume that any references of "ubuntu" implies Ubuntu-like distro
+ # The workaround is not required for 18.04, but doesn't hurt either.
+ with open("/etc/os-release") as f:
+ return "ubuntu" in f.read()
+ except OSError:
+ return False
+
+if is_ubuntu():
+ def seclevel_workaround(*ctxs):
+ """"Lower security level to '1' and allow all ciphers for TLS 1.0/1"""
+ for ctx in ctxs:
+ if (
+ hasattr(ctx, "minimum_version") and
+ ctx.minimum_version <= ssl._ssl.PROTO_TLSv1_1
+ ):
+ ctx.set_ciphers("@SECLEVEL=1:ALL")
+else:
+ def seclevel_workaround(*ctxs):
+ pass
+
+
+
def handle_error(prefix):
@@ -2136,16 +2180,29 @@ else:
server_context = ssl.SSLContext(server_protocol)
server_context.options |= server_options
+ min_version = PROTOCOL_TO_TLS_VERSION.get(client_protocol, None)
+ if (min_version is not None
+ # SSLContext.minimum_version is only available on recent OpenSSL
+ # (setter added in OpenSSL 1.1.0, getter added in OpenSSL 1.1.1)
+ and hasattr(server_context, 'minimum_version')
+ and server_protocol == ssl.PROTOCOL_TLS
+ and server_context.minimum_version > min_version):
+ # If OpenSSL configuration is strict and requires more recent TLS
+ # version, we have to change the minimum to test old TLS versions.
+ server_context.minimum_version = min_version
+
# NOTE: we must enable "ALL" ciphers on the client, otherwise an
# SSLv23 client will send an SSLv3 hello (rather than SSLv2)
# starting from OpenSSL 1.0.0 (see issue #8322).
- if client_context.protocol == ssl.PROTOCOL_SSLv23:
+ if client_context.protocol == ssl.PROTOCOL_TLS:
client_context.set_ciphers("ALL")
+ seclevel_workaround(server_context, client_context)
+
for ctx in (client_context, server_context):
ctx.verify_mode = certsreqs
- ctx.load_cert_chain(CERTFILE)
- ctx.load_verify_locations(CERTFILE)
+ ctx.load_cert_chain(SIGNED_CERTFILE)
+ ctx.load_verify_locations(SIGNING_CA)
try:
stats = server_params_test(client_context, server_context,
chatty=False, connectionchatty=False)
diff --git a/lib_pypy/_cffi_ssl/_stdssl/__init__.py b/lib_pypy/_cffi_ssl/_stdssl/__init__.py
index 400ae7700a..d83caef6b6 100644
--- a/lib_pypy/_cffi_ssl/_stdssl/__init__.py
+++ b/lib_pypy/_cffi_ssl/_stdssl/__init__.py
@@ -325,8 +325,8 @@ class _SSLSocket(object):
# bpo43522 and OpenSSL < 1.1.1l: copy hostflags manually
if OPENSSL_VERSION_INFO < (1, 1, 1, 12): # 12 == 'l'
- params = lib.SSL_CTX_get0_param(ctx);
- lib.X509_VERIFY_PARAM_set_hostflags(params, ctx.hostflags);
+ params = lib.SSL_CTX_get0_param(ctx)
+ lib.X509_VERIFY_PARAM_set_hostflags(params, sslctx.hostflags);
self._app_data_handle = ffi.new_handle(self)
lib.SSL_set_app_data(ssl, ffi.cast("char*", self._app_data_handle))
diff --git a/pypy/doc/release-v7.3.8.rst b/pypy/doc/release-v7.3.8.rst
index 332eb8e99b..862e723cb4 100644
--- a/pypy/doc/release-v7.3.8.rst
+++ b/pypy/doc/release-v7.3.8.rst
@@ -3,7 +3,7 @@ PyPy v7.3.8: release of python 2.7, 3.7, 3.8, and 3.9-beta
==========================================================
..
- Changelog up to commit 0360402c9455
+ Changelog up to commit 0db7d7a9cbf1
.. note::
This is a pre-release announcement. When the release actually happens, it
@@ -31,8 +31,7 @@ wish to share. The release includes four different interpreters:
Python 3.9, including the stdlib for CPython 3.9.10. As this is our first
release of this interpreter, we relate to this as "beta" quality. We
welcome testing of this version, if you discover incompatibilities, please
- report them so we can gain confidence in the version. There is still a known
- `speed regression`_ around ``**kwargs`` handling in 3.9.
+ report them so we can gain confidence in the version.
The interpreters are based on much the same codebase, thus the multiple
release. This is a micro release, all APIs are compatible with the other 7.3
@@ -101,20 +100,30 @@ This PyPy release supports:
* **x86** machines on most common operating systems
(Linux 32/64 bits, Mac OS X 64 bits, Windows 64 bits, OpenBSD, FreeBSD)
- * 64-bit **ARM** machines running Linux.
-
- * big- and little-endian variants of **PPC64** running Linux,
+ * 64-bit **ARM** machines running Linux. A shoutout to Huawei for sponsoring
+ the VM running the tests.
* **s390x** running Linux
-PyPy support Windows 32-bit and ARM 32 bit processors, but does not
-release binaries. Please reach out to us if you wish to sponsor releases for
-those platforms. It also supports s390x, and big and little-endian variants of
-PPC64 running Linux.
+ * big- and little-endian variants of **PPC64** running Linux,
+
+PyPy support Windows 32-bit, PPC64 big- and little-endian, and ARM 32 bit, but
+does not release binaries. Please reach out to us if you wish to sponsor
+releases for those platforms.
.. _`PyPy and CPython 3.7.4`: https://speed.pypy.org
.. _`dynamic languages`: https://rpython.readthedocs.io/en/latest/examples.html
+Known Issues with PyPy3.9
+=========================
+- There is still a known `speed regression`_ around ``**kwargs`` handling
+- We slightly modified the concurrent future's ``ProcessExcecutorPool`` to
+ start all the worker processes when the first task is recieved (like on
+ Python3.8) to avoid an apparent race condition when using ``fork`` and
+ threads (issue 3650_).
+- Some of the code trace reporting with ``pypy -m trace --trace`` is slightly
+ off. See issues 3673_ and 3674_.
+
Changelog
=========
@@ -129,6 +138,8 @@ Bugfixes shared across versions
- Avoid using ``epoll_event`` directly from RPython since it is a ``packed struct``
- Clean up some compilation warnings around `const char *`` conversions to
``char *``
+- Make sure that frozensets cannot be mutated by using methods from set (issue
+ 3676_)
Speedups and enhancements shared across versions
------------------------------------------------
@@ -147,6 +158,10 @@ Speedups and enhancements shared across versions
- Prepare ``_ssl`` for OpenSSL3
- Improve ``x << y`` where ``x`` and ``y`` are ints but the results doesn't fit
into a machine word: don't convert ``y`` to ``rbigint`` and back to int
+- Avoid updating counter when using `--jit off`.
+- Speed up ``str`` -> ``float`` conversion for the fast path (ascii, no ``'_'``, no
+ ``INF``, no leading or trailing whitespace). PyPy with `--jit off`` is now
+ faster than CPython for this fastpath (issue 3682_).
C-API (cpyext) and C-extensions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -245,6 +260,7 @@ Python 3.8+ bugfixes
stdlib test failures
- Update bundled ``setuptools`` to ``58.1.0`` to get the fix for the new PyPy
layout
+- Fix ``multiprocessing.sharedmemory`` on windows (issue 3678_).
Python 3.8+ speedups and enhancements
-------------------------------------
@@ -291,8 +307,14 @@ Python 3.8 C-API
.. _3644: https://foss.heptapod.net/pypy/pypy/-/issues/3644
.. _3642: https://foss.heptapod.net/pypy/pypy/-/issues/3642
.. _3652: https://foss.heptapod.net/pypy/pypy/-/issues/3652
+.. _3650: https://foss.heptapod.net/pypy/pypy/-/issues/3650
.. _3656: https://foss.heptapod.net/pypy/pypy/-/issues/3656
.. _3661: https://foss.heptapod.net/pypy/pypy/-/issues/3661
+.. _3673: https://foss.heptapod.net/pypy/pypy/-/issues/3673
+.. _3674: https://foss.heptapod.net/pypy/pypy/-/issues/3674
+.. _3676: https://foss.heptapod.net/pypy/pypy/-/issues/3676
+.. _3678: https://foss.heptapod.net/pypy/pypy/-/issues/3678
+.. _3682: https://foss.heptapod.net/pypy/pypy/-/issues/3682
.. _bpo35883: https://bugs.python.org/issue35883
.. _bpo44954: https://bugs.python.org/issue44954
.. _bpo40780: https://bugs.python.org/issue40780
diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py
index 6fb461a734..6b73667ded 100644
--- a/pypy/objspace/std/setobject.py
+++ b/pypy/objspace/std/setobject.py
@@ -20,7 +20,6 @@ UNROLL_CUTOFF = 5
class W_BaseSetObject(W_Root):
typedef = None
- exact_class_applevel_name = 'set-or-frozenset'
def __init__(self, space, w_iterable=None):
"""Initialize the set by taking ownership of 'setdata'."""
@@ -279,30 +278,6 @@ class W_BaseSetObject(W_Root):
return self.symmetric_difference(w_other)
descr_rxor = descr_xor # symmetric
- def descr_inplace_sub(self, space, w_other):
- if not isinstance(w_other, W_BaseSetObject):
- return space.w_NotImplemented
- self.difference_update(w_other)
- return self
-
- def descr_inplace_and(self, space, w_other):
- if not isinstance(w_other, W_BaseSetObject):
- return space.w_NotImplemented
- self.intersect_update(w_other)
- return self
-
- def descr_inplace_or(self, space, w_other):
- if not isinstance(w_other, W_BaseSetObject):
- return space.w_NotImplemented
- self.update(w_other)
- return self
-
- def descr_inplace_xor(self, space, w_other):
- if not isinstance(w_other, W_BaseSetObject):
- return space.w_NotImplemented
- self.descr_symmetric_difference_update(space, w_other)
- return self
-
def descr_copy(self, space):
"""Return a shallow copy of a set."""
if type(self) is W_FrozensetObject:
@@ -420,16 +395,6 @@ class W_BaseSetObject(W_Root):
return space.w_False
return space.w_True
- def descr_add(self, space, w_other):
- """Add an element to a set.
-
- This has no effect if the element is already present."""
- self.add(w_other)
-
- def descr_clear(self, space):
- """Remove all elements from this set."""
- self.clear()
-
@gateway.unwrap_spec(others_w='args_w')
def descr_difference_update(self, space, others_w):
"""Update the set, removing elements found in others."""
@@ -440,6 +405,65 @@ class W_BaseSetObject(W_Root):
w_other_as_set = self._newobj(space, w_other)
self.difference_update(w_other_as_set)
+
+
+class W_SetObject(W_BaseSetObject):
+
+ #overridden here so the error is reported correctly
+ def __init__(self, space, w_iterable=None):
+ """Initialize the set by taking ownership of 'setdata'."""
+ W_BaseSetObject.__init__(self, space, w_iterable)
+
+ def _newobj(self, space, w_iterable):
+ """Make a new set by taking ownership of 'w_iterable'."""
+ if type(self) is W_SetObject:
+ return W_SetObject(space, w_iterable)
+ w_type = space.type(self)
+ w_obj = space.allocate_instance(W_SetObject, w_type)
+ W_SetObject.__init__(w_obj, space, w_iterable)
+ return w_obj
+
+ @staticmethod
+ def descr_new(space, w_settype, __args__):
+ w_obj = space.allocate_instance(W_SetObject, w_settype)
+ W_SetObject.__init__(w_obj, space)
+ return w_obj
+
+ def descr_inplace_sub(self, space, w_other):
+ if not isinstance(w_other, W_BaseSetObject):
+ return space.w_NotImplemented
+ self.difference_update(w_other)
+ return self
+
+ def descr_inplace_and(self, space, w_other):
+ if not isinstance(w_other, W_BaseSetObject):
+ return space.w_NotImplemented
+ self.intersect_update(w_other)
+ return self
+
+ def descr_inplace_or(self, space, w_other):
+ if not isinstance(w_other, W_BaseSetObject):
+ return space.w_NotImplemented
+ self.update(w_other)
+ return self
+
+ def descr_inplace_xor(self, space, w_other):
+ if not isinstance(w_other, W_BaseSetObject):
+ return space.w_NotImplemented
+ self.descr_symmetric_difference_update(space, w_other)
+ return self
+
+
+ def descr_add(self, space, w_other):
+ """Add an element to a set.
+
+ This has no effect if the element is already present."""
+ self.add(w_other)
+
+ def descr_clear(self, space):
+ """Remove all elements from this set."""
+ self.clear()
+
def _discard_from_set(self, space, w_item):
"""
Discard an element from a set, with automatic conversion to
@@ -507,87 +531,64 @@ class W_BaseSetObject(W_Root):
else:
_update_from_iterable(space, self, w_other)
-
-class W_SetObject(W_BaseSetObject):
-
- #overridden here so the error is reported correctly
- def __init__(self, space, w_iterable=None):
- """Initialize the set by taking ownership of 'setdata'."""
- W_BaseSetObject.__init__(self, space, w_iterable)
-
- def _newobj(self, space, w_iterable):
- """Make a new set by taking ownership of 'w_iterable'."""
- if type(self) is W_SetObject:
- return W_SetObject(space, w_iterable)
- w_type = space.type(self)
- w_obj = space.allocate_instance(W_SetObject, w_type)
- W_SetObject.__init__(w_obj, space, w_iterable)
- return w_obj
-
- @staticmethod
- def descr_new(space, w_settype, __args__):
- w_obj = space.allocate_instance(W_SetObject, w_settype)
- W_SetObject.__init__(w_obj, space)
- return w_obj
-
W_SetObject.typedef = TypeDef("set",
__doc__ = """set(iterable) --> set object
Build an unordered collection.""",
__new__ = gateway.interp2app(W_SetObject.descr_new),
__init__ = gateway.interp2app(W_SetObject.descr_init),
- __repr__ = gateway.interp2app(W_BaseSetObject.descr_repr),
+ __repr__ = gateway.interp2app(W_SetObject.descr_repr),
__hash__ = None,
- __cmp__ = gateway.interp2app(W_BaseSetObject.descr_cmp),
+ __cmp__ = gateway.interp2app(W_SetObject.descr_cmp),
# comparison operators
- __eq__ = gateway.interp2app(W_BaseSetObject.descr_eq),
- __ne__ = gateway.interp2app(W_BaseSetObject.descr_ne),
- __lt__ = gateway.interp2app(W_BaseSetObject.descr_lt),
- __le__ = gateway.interp2app(W_BaseSetObject.descr_le),
- __gt__ = gateway.interp2app(W_BaseSetObject.descr_gt),
- __ge__ = gateway.interp2app(W_BaseSetObject.descr_ge),
+ __eq__ = gateway.interp2app(W_SetObject.descr_eq),
+ __ne__ = gateway.interp2app(W_SetObject.descr_ne),
+ __lt__ = gateway.interp2app(W_SetObject.descr_lt),
+ __le__ = gateway.interp2app(W_SetObject.descr_le),
+ __gt__ = gateway.interp2app(W_SetObject.descr_gt),
+ __ge__ = gateway.interp2app(W_SetObject.descr_ge),
# non-mutating operators
- __len__ = gateway.interp2app(W_BaseSetObject.descr_len),
- __iter__ = gateway.interp2app(W_BaseSetObject.descr_iter),
- __contains__ = gateway.interp2app(W_BaseSetObject.descr_contains),
- __sub__ = gateway.interp2app(W_BaseSetObject.descr_sub),
- __rsub__ = gateway.interp2app(W_BaseSetObject.descr_rsub),
- __and__ = gateway.interp2app(W_BaseSetObject.descr_and),
- __rand__ = gateway.interp2app(W_BaseSetObject.descr_rand),
- __or__ = gateway.interp2app(W_BaseSetObject.descr_or),
- __ror__ = gateway.interp2app(W_BaseSetObject.descr_ror),
- __xor__ = gateway.interp2app(W_BaseSetObject.descr_xor),
- __rxor__ = gateway.interp2app(W_BaseSetObject.descr_rxor),
+ __len__ = gateway.interp2app(W_SetObject.descr_len),
+ __iter__ = gateway.interp2app(W_SetObject.descr_iter),
+ __contains__ = gateway.interp2app(W_SetObject.descr_contains),
+ __sub__ = gateway.interp2app(W_SetObject.descr_sub),
+ __rsub__ = gateway.interp2app(W_SetObject.descr_rsub),
+ __and__ = gateway.interp2app(W_SetObject.descr_and),
+ __rand__ = gateway.interp2app(W_SetObject.descr_rand),
+ __or__ = gateway.interp2app(W_SetObject.descr_or),
+ __ror__ = gateway.interp2app(W_SetObject.descr_ror),
+ __xor__ = gateway.interp2app(W_SetObject.descr_xor),
+ __rxor__ = gateway.interp2app(W_SetObject.descr_rxor),
# mutating operators
- __isub__ = gateway.interp2app(W_BaseSetObject.descr_inplace_sub),
- __iand__ = gateway.interp2app(W_BaseSetObject.descr_inplace_and),
- __ior__ = gateway.interp2app(W_BaseSetObject.descr_inplace_or),
- __ixor__ = gateway.interp2app(W_BaseSetObject.descr_inplace_xor),
+ __isub__ = gateway.interp2app(W_SetObject.descr_inplace_sub),
+ __iand__ = gateway.interp2app(W_SetObject.descr_inplace_and),
+ __ior__ = gateway.interp2app(W_SetObject.descr_inplace_or),
+ __ixor__ = gateway.interp2app(W_SetObject.descr_inplace_xor),
# non-mutating methods
- __reduce__ = gateway.interp2app(W_BaseSetObject.descr_reduce),
- copy = gateway.interp2app(W_BaseSetObject.descr_copy),
- difference = gateway.interp2app(W_BaseSetObject.descr_difference),
- intersection = gateway.interp2app(W_BaseSetObject.descr_intersection),
- issubset = gateway.interp2app(W_BaseSetObject.descr_issubset),
- issuperset = gateway.interp2app(W_BaseSetObject.descr_issuperset),
- symmetric_difference = gateway.interp2app(W_BaseSetObject.descr_symmetric_difference),
- union = gateway.interp2app(W_BaseSetObject.descr_union),
- isdisjoint = gateway.interp2app(W_BaseSetObject.descr_isdisjoint),
+ __reduce__ = gateway.interp2app(W_SetObject.descr_reduce),
+ copy = gateway.interp2app(W_SetObject.descr_copy),
+ difference = gateway.interp2app(W_SetObject.descr_difference),
+ intersection = gateway.interp2app(W_SetObject.descr_intersection),
+ issubset = gateway.interp2app(W_SetObject.descr_issubset),
+ issuperset = gateway.interp2app(W_SetObject.descr_issuperset),
+ symmetric_difference = gateway.interp2app(W_SetObject.descr_symmetric_difference),
+ union = gateway.interp2app(W_SetObject.descr_union),
+ isdisjoint = gateway.interp2app(W_SetObject.descr_isdisjoint),
# mutating methods
- add = gateway.interp2app(W_BaseSetObject.descr_add),
- clear = gateway.interp2app(W_BaseSetObject.descr_clear),
- difference_update = gateway.interp2app(W_BaseSetObject.descr_difference_update),
- discard = gateway.interp2app(W_BaseSetObject.descr_discard),
- intersection_update = gateway.interp2app(W_BaseSetObject.descr_intersection_update),
- pop = gateway.interp2app(W_BaseSetObject.descr_pop),
- remove = gateway.interp2app(W_BaseSetObject.descr_remove),
- symmetric_difference_update = gateway.interp2app(W_BaseSetObject.descr_symmetric_difference_update),
- update = gateway.interp2app(W_BaseSetObject.descr_update)
+ add = gateway.interp2app(W_SetObject.descr_add),
+ clear = gateway.interp2app(W_SetObject.descr_clear),
+ difference_update = gateway.interp2app(W_SetObject.descr_difference_update),
+ discard = gateway.interp2app(W_SetObject.descr_discard),
+ intersection_update = gateway.interp2app(W_SetObject.descr_intersection_update),
+ pop = gateway.interp2app(W_SetObject.descr_pop),
+ remove = gateway.interp2app(W_SetObject.descr_remove),
+ symmetric_difference_update = gateway.interp2app(W_SetObject.descr_symmetric_difference_update),
+ update = gateway.interp2app(W_SetObject.descr_update)
)
set_typedef = W_SetObject.typedef
@@ -668,41 +669,41 @@ W_FrozensetObject.typedef = TypeDef("frozenset",
Build an immutable unordered collection.""",
__new__ = gateway.interp2app(W_FrozensetObject.descr_new2),
- __repr__ = gateway.interp2app(W_BaseSetObject.descr_repr),
+ __repr__ = gateway.interp2app(W_FrozensetObject.descr_repr),
__hash__ = gateway.interp2app(W_FrozensetObject.descr_hash),
- __cmp__ = gateway.interp2app(W_BaseSetObject.descr_cmp),
+ __cmp__ = gateway.interp2app(W_FrozensetObject.descr_cmp),
# comparison operators
- __eq__ = gateway.interp2app(W_BaseSetObject.descr_eq),
- __ne__ = gateway.interp2app(W_BaseSetObject.descr_ne),
- __lt__ = gateway.interp2app(W_BaseSetObject.descr_lt),
- __le__ = gateway.interp2app(W_BaseSetObject.descr_le),
- __gt__ = gateway.interp2app(W_BaseSetObject.descr_gt),
- __ge__ = gateway.interp2app(W_BaseSetObject.descr_ge),
+ __eq__ = gateway.interp2app(W_FrozensetObject.descr_eq),
+ __ne__ = gateway.interp2app(W_FrozensetObject.descr_ne),
+ __lt__ = gateway.interp2app(W_FrozensetObject.descr_lt),
+ __le__ = gateway.interp2app(W_FrozensetObject.descr_le),
+ __gt__ = gateway.interp2app(W_FrozensetObject.descr_gt),
+ __ge__ = gateway.interp2app(W_FrozensetObject.descr_ge),
# non-mutating operators
- __len__ = gateway.interp2app(W_BaseSetObject.descr_len),
- __iter__ = gateway.interp2app(W_BaseSetObject.descr_iter),
- __contains__ = gateway.interp2app(W_BaseSetObject.descr_contains),
- __sub__ = gateway.interp2app(W_BaseSetObject.descr_sub),
- __rsub__ = gateway.interp2app(W_BaseSetObject.descr_rsub),
- __and__ = gateway.interp2app(W_BaseSetObject.descr_and),
- __rand__ = gateway.interp2app(W_BaseSetObject.descr_rand),
- __or__ = gateway.interp2app(W_BaseSetObject.descr_or),
- __ror__ = gateway.interp2app(W_BaseSetObject.descr_ror),
- __xor__ = gateway.interp2app(W_BaseSetObject.descr_xor),
- __rxor__ = gateway.interp2app(W_BaseSetObject.descr_rxor),
+ __len__ = gateway.interp2app(W_FrozensetObject.descr_len),
+ __iter__ = gateway.interp2app(W_FrozensetObject.descr_iter),
+ __contains__ = gateway.interp2app(W_FrozensetObject.descr_contains),
+ __sub__ = gateway.interp2app(W_FrozensetObject.descr_sub),
+ __rsub__ = gateway.interp2app(W_FrozensetObject.descr_rsub),
+ __and__ = gateway.interp2app(W_FrozensetObject.descr_and),
+ __rand__ = gateway.interp2app(W_FrozensetObject.descr_rand),
+ __or__ = gateway.interp2app(W_FrozensetObject.descr_or),
+ __ror__ = gateway.interp2app(W_FrozensetObject.descr_ror),
+ __xor__ = gateway.interp2app(W_FrozensetObject.descr_xor),
+ __rxor__ = gateway.interp2app(W_FrozensetObject.descr_rxor),
# non-mutating methods
- __reduce__ = gateway.interp2app(W_BaseSetObject.descr_reduce),
- copy = gateway.interp2app(W_BaseSetObject.descr_copy),
- difference = gateway.interp2app(W_BaseSetObject.descr_difference),
- intersection = gateway.interp2app(W_BaseSetObject.descr_intersection),
- issubset = gateway.interp2app(W_BaseSetObject.descr_issubset),
- issuperset = gateway.interp2app(W_BaseSetObject.descr_issuperset),
- symmetric_difference = gateway.interp2app(W_BaseSetObject.descr_symmetric_difference),
- union = gateway.interp2app(W_BaseSetObject.descr_union),
- isdisjoint = gateway.interp2app(W_BaseSetObject.descr_isdisjoint)
+ __reduce__ = gateway.interp2app(W_FrozensetObject.descr_reduce),
+ copy = gateway.interp2app(W_FrozensetObject.descr_copy),
+ difference = gateway.interp2app(W_FrozensetObject.descr_difference),
+ intersection = gateway.interp2app(W_FrozensetObject.descr_intersection),
+ issubset = gateway.interp2app(W_FrozensetObject.descr_issubset),
+ issuperset = gateway.interp2app(W_FrozensetObject.descr_issuperset),
+ symmetric_difference = gateway.interp2app(W_FrozensetObject.descr_symmetric_difference),
+ union = gateway.interp2app(W_FrozensetObject.descr_union),
+ isdisjoint = gateway.interp2app(W_FrozensetObject.descr_isdisjoint)
)
frozenset_typedef = W_FrozensetObject.typedef
diff --git a/pypy/objspace/std/test/test_setobject.py b/pypy/objspace/std/test/test_setobject.py
index a68ffe24f5..e4e3c74a1c 100644
--- a/pypy/objspace/std/test/test_setobject.py
+++ b/pypy/objspace/std/test/test_setobject.py
@@ -1085,4 +1085,12 @@ class AppTestAppSetTest:
assert "frozenset" in str(e.value)
if hasattr(frozenset.copy, 'im_func'):
e = raises(TypeError, frozenset.copy.im_func, 42)
- assert "'set-or-frozenset'" in str(e.value)
+ assert "'frozenset' object expected, got 'int' instead" in str(e.value)
+ if hasattr(set.copy, 'im_func'):
+ e = raises(TypeError, set.copy.im_func, 42)
+ assert "'set' object expected, got 'int' instead" in str(e.value)
+
+ def test_cant_mutate_frozenset_via_set(self):
+ x = frozenset()
+ raises(TypeError, set.add.im_func, x, 1)
+ raises(TypeError, set.__ior__.im_func, x, set([2]))
diff --git a/pypy/tool/release/check_versions.py b/pypy/tool/release/check_versions.py
index 29f39433ea..7be8bd6fee 100644
--- a/pypy/tool/release/check_versions.py
+++ b/pypy/tool/release/check_versions.py
@@ -33,6 +33,9 @@ def assert_in(a, b):
pypy_versions = {
+ '7.3.8rc2': {'python_version': ['3.9.10', '3.8.12', '3.7.12', '2.7.18'],
+ 'date': '2022-02-11',
+ },
'7.3.8rc1': {'python_version': ['3.9.10', '3.8.12', '3.7.12', '2.7.18'],
'date': '2022-01-26',
},
@@ -118,6 +121,8 @@ arch_map={('aarch64', 'linux'): 'aarch64',
def check_versions(data, url, verbose=0):
for d in data:
+ if verbose > 0:
+ print(f"checking {d['pypy_version']} {d['python_version']}")
assert_in(d['pypy_version'], pypy_versions)
v = pypy_versions[d['pypy_version']]
assert_in(d['python_version'], v['python_version'])
@@ -139,7 +144,7 @@ def check_versions(data, url, verbose=0):
for f in d['files']:
download_url = f['download_url']
if verbose > 0:
- print(f'checking {download_url}')
+ print(f' checking {download_url}', end='')
if 'rc' not in d['pypy_version']:
assert_in(f['filename'], download_url)
assert_in(d['pypy_version'], download_url)
@@ -161,6 +166,10 @@ def check_versions(data, url, verbose=0):
except error.HTTPError as e:
raise ValueError(f"could not open {f['download_url']}") from None
assert_equal(r.getcode(), 200)
+ if verbose > 0:
+ print(f' ok')
+ if verbose > 0:
+ print(f"{d['pypy_version']} {d['python_version']} ok")
if __name__ == '__main__':
if len(sys.argv) > 1:
diff --git a/pypy/tool/release/repackage.sh b/pypy/tool/release/repackage.sh
index 7d6d9c3d7d..3bd34a0c9e 100755
--- a/pypy/tool/release/repackage.sh
+++ b/pypy/tool/release/repackage.sh
@@ -2,11 +2,11 @@
# Edit these appropriately before running this script
pmaj=3 # python main version: 2 or 3
-pmin=8 # python minor version
+pmin=9 # python minor version
maj=7
min=3
rev=8
-rc=rc1 # comment this line for actual release
+rc=rc2 # comment this line for actual release
function maybe_exit {
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
@@ -45,10 +45,17 @@ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
fi
fi
+if [ -v rc ]
+then
+ wanted="\"$maj.$min.$rev${rc/rc/-candidate}\""
+else
+ wanted="\"$maj.$min.$rev\""
+fi
+
function repackage_builds {
# Download latest builds from the buildmaster, rename the top
# level directory, and repackage ready to be uploaded
- for plat in linux linux64 osx64 # s390x aarch64 linux-armhf-raspbian linux-armel
+ for plat in linux linux64 osx64 s390x # aarch64 linux-armhf-raspbian linux-armel
do
echo downloading package for $plat
if wget -q --show-progress http://buildbot.pypy.org/nightly/$branchname/pypy-c-jit-latest-$plat.tar.bz2
@@ -77,10 +84,10 @@ function repackage_builds {
else
actual_ver=$(grep PYPY_VERSION pypy-c-jit-*-$plat/include/pypy$pmaj.$pmin/patchlevel.h |cut -f3 -d' ')
fi
- if [ $actual_ver != "\"$maj.$min.$rev\"" ]
+ if [ $actual_ver != $wanted ]
then
echo xxxxxxxxxxxxxxxxxxxxxx
- echo version mismatch, expected "\"$maj.$min.$rev\"", got $actual_ver for $plat
+ echo version mismatch, expected $wanted, got $actual_ver for $plat
echo xxxxxxxxxxxxxxxxxxxxxx
exit -1
rm -rf pypy-c-jit-*-$plat
@@ -110,10 +117,10 @@ function repackage_builds {
unzip -q pypy-c-jit-latest-$plat.zip
rm pypy-c-jit-latest-$plat.zip
actual_ver=$(grep PYPY_VERSION pypy-c-jit-*-$plat/include/patchlevel.h |cut -f3 -d' ')
- if [ $actual_ver != "\"$maj.$min.$rev\"" ]
+ if [ $actual_ver != $wanted ]
then
echo xxxxxxxxxxxxxxxxxxxxxx
- echo version mismatch, expected "\"$maj.$min.$rev\"", got $actual_ver for $plat
+ echo version mismatch, expected $wanted, got $actual_ver for $plat
echo xxxxxxxxxxxxxxxxxxxxxx
rm -rf pypy-c-jit-*-$plat
continue
diff --git a/pypy/tool/release/versions.json b/pypy/tool/release/versions.json
index b77e667561..23886f8bed 100644
--- a/pypy/tool/release/versions.json
+++ b/pypy/tool/release/versions.json
@@ -1,5 +1,158 @@
[
{
+ "pypy_version": "7.3.8rc2",
+ "python_version": "3.9.10",
+ "stable": false,
+ "latest_pypy": false,
+ "date": "2022-02-11",
+ "files": [
+ {
+ "filename": "pypy3.9-v7.3.8rc2-linux32.tar.bz2",
+ "arch": "i686",
+ "platform": "linux",
+ "download_url": "https://downloads.python.org/pypy/pypy3.9-v7.3.8rc2-linux32.tar.bz2"
+ },
+ {
+ "filename": "pypy3.9-v7.3.8rc2-linux64.tar.bz2",
+ "arch": "x64",
+ "platform": "linux",
+ "download_url": "https://downloads.python.org/pypy/pypy3.9-v7.3.8rc2-linux64.tar.bz2"
+ },
+ {
+ "filename": "pypy3.9-v7.3.8rc2-osx64.tar.bz2",
+ "arch": "x64",
+ "platform": "darwin",
+ "download_url": "https://downloads.python.org/pypy/pypy3.9-v7.3.8rc2-osx64.tar.bz2"
+ },
+ {
+ "filename": "pypy3.9-v7.3.8rc2-s390x.tar.bz2",
+ "arch": "s390x",
+ "platform": "linux",
+ "download_url": "https://downloads.python.org/pypy/pypy3.9-v7.3.8rc2-s390x.tar.bz2"
+ },
+ {
+ "filename": "pypy3.9-v7.3.8rc2-win64.zip",
+ "arch": "x64",
+ "platform": "win64",
+ "download_url": "https://downloads.python.org/pypy/pypy3.9-v7.3.8rc2-win64.zip"
+ }
+ ]
+ }, {
+ "pypy_version": "7.3.8rc2",
+ "python_version": "3.8.12",
+ "stable": false,
+ "latest_pypy": false,
+ "date": "2022-02-11",
+ "files": [
+ {
+ "filename": "pypy3.8-v7.3.8rc2-linux32.tar.bz2",
+ "arch": "i686",
+ "platform": "linux",
+ "download_url": "https://downloads.python.org/pypy/pypy3.8-v7.3.8rc2-linux32.tar.bz2"
+ },
+ {
+ "filename": "pypy3.8-v7.3.8rc2-linux64.tar.bz2",
+ "arch": "x64",
+ "platform": "linux",
+ "download_url": "https://downloads.python.org/pypy/pypy3.8-v7.3.8rc2-linux64.tar.bz2"
+ },
+ {
+ "filename": "pypy3.8-v7.3.8rc2-osx64.tar.bz2",
+ "arch": "x64",
+ "platform": "darwin",
+ "download_url": "https://downloads.python.org/pypy/pypy3.8-v7.3.8rc2-osx64.tar.bz2"
+ },
+ {
+ "filename": "pypy3.8-v7.3.8rc2-s390x.tar.bz2",
+ "arch": "s390x",
+ "platform": "linux",
+ "download_url": "https://downloads.python.org/pypy/pypy3.8-v7.3.8rc2-s390x.tar.bz2"
+ },
+ {
+ "filename": "pypy3.8-v7.3.8rc2-win64.zip",
+ "arch": "x64",
+ "platform": "win64",
+ "download_url": "https://downloads.python.org/pypy/pypy3.8-v7.3.8rc2-win64.zip"
+ }
+ ]
+ },{
+ "pypy_version": "7.3.8rc2",
+ "python_version": "3.7.12",
+ "stable": false,
+ "latest_pypy": false,
+ "date": "2022-02-11",
+ "files": [
+ {
+ "filename": "pypy3.7-v7.3.8rc2-linux32.tar.bz2",
+ "arch": "i686",
+ "platform": "linux",
+ "download_url": "https://downloads.python.org/pypy/pypy3.7-v7.3.8rc2-linux32.tar.bz2"
+ },
+ {
+ "filename": "pypy3.7-v7.3.8rc2-linux64.tar.bz2",
+ "arch": "x64",
+ "platform": "linux",
+ "download_url": "https://downloads.python.org/pypy/pypy3.7-v7.3.8rc2-linux64.tar.bz2"
+ },
+ {
+ "filename": "pypy3.7-v7.3.8rc2-osx64.tar.bz2",
+ "arch": "x64",
+ "platform": "darwin",
+ "download_url": "https://downloads.python.org/pypy/pypy3.7-v7.3.8rc2-osx64.tar.bz2"
+ },
+ {
+ "filename": "pypy3.7-v7.3.8rc2-s390x.tar.bz2",
+ "arch": "s390x",
+ "platform": "linux",
+ "download_url": "https://downloads.python.org/pypy/pypy3.7-v7.3.8rc2-s390x.tar.bz2"
+ },
+ {
+ "filename": "pypy3.7-v7.3.8rc2-win64.zip",
+ "arch": "x64",
+ "platform": "win64",
+ "download_url": "https://downloads.python.org/pypy/pypy3.7-v7.3.8rc2-win64.zip"
+ }
+ ]
+ },{
+ "pypy_version": "7.3.8rc2",
+ "python_version": "2.7.18",
+ "stable": false,
+ "latest_pypy": false,
+ "date": "2022-02-11",
+ "files": [
+ {
+ "filename": "pypy2.7-v7.3.8rc2-linux32.tar.bz2",
+ "arch": "i686",
+ "platform": "linux",
+ "download_url": "https://downloads.python.org/pypy/pypy2.7-v7.3.8rc2-linux32.tar.bz2"
+ },
+ {
+ "filename": "pypy2.7-v7.3.8rc2-linux64.tar.bz2",
+ "arch": "x64",
+ "platform": "linux",
+ "download_url": "https://downloads.python.org/pypy/pypy2.7-v7.3.8rc2-linux64.tar.bz2"
+ },
+ {
+ "filename": "pypy2.7-v7.3.8rc2-osx64.tar.bz2",
+ "arch": "x64",
+ "platform": "darwin",
+ "download_url": "https://downloads.python.org/pypy/pypy2.7-v7.3.8rc2-osx64.tar.bz2"
+ },
+ {
+ "filename": "pypy2.7-v7.3.8rc2-s390x.tar.bz2",
+ "arch": "s390x",
+ "platform": "linux",
+ "download_url": "https://downloads.python.org/pypy/pypy2.7-v7.3.8rc2-s390x.tar.bz2"
+ },
+ {
+ "filename": "pypy2.7-v7.3.8rc2-win64.zip",
+ "arch": "x64",
+ "platform": "win64",
+ "download_url": "https://downloads.python.org/pypy/pypy2.7-v7.3.8rc2-win64.zip"
+ }
+ ]
+ },
+ {
"pypy_version": "7.3.8rc1",
"python_version": "3.9.10",
"stable": false,
@@ -2014,12 +2167,6 @@
"latest_pypy": false,
"files": [
{
- "filename": "pypy-c-jit-latest-aarch64.tar.bz2",
- "arch": "aarch64",
- "platform": "linux",
- "download_url": "http://buildbot.pypy.org/nightly/py3.9/pypy-c-jit-latest-aarch64.tar.bz2"
- },
- {
"filename": "pypy-c-jit-latest-linux.tar.bz2",
"arch": "i686",
"platform": "linux",
diff --git a/rpython/jit/metainterp/test/test_warmspot.py b/rpython/jit/metainterp/test/test_warmspot.py
index a2a508b610..76e382339c 100644
--- a/rpython/jit/metainterp/test/test_warmspot.py
+++ b/rpython/jit/metainterp/test/test_warmspot.py
@@ -1,7 +1,7 @@
import py
from rpython.jit.metainterp import jitexc
from rpython.jit.metainterp.warmspot import get_stats
-from rpython.rlib.jit import JitDriver, set_param, unroll_safe, jit_callback
+from rpython.rlib.jit import JitDriver, set_param, unroll_safe, jit_callback, set_user_param
from rpython.jit.backend.llgraph import runner
from rpython.jit.metainterp.test.support import LLJitMixin
@@ -575,6 +575,26 @@ class TestLLWarmspot(LLJitMixin):
assert str(e.value) == ("there are multiple jit_merge_points "
"with the same jitdriver")
+ def test_jit_off_returns_early(self):
+ from rpython.jit.metainterp.counter import DeterministicJitCounter
+ driver = JitDriver(greens = ['s'], reds = ['i'], name='jit')
+
+ def loop(i, s):
+ set_user_param(driver, "off")
+ while i > s:
+ driver.jit_merge_point(i=i, s=s)
+ i -= 1
+
+ def main(s):
+ loop(30, s)
+
+ fn = DeterministicJitCounter.lookup_chain
+ DeterministicJitCounter.lookup_chain = None
+ try:
+ self.meta_interp(main, [5]) # must not crash
+ finally:
+ DeterministicJitCounter.lookup_chain = fn
+
class TestWarmspotDirect(object):
def setup_class(cls):
diff --git a/rpython/jit/metainterp/warmstate.py b/rpython/jit/metainterp/warmstate.py
index 0ea2b9d2f9..fc2767feac 100644
--- a/rpython/jit/metainterp/warmstate.py
+++ b/rpython/jit/metainterp/warmstate.py
@@ -435,6 +435,8 @@ class WarmEnterState(object):
can_enter_jit() hint, and at the start of a function
with a different threshold.
"""
+ if increment_threshold == 0:
+ return # jit is off
# Look for the cell corresponding to the current greenargs.
# Search for the JitCell that is of the correct subclass of
# BaseJitCell, and that stores a key that compares equal.
diff --git a/rpython/rlib/rfloat.py b/rpython/rlib/rfloat.py
index 04a7b3be72..378022215d 100644
--- a/rpython/rlib/rfloat.py
+++ b/rpython/rlib/rfloat.py
@@ -51,25 +51,27 @@ def string_to_float(s):
"""
from rpython.rlib.rstring import strip_spaces, ParseStringError
- s = strip_spaces(s)
if not s:
raise ParseStringError(INVALID_MSG)
-
- low = s.lower()
- if low == "-inf" or low == "-infinity":
- return -INFINITY
- elif low == "inf" or low == "+inf":
- return INFINITY
- elif low == "infinity" or low == "+infinity":
- return INFINITY
- elif low == "nan" or low == "+nan":
- return NAN
- elif low == "-nan":
- return -NAN
-
+ def iswhitespace(ch):
+ return (ch == ' ' or ch == '\f' or ch == '\n' or ch == '\r' or
+ ch == '\t' or ch == '\v')
+ if iswhitespace(s[0]) or iswhitespace(s[-1]):
+ s = strip_spaces(s)
try:
return rstring_to_float(s)
except ValueError:
+ low = s.lower()
+ if low == "-inf" or low == "-infinity":
+ return -INFINITY
+ elif low == "inf" or low == "+inf":
+ return INFINITY
+ elif low == "infinity" or low == "+infinity":
+ return INFINITY
+ elif low == "nan" or low == "+nan":
+ return NAN
+ elif low == "-nan":
+ return -NAN
raise ParseStringError(INVALID_MSG)
def rstring_to_float(s):
diff --git a/rpython/rlib/test/test_rfloat.py b/rpython/rlib/test/test_rfloat.py
index c0ea94c472..5683d38806 100644
--- a/rpython/rlib/test/test_rfloat.py
+++ b/rpython/rlib/test/test_rfloat.py
@@ -274,6 +274,14 @@ def test_string_to_float():
py.test.raises(ParseStringError, string_to_float, s)
py.test.raises(ParseStringError, string_to_float, "")
+def test_string_to_float_nan():
+ nan = float('nan')
+ pinf = float('inf')
+ for s in ['nan', '+nan', '-nan', 'NAN', '+nAn']:
+ assert math.isnan(string_to_float(s))
+ for s in ['inf', '+inf', '-inf', '-infinity', ' -infiNITy ']:
+ assert math.isinf(string_to_float(s))
+
def test_log2():
from rpython.rlib import rfloat
assert rfloat.log2(1.0) == 0.0