[pypy-commit] pypy record-known-result: merge default

cfbolz pypy.commits at gmail.com
Wed Oct 16 08:45:10 EDT 2019


Author: Carl Friedrich Bolz-Tereick <cfbolz at gmx.de>
Branch: record-known-result
Changeset: r97789:f1e552055e69
Date: 2019-10-16 14:17 +0200
http://bitbucket.org/pypy/pypy/changeset/f1e552055e69/

Log:	merge default

diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -50,4 +50,10 @@
 de061d87e39c7df4e436974096d7982c676a859d release-pypy3.6-v7.1.0
 784b254d669919c872a505b807db8462b6140973 release-pypy3.6-v7.1.1
 8cdda8b8cdb8ff29d9e620cccd6c5edd2f2a23ec release-pypy2.7-v7.1.1
-
+85dae4fd5c234b482feff834c73e089872194541 release-pypy2.7-v7.2.0rc0
+7ffb92269488f37c707ce66076f50ffd8613f8e2 release-pypy3.6-v7.2.0rc0
+4d6761df14ffd6f38450f183ac1fad32c946c21b release-pypy3.6-v7.2.0rc1
+5da45ced70e515f94686be0df47c59abd1348ebc release-pypy3.6-v7.2.0rc2
+4a68d8d3d2fc1faec2e83bcb4d28559099092574 release-pypy2.7-v7.2.0rc2
+4a68d8d3d2fc1faec2e83bcb4d28559099092574 release-pypy2.7-v7.2.0
+5da45ced70e515f94686be0df47c59abd1348ebc release-pypy3.6-v7.2.0
diff --git a/lib-python/2.7/test/test_dictviews.py b/lib-python/2.7/test/test_dictviews.py
--- a/lib-python/2.7/test/test_dictviews.py
+++ b/lib-python/2.7/test/test_dictviews.py
@@ -182,7 +182,7 @@
 
     def test_deeply_nested_repr(self):
         d = {}
-        for i in range(sys.getrecursionlimit() + 100):
+        for i in range(sys.getrecursionlimit() + 200):
             d = {42: d.viewvalues()}
         self.assertRaises(RuntimeError, repr, d)
 
diff --git a/pypy/doc/commandline_ref.rst b/pypy/doc/commandline_ref.rst
--- a/pypy/doc/commandline_ref.rst
+++ b/pypy/doc/commandline_ref.rst
@@ -9,3 +9,4 @@
 
    man/pypy.1.rst
    man/pypy3.1.rst
+   jit_help.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
@@ -42,7 +42,8 @@
 -------------------------------
 
 .. toctree::
-   whatsnew-pypy3-head.rst
+    whatsnew-pypy3-head.rst
+    whatsnew-pypy3-7.1.0.rst
 
 CPython 3.5 compatible versions
 -------------------------------
@@ -50,6 +51,8 @@
 .. toctree::
 
    whatsnew-pypy3-7.0.0.rst
+   whatsnew-pypy3-6.0.0.rst
+   whatsnew-pypy3-5.10.0.rst
    whatsnew-pypy3-5.9.0.rst
    whatsnew-pypy3-5.8.0.rst
    whatsnew-pypy3-5.7.0.rst
@@ -62,10 +65,4 @@
    whatsnew-pypy3-5.5.0.rst
    whatsnew-pypy3-5.1.1-alpha1.rst
 
-CPython 3.2 compatible versions
--------------------------------
 
-.. toctree::
-
-   whatsnew-pypy3-2.4.0.rst
-   whatsnew-pypy3-2.3.1.rst
diff --git a/pypy/doc/jit_help.rst b/pypy/doc/jit_help.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/jit_help.rst
@@ -0,0 +1,78 @@
+========
+JIT help
+========
+
+.. note this is from ``pypy --jit help``
+
+Advanced JIT options
+====================
+
+``<pypy> --jit`` [*options*] where *options* is a comma-separated list of
+``OPTION=VALUE``:
+
+ decay=N
+    amount to regularly decay counters by (0=none, 1000=max) (default 40)
+
+ disable_unrolling=N
+    after how many operations we should not unroll (default 200)
+
+ enable_opts=N
+    INTERNAL USE ONLY (MAY NOT WORK OR LEAD TO CRASHES): optimizations to
+    enable, or all =
+    intbounds:rewrite:virtualize:string:pure:earlyforce:heap:unroll (default
+    all)
+
+ function_threshold=N
+    number of times a function must run for it to become traced from start
+    (default 1619)
+
+ inlining=N
+    inline python functions or not (1/0) (default 1)
+
+ loop_longevity=N
+    a parameter controlling how long loops will be kept before being freed,
+    an estimate (default 1000)
+
+ max_retrace_guards=N
+    number of extra guards a retrace can cause (default 15)
+
+ max_unroll_loops=N
+    number of extra unrollings a loop can cause (default 0)
+
+ max_unroll_recursion=N
+    how many levels deep to unroll a recursive function (default 7)
+
+ retrace_limit=N
+    how many times we can try retracing before giving up (default 0)
+
+ threshold=N
+    number of times a loop has to run for it to become hot (default 1039)
+
+ trace_eagerness=N
+    number of times a guard has to fail before we start compiling a bridge
+    (default 200)
+
+ trace_limit=N
+    number of recorded operations before we abort tracing with ABORT_TOO_LONG
+    (default 6000)
+
+ vec=N
+    turn on the vectorization optimization (vecopt). Supports x86 (SSE 4.1),
+    powerpc (SVX), s390x SIMD (default 0)
+
+ vec_all=N
+    try to vectorize trace loops that occur outside of the numpypy library
+    (default 0)
+
+ vec_cost=N
+    threshold for which traces to bail. Unpacking increases the counter,
+    vector operation decrease the cost (default 0)
+
+ off
+    turn off the JIT
+ help
+    print this page
+
+The :ref:`pypyjit<jit-hooks>` module can be used to control the JIT from inside
+pypy
+
diff --git a/pypy/doc/release-v7.2.0.rst b/pypy/doc/release-v7.2.0.rst
--- a/pypy/doc/release-v7.2.0.rst
+++ b/pypy/doc/release-v7.2.0.rst
@@ -216,6 +216,7 @@
 * Add more constants to `sysconfig``. Set ``MACOSX_DEPLOYMENT_TARGET`` for
   darwin (`issue 2994`_)
 * fix ``CBuffer.buffer_attach``
+* Add ``_PyDict_GetItemWithError`` (``PyDict_GetItemWithError`` on Python3)
 
 Python 3.6 only
 ---------------
@@ -307,6 +308,7 @@
 .. _33786 : https://bugs.python.org/issue33786
 .. _32270 : https://bugs.python.org/issue32270
 .. _28691 : https://bugs.python.org/issue28691
+.. _33729 : https://bugs.python.org/issue33729
 
 .. _opencv2: https://github.com/skvark/opencv-python/
 .. _`issue 2617`: https://bitbucket.com/pypy/pypy/issues/2617
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
@@ -3,11 +3,9 @@
 ==========================
 
 .. this is a revision shortly after release-pypy-7.2.0
-.. startrev: 78cd4acbcbec 
+.. startrev: a511d86377d6 
 
+.. branch: fix-descrmismatch-crash
 
-.. branch: json-decoder-maps
+Fix segfault when calling descr-methods with no arguments
 
-Much faster and more memory-efficient JSON decoding. The resulting
-dictionaries that come out of the JSON decoder have faster lookups too.
-
diff --git a/pypy/doc/whatsnew-pypy2-5.7.0.rst b/pypy/doc/whatsnew-pypy2-5.7.0.rst
--- a/pypy/doc/whatsnew-pypy2-5.7.0.rst
+++ b/pypy/doc/whatsnew-pypy2-5.7.0.rst
@@ -14,6 +14,7 @@
 changed in exactly the same way because of this fix.
 
 
+
 .. branch: rpython-error-to-systemerror
 
 Any uncaught RPython exception (from a PyPy bug) is turned into an
diff --git a/pypy/doc/whatsnew-pypy2-7.2.0.rst b/pypy/doc/whatsnew-pypy2-7.2.0.rst
--- a/pypy/doc/whatsnew-pypy2-7.2.0.rst
+++ b/pypy/doc/whatsnew-pypy2-7.2.0.rst
@@ -74,3 +74,9 @@
 .. branch: openssl-for-macos
 
 Update _ssl on macos to statically link to openssl-1.1.1c
+
+.. branch: json-decoder-maps
+
+Much faster and more memory-efficient JSON decoding. The resulting
+dictionaries that come out of the JSON decoder have faster lookups too.
+
diff --git a/pypy/doc/whatsnew-pypy3-2.3.1.rst b/pypy/doc/whatsnew-pypy3-2.3.1.rst
deleted file mode 100644
--- a/pypy/doc/whatsnew-pypy3-2.3.1.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-=========================
-What's new in PyPy3 2.3.1
-=========================
-
-.. this is a revision shortly after pypy3-release-2.3.x
-.. startrev: 0137d8e6657d
diff --git a/pypy/doc/whatsnew-pypy3-2.4.0.rst b/pypy/doc/whatsnew-pypy3-2.4.0.rst
deleted file mode 100644
--- a/pypy/doc/whatsnew-pypy3-2.4.0.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-=========================
-What's new in PyPy3 2.4.0
-=========================
-
-.. this is a revision shortly after pypy3-release-2.4.x
-.. startrev: 12b940544622
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -22,9 +22,13 @@
 
 __all__ = ['ObjSpace', 'OperationError', 'W_Root']
 
+def get_printable_location(tp):
+    return "unpackiterable: %s" % (tp, )
+
 unpackiterable_driver = jit.JitDriver(name='unpackiterable',
                                       greens=['tp'],
-                                      reds=['items', 'w_iterator'])
+                                      reds=['items', 'w_iterator'],
+                                      get_printable_location=get_printable_location)
 
 
 class W_Root(object):
@@ -419,6 +423,8 @@
 
 @specialize.memo()
 def wrappable_class_name(Class):
+    if 'exact_class_applevel_name' in Class.__dict__:
+        return Class.exact_class_applevel_name
     try:
         return Class.typedef.name
     except AttributeError:
diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py
--- a/pypy/interpreter/gateway.py
+++ b/pypy/interpreter/gateway.py
@@ -709,6 +709,7 @@
                     self.func__args__ = func
                 elif unwrap_spec == [self_type, ObjSpace, Arguments]:
                     self.__class__ = BuiltinCodePassThroughArguments1
+                    self.descr_reqcls = self_type
                     miniglobals = {'func': func, 'self_type': self_type}
                     d = {}
                     source = """if 1:
@@ -754,10 +755,7 @@
         except DescrMismatch:
             if w_obj is not None:
                 args = args.prepend(w_obj)
-            return scope_w[0].descr_call_mismatch(space,
-                                                  self.descrmismatch_op,
-                                                  self.descr_reqcls,
-                                                  args)
+            return self._type_unwrap_mismatch(space, args)
         except Exception as e:
             self.handle_exception(space, e)
             w_result = None
@@ -765,6 +763,15 @@
             w_result = space.w_None
         return w_result
 
+    def _type_unwrap_mismatch(self, space, args):
+        w_obj = args.firstarg()
+        if w_obj is None:
+            raise oefmt(space.w_SystemError, "unexpected DescrMismatch error")
+        return w_obj.descr_call_mismatch(space,
+                                         self.descrmismatch_op,
+                                         self.descr_reqcls,
+                                         args)
+
     def handle_exception(self, space, e):
         try:
             if not we_are_translated():
@@ -787,10 +794,7 @@
         try:
             w_result = self.func__args__(space, args)
         except DescrMismatch:
-            return args.firstarg().descr_call_mismatch(space,
-                                                  self.descrmismatch_op,
-                                                  self.descr_reqcls,
-                                                  args)
+            return self._type_unwrap_mismatch(space, args)
         except Exception as e:
             self.handle_exception(space, e)
             w_result = None
@@ -808,10 +812,7 @@
         try:
             w_result = self.func__args__(space, w_obj, args)
         except DescrMismatch:
-            return args.firstarg().descr_call_mismatch(space,
-                                                  self.descrmismatch_op,
-                                                  self.descr_reqcls,
-                                                  args.prepend(w_obj))
+            return self._type_unwrap_mismatch(space, args.prepend(w_obj))
         except Exception as e:
             self.handle_exception(space, e)
             w_result = None
@@ -851,9 +852,7 @@
         try:
             w_result = self.fastfunc_1(space, w1)
         except DescrMismatch:
-            return w1.descr_call_mismatch(space,
-                                          self.descrmismatch_op,
-                                          self.descr_reqcls,
+            return self._type_unwrap_mismatch(space,
                                           Arguments(space, [w1]))
         except Exception as e:
             self.handle_exception(space, e)
@@ -877,9 +876,7 @@
         try:
             w_result = self.fastfunc_2(space, w1, w2)
         except DescrMismatch:
-            return w1.descr_call_mismatch(space,
-                                          self.descrmismatch_op,
-                                          self.descr_reqcls,
+            return self._type_unwrap_mismatch(space,
                                           Arguments(space, [w1, w2]))
         except Exception as e:
             self.handle_exception(space, e)
@@ -904,9 +901,7 @@
         try:
             w_result = self.fastfunc_3(space, w1, w2, w3)
         except DescrMismatch:
-            return w1.descr_call_mismatch(space,
-                                          self.descrmismatch_op,
-                                          self.descr_reqcls,
+            return self._type_unwrap_mismatch(space,
                                           Arguments(space, [w1, w2, w3]))
         except Exception as e:
             self.handle_exception(space, e)
@@ -932,9 +927,7 @@
         try:
             w_result = self.fastfunc_4(space, w1, w2, w3, w4)
         except DescrMismatch:
-            return w1.descr_call_mismatch(space,
-                                          self.descrmismatch_op,
-                                          self.descr_reqcls,
+            return self._type_unwrap_mismatch(space,
                                           Arguments(space,
                                                     [w1, w2, w3, w4]))
         except Exception as e:
diff --git a/pypy/interpreter/test/test_gateway.py b/pypy/interpreter/test/test_gateway.py
--- a/pypy/interpreter/test/test_gateway.py
+++ b/pypy/interpreter/test/test_gateway.py
@@ -966,6 +966,29 @@
         # white-box check for opt
         assert called[0] is args
 
+    def test_base_regular_descr_mismatch(self):
+        space = self.space
+
+        def f():
+            raise gateway.DescrMismatch
+
+        w_f = space.wrap(gateway.interp2app_temp(f,
+                         unwrap_spec=[]))
+        args = argument.Arguments(space, [])
+        space.raises_w(space.w_SystemError, space.call_args, w_f, args)
+
+    def test_pass_trough_arguments0_descr_mismatch(self):
+        space = self.space
+
+        def f(space, __args__):
+            raise gateway.DescrMismatch
+
+        w_f = space.wrap(gateway.interp2app_temp(f,
+                         unwrap_spec=[gateway.ObjSpace,
+                                      gateway.Arguments]))
+        args = argument.Arguments(space, [])
+        space.raises_w(space.w_SystemError, space.call_args, w_f, args)
+
 
 class AppTestKeywordsToBuiltinSanity(object):
     def test_type(self):
@@ -1005,3 +1028,26 @@
 
         d.update(**{clash: 33})
         dict.update(d, **{clash: 33})
+
+
+
+class AppTestFastPathCrash(object):
+    def setup_class(cls):
+        cls.w_runappdirect = cls.space.wrap(cls.runappdirect)
+
+    def test_fast_path_crash(self):
+        # issue bb-3091 crash in BuiltinCodePassThroughArguments0.funcrun
+        for obj in (dict, set):
+            with raises(TypeError) as excinfo:
+                if self.runappdirect:
+                    import platform
+                    if platform.python_implementation() == 'PyPy':
+                        msg_fmt = "%s instance as first argument (got %s"
+                    else:
+                        msg_fmt = "'%s' object but received a '%s'"
+                    obj.__init__(0)
+                else:
+                    msg_fmt = "'%s' object expected, got '%s'"
+                    obj.__init__.im_func(0)
+            msg = msg_fmt %(obj.__name__, 'int')
+            assert msg in str(excinfo.value)
diff --git a/pypy/module/_pypyjson/interp_decoder.py b/pypy/module/_pypyjson/interp_decoder.py
--- a/pypy/module/_pypyjson/interp_decoder.py
+++ b/pypy/module/_pypyjson/interp_decoder.py
@@ -69,6 +69,9 @@
     # hit in the cache
     STRING_CACHE_USEFULNESS_FACTOR = 4
 
+    # don't make arbitrarily huge maps
+    MAX_MAP_SIZE = 100
+
 
     def __init__(self, space, s):
         self.space = space
@@ -368,7 +371,7 @@
                 return w_res
             elif ch == ',':
                 i = self.skip_whitespace(i)
-                if currmap.is_state_blocked():
+                if currmap.is_state_blocked() or nextindex > self.MAX_MAP_SIZE:
                     self.scratch.append(values_w)  # can reuse next time
                     dict_w = self._switch_to_dict(currmap, values_w, nextindex)
                     return self.decode_object_dict(i, start, dict_w)
diff --git a/pypy/module/_pypyjson/simd.py b/pypy/module/_pypyjson/simd.py
--- a/pypy/module/_pypyjson/simd.py
+++ b/pypy/module/_pypyjson/simd.py
@@ -1,7 +1,7 @@
 from rpython.rtyper.lltypesystem import lltype, rffi
 from rpython.rlib import objectmodel, unroll
 from rpython.rlib.rarithmetic import r_uint, intmask, LONG_BIT
-from rpython.jit.backend.detect_cpu import autodetect
+from rpython.jit.backend.detect_cpu import autodetect, ProcessorAutodetectError
 
 # accelerators for string operations using simd on regular word sizes (*not*
 # SSE instructions). this style is sometimes called SWAR (SIMD Within A
@@ -15,8 +15,11 @@
     WORD_SIZE = 8
     EVERY_BYTE_ONE = 0x0101010101010101
     EVERY_BYTE_HIGHEST_BIT = 0x8080808080808080
-    if autodetect() == "x86-64":
-        USE_SIMD = True
+    try:
+        if autodetect() == "x86-64":
+            USE_SIMD = True
+    except ProcessorAutodetectError:
+        pass
 else:
     WORD_SIZE = 4
     EVERY_BYTE_ONE = 0x01010101
diff --git a/pypy/module/_pypyjson/test/test__pypyjson.py b/pypy/module/_pypyjson/test/test__pypyjson.py
--- a/pypy/module/_pypyjson/test/test__pypyjson.py
+++ b/pypy/module/_pypyjson/test/test__pypyjson.py
@@ -469,6 +469,14 @@
         res = _pypyjson.loads(json)
         assert res == [{u'a': 1}, {u'a': 2}]
 
+    def test_huge_map(self):
+        import _pypyjson
+        import __pypy__
+        s = '{' + ",".join('"%s": %s' % (i, i) for i in range(200)) + '}'
+        res = _pypyjson.loads(s)
+        assert len(res) == 200
+        assert __pypy__.strategy(res) == "UnicodeDictStrategy"
+
     def test_tab_in_string_should_fail(self):
         import _pypyjson
         # http://json.org/JSON_checker/test/fail25.json
diff --git a/pypy/module/_weakref/interp__weakref.py b/pypy/module/_weakref/interp__weakref.py
--- a/pypy/module/_weakref/interp__weakref.py
+++ b/pypy/module/_weakref/interp__weakref.py
@@ -156,6 +156,8 @@
 
 
 class W_WeakrefBase(W_Root):
+    exact_class_applevel_name = 'weakref-or-proxy'
+
     def __init__(self, space, w_obj, w_callable):
         assert w_callable is not space.w_None    # should be really None
         self.space = space
diff --git a/pypy/module/_weakref/test/test_weakref.py b/pypy/module/_weakref/test/test_weakref.py
--- a/pypy/module/_weakref/test/test_weakref.py
+++ b/pypy/module/_weakref/test/test_weakref.py
@@ -543,3 +543,12 @@
         p1[42] = p2
         assert a1.setkey == 42
         assert a1.setvalue is p2
+
+    def test_error_message_wrong_self(self):
+        import _weakref
+        unboundmeth = _weakref.ref.__repr__
+        e = raises(TypeError, unboundmeth, 42)
+        assert "weakref" in str(e.value)
+        if hasattr(unboundmeth, 'im_func'):
+            e = raises(TypeError, unboundmeth.im_func, 42)
+            assert "'weakref-or-proxy'" in str(e.value)
diff --git a/pypy/module/cStringIO/interp_stringio.py b/pypy/module/cStringIO/interp_stringio.py
--- a/pypy/module/cStringIO/interp_stringio.py
+++ b/pypy/module/cStringIO/interp_stringio.py
@@ -7,6 +7,8 @@
 
 
 class W_InputOutputType(W_Root):
+    exact_class_applevel_name = "StringI-or-StringO"
+
     softspace = 0    # part of the file object API
 
     def descr___iter__(self):
diff --git a/pypy/module/cStringIO/test/test_interp_stringio.py b/pypy/module/cStringIO/test/test_interp_stringio.py
--- a/pypy/module/cStringIO/test/test_interp_stringio.py
+++ b/pypy/module/cStringIO/test/test_interp_stringio.py
@@ -204,3 +204,12 @@
         import cStringIO
         assert type(cStringIO.StringIO()) is cStringIO.OutputType
         assert type(cStringIO.StringIO('')) is cStringIO.InputType
+
+    def test_error_message_wrong_self(self):
+        import cStringIO
+        unboundmeth = cStringIO.InputType.close
+        e = raises(TypeError, unboundmeth, 42)
+        assert "StringI" in str(e.value)
+        if hasattr(unboundmeth, 'im_func'):
+            e = raises(TypeError, unboundmeth.im_func, 42)
+            assert "'StringI-or-StringO'" in str(e.value)
diff --git a/pypy/module/cpyext/dictobject.py b/pypy/module/cpyext/dictobject.py
--- a/pypy/module/cpyext/dictobject.py
+++ b/pypy/module/cpyext/dictobject.py
@@ -80,6 +80,13 @@
     # XXX this is wrong with IntMutableCell.  Hope it works...
     return w_dict.getitem(w_key)
 
+ at cpython_api([PyObject, PyObject], PyObject, result_borrowed=True)
+def _PyDict_GetItemWithError(space, w_dict, w_key):
+    # Like PyDict_GetItem(), but doesn't swallow the error
+    if not isinstance(w_dict, W_DictMultiObject):
+        PyErr_BadInternalCall(space)
+    return w_dict.getitem(w_key)
+
 @cpython_api([PyObject, PyObject, PyObject], rffi.INT_real, error=-1)
 def PyDict_SetItem(space, w_dict, w_key, w_obj):
     if not isinstance(w_dict, W_DictMultiObject):
diff --git a/pypy/module/cpyext/test/test_dictobject.py b/pypy/module/cpyext/test/test_dictobject.py
--- a/pypy/module/cpyext/test/test_dictobject.py
+++ b/pypy/module/cpyext/test/test_dictobject.py
@@ -173,6 +173,26 @@
             ])
         assert module.dict_proxy({'a': 1, 'b': 2}) == 2
 
+    def test_getitemwitherror(self):
+        module = self.import_extension('foo', [
+            ("dict_getitem", "METH_VARARGS",
+             """
+             PyObject *d, *key, *result;
+             if (!PyArg_ParseTuple(args, "OO", &d, &key)) {
+                return NULL;
+             }
+             result = _PyDict_GetItemWithError(d, key);
+             if (result == NULL && !PyErr_Occurred())
+                Py_RETURN_NONE;
+             Py_XINCREF(result);
+             return result;
+             """)])
+        d = {'foo': 'bar'}
+        assert module.dict_getitem(d, 'foo') == 'bar'
+        assert module.dict_getitem(d, 'missing') is None
+        with raises(TypeError):
+            module.dict_getitem(d, [])
+
     def test_update(self):
         module = self.import_extension('foo', [
             ("update", "METH_VARARGS",
diff --git a/pypy/objspace/fake/objspace.py b/pypy/objspace/fake/objspace.py
--- a/pypy/objspace/fake/objspace.py
+++ b/pypy/objspace/fake/objspace.py
@@ -149,6 +149,9 @@
         is_root(w_obj)
         return NonConstant(False)
 
+    def utf8_len_w(self, space):
+        return NonConstant((NonConstant("utf8len_foobar"), NonConstant(14)))
+
     @not_rpython
     def unwrap(self, w_obj):
         raise NotImplementedError
diff --git a/pypy/objspace/fake/test/test_objspace.py b/pypy/objspace/fake/test/test_objspace.py
--- a/pypy/objspace/fake/test/test_objspace.py
+++ b/pypy/objspace/fake/test/test_objspace.py
@@ -1,4 +1,5 @@
-import py
+import pytest
+from rpython.rlib.nonconst import NonConstant
 from pypy.objspace.fake.objspace import FakeObjSpace, W_Root
 from pypy.interpreter.argument import Arguments
 from pypy.interpreter.typedef import TypeDef
@@ -63,8 +64,8 @@
     def test_is_true(self):
         space = self.space
         space.translates(lambda: space.is_true(W_Root()))
-        py.test.raises(AssertionError,
-                       space.translates, lambda: space.is_true(42))
+        with pytest.raises(AssertionError):
+            space.translates(lambda: space.is_true(42))
 
     def test_unpackiterable(self):
         space = self.space
@@ -79,3 +80,23 @@
         space = self.space
         space.translates(lambda: (space.get(W_Root(), W_Root()),
                                   space.get(W_Root(), W_Root(), W_Root())))
+
+    def test_bug_utf8_len_w(self):
+        space = self.space
+
+        class A(object):
+            pass
+
+        def f():
+            s = NonConstant('a')
+            w_s = space.newutf8(s, 1)
+            t, l = space.utf8_len_w(w_s)
+            a = A()
+            if l == 1:
+                a.x = 1
+            else:
+                raise Exception
+            return a.x
+        space.translates(f)
+
+
diff --git a/pypy/objspace/std/bytesobject.py b/pypy/objspace/std/bytesobject.py
--- a/pypy/objspace/std/bytesobject.py
+++ b/pypy/objspace/std/bytesobject.py
@@ -24,6 +24,7 @@
 
 class W_AbstractBytesObject(W_Root):
     __slots__ = ()
+    exact_class_applevel_name = 'str'
 
     def is_w(self, space, w_other):
         if not isinstance(w_other, W_AbstractBytesObject):
diff --git a/pypy/objspace/std/mapdict.py b/pypy/objspace/std/mapdict.py
--- a/pypy/objspace/std/mapdict.py
+++ b/pypy/objspace/std/mapdict.py
@@ -692,10 +692,12 @@
             return unerase_item(erased)
 
         def _mapdict_write_storage(self, storageindex, value):
-            for i in rangenmin1:
-                if storageindex == i:
-                    setattr(self, "_value%s" % i, value)
-                    return
+            assert storageindex >= 0
+            if storageindex < nmin1:
+                for i in rangenmin1:
+                    if storageindex == i:
+                        setattr(self, "_value%s" % i, value)
+                        return
             if self._has_storage_list():
                 self._mapdict_get_storage_list()[storageindex - nmin1] = value
                 return
diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py
--- a/pypy/objspace/std/setobject.py
+++ b/pypy/objspace/std/setobject.py
@@ -20,6 +20,7 @@
 
 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'."""
@@ -496,6 +497,12 @@
 
 
 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:
@@ -516,7 +523,7 @@
 
 Build an unordered collection.""",
     __new__ = gateway.interp2app(W_SetObject.descr_new),
-    __init__ = gateway.interp2app(W_BaseSetObject.descr_init),
+    __init__ = gateway.interp2app(W_SetObject.descr_init),
     __repr__ = gateway.interp2app(W_BaseSetObject.descr_repr),
     __hash__ = None,
     __cmp__ = gateway.interp2app(W_BaseSetObject.descr_cmp),
@@ -1657,9 +1664,13 @@
     w_set.sstorage = w_set.strategy.get_storage_from_list(iterable_w)
 
 
+def get_printable_location(tp, strategy):
+    return "create_set: %s %s" % (tp, strategy)
+
 create_set_driver = jit.JitDriver(name='create_set',
                                   greens=['tp', 'strategy'],
-                                  reds='auto')
+                                  reds='auto',
+                                  get_printable_location=get_printable_location)
 
 def _create_from_iterable(space, w_set, w_iterable):
     w_set.strategy = strategy = space.fromcache(EmptySetStrategy)
diff --git a/pypy/objspace/std/test/test_bytesobject.py b/pypy/objspace/std/test/test_bytesobject.py
--- a/pypy/objspace/std/test/test_bytesobject.py
+++ b/pypy/objspace/std/test/test_bytesobject.py
@@ -933,3 +933,10 @@
     def test_add(self):
         assert 'abc' + 'abc' == 'abcabc'
         assert isinstance('abc' + u'\u03a3', unicode)
+
+    def test_error_message_wrong_self(self):
+        e = raises(TypeError, bytes.upper, 42)
+        assert "str" in str(e.value)
+        if hasattr(bytes.upper, 'im_func'):
+            e = raises(TypeError, bytes.upper.im_func, 42)
+            assert "'str'" in str(e.value)
diff --git a/pypy/objspace/std/test/test_intobject.py b/pypy/objspace/std/test/test_intobject.py
--- a/pypy/objspace/std/test/test_intobject.py
+++ b/pypy/objspace/std/test/test_intobject.py
@@ -684,6 +684,15 @@
         x = int(-sys.maxint)
         assert x.__rsub__(2) == (2 + sys.maxint)
 
+    def test_error_message_wrong_self(self):
+        unboundmeth = int.__str__
+        e = raises(TypeError, unboundmeth, "!")
+        assert "int" in str(e.value)
+        if hasattr(unboundmeth, 'im_func'):
+            e = raises(TypeError, unboundmeth.im_func, "!")
+            assert "'int'" in str(e.value)
+
+
 class AppTestIntShortcut(AppTestInt):
     spaceconfig = {"objspace.std.intshortcut": True}
 
diff --git a/pypy/objspace/std/test/test_longobject.py b/pypy/objspace/std/test/test_longobject.py
--- a/pypy/objspace/std/test/test_longobject.py
+++ b/pypy/objspace/std/test/test_longobject.py
@@ -450,3 +450,10 @@
         expected = (2 << (size * 4)) // 3
         assert long(n, 16) == expected
 
+    def test_error_message_wrong_self(self):
+        unboundmeth = long.__str__
+        e = raises(TypeError, unboundmeth, 42)
+        assert "long" in str(e.value)
+        if hasattr(unboundmeth, 'im_func'):
+            e = raises(TypeError, unboundmeth.im_func, 42)
+            assert "'long'" in str(e.value)
diff --git a/pypy/objspace/std/test/test_setobject.py b/pypy/objspace/std/test/test_setobject.py
--- a/pypy/objspace/std/test/test_setobject.py
+++ b/pypy/objspace/std/test/test_setobject.py
@@ -1037,3 +1037,15 @@
            raise ValueError
            yield 1
         raises(ValueError, set, f())
+
+    def test_frozenset_init_does_nothing(self):
+        f = frozenset([1, 2, 3])
+        f.__init__(4, 5, 6)
+        assert f == frozenset([1, 2, 3])
+
+    def test_error_message_wrong_self(self):
+        e = raises(TypeError, frozenset.copy, 42)
+        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)
diff --git a/pypy/objspace/std/test/test_tupleobject.py b/pypy/objspace/std/test/test_tupleobject.py
--- a/pypy/objspace/std/test/test_tupleobject.py
+++ b/pypy/objspace/std/test/test_tupleobject.py
@@ -454,3 +454,11 @@
             (4.1, 2.3), (3.6, 4.8)]
         assert specialized_zip_2_lists(["foo", "bar"], [6, 2]) == [
             ("foo", 6), ("bar", 2)]
+
+    def test_error_message_wrong_self(self):
+        unboundmeth = tuple.__hash__
+        e = raises(TypeError, unboundmeth, 42)
+        assert "tuple" in str(e.value)
+        if hasattr(unboundmeth, 'im_func'):
+            e = raises(TypeError, unboundmeth.im_func, 42)
+            assert "'tuple'" in str(e.value)
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,15 +1,18 @@
 # Edit these appropriately before running this script
 pmaj=2  # python main version: 2 or 3
 pmin=7  # python minor version
-exe=pypy3 # pypy3 or pypy
 maj=7
 min=2
-rev=0
+rev=0rc2
 
+case $pmaj in
+    "2") exe=pypy;;
+    "3") exe=pypy3;;
+    *) echo invalid pmaj=$pmaj; exit 1;;
+esac
 
 branchname=release-pypy$pmaj.$pmin-v$maj.x # ==OR== release-v$maj.x  # ==OR== release-v$maj.$min.x
-tagname=release-candidate-pypy$pmaj.$pmin-v$maj.$min.$rev  # ==OR== release-$maj.$min
-# tagname=release-pypy$pmaj.$pmin-v$maj.$min.$rev  # ==OR== release-$maj.$min
+tagname=release-pypy$pmaj.$pmin-v$maj.$min.$rev  # ==OR== release-$maj.$min
 
 echo checking hg log -r $branchname
 hg log -r $branchname || exit 1
diff --git a/requirements.txt b/requirements.txt
--- a/requirements.txt
+++ b/requirements.txt
@@ -6,5 +6,5 @@
 vmprof>=0.4.10; 'x86' in platform.machine #skip arm, s390x
 
 # hypothesis is used for test generation on untranslated tests
-hypothesis
+hypothesis<4.40
 enum34>=1.1.2
diff --git a/rpython/jit/metainterp/quasiimmut.py b/rpython/jit/metainterp/quasiimmut.py
--- a/rpython/jit/metainterp/quasiimmut.py
+++ b/rpython/jit/metainterp/quasiimmut.py
@@ -5,6 +5,7 @@
 from rpython.jit.metainterp.history import (
     AbstractDescr, ConstPtr, ConstInt, ConstFloat)
 from rpython.rlib.objectmodel import we_are_translated
+from rpython.rlib.debug import ll_assert, debug_print, debug_start, debug_stop
 
 
 def get_mutate_field_name(fieldname):
@@ -26,12 +27,14 @@
     return qmut
 
 def make_invalidation_function(STRUCT, mutatefieldname):
-    #
+    # fake a repr
+    descr_repr = "FieldDescr(%s, '%s')" % (STRUCT.TO, mutatefieldname)
+
     def _invalidate_now(p):
         qmut_ptr = getattr(p, mutatefieldname)
         setattr(p, mutatefieldname, lltype.nullptr(rclass.OBJECT))
         qmut = cast_base_ptr_to_instance(QuasiImmut, qmut_ptr)
-        qmut.invalidate()
+        qmut.invalidate(descr_repr)
     _invalidate_now._dont_inline_ = True
     #
     def invalidation(p):
@@ -45,7 +48,7 @@
     if qmut_ref:
         cpu.bh_setfield_gc_r(p, ConstPtr.value, mutatefielddescr)
         qmut = cast_gcref_to_instance(QuasiImmut, qmut_ref)
-        qmut.invalidate()
+        qmut.invalidate(mutatefielddescr.repr_of_descr())
 
 
 class QuasiImmut(object):
@@ -78,7 +81,8 @@
         # already invalidated; see below
         self.compress_limit = (len(self.looptokens_wrefs) + 15) * 2
 
-    def invalidate(self):
+    def invalidate(self, descr_repr=None):
+        debug_start("jit-invalidate-quasi-immutable")
         # When this is called, all the loops that we record become
         # invalid: all GUARD_NOT_INVALIDATED in these loops (and
         # in attached bridges) must now fail.
@@ -87,9 +91,11 @@
             return
         wrefs = self.looptokens_wrefs
         self.looptokens_wrefs = []
+        invalidated = 0
         for wref in wrefs:
             looptoken = wref()
             if looptoken is not None:
+                invalidated += 1
                 looptoken.invalidated = True
                 self.cpu.invalidate_loop(looptoken)
                 # NB. we must call cpu.invalidate_loop() even if
@@ -100,6 +106,8 @@
                 if not we_are_translated():
                     self.cpu.stats.invalidated_token_numbers.add(
                         looptoken.number)
+        debug_print("fieldname", descr_repr or "<unknown>", "invalidated", invalidated)
+        debug_stop("jit-invalidate-quasi-immutable")
 
 
 class QuasiImmutDescr(AbstractDescr):
diff --git a/rpython/rlib/runicode.py b/rpython/rlib/runicode.py
--- a/rpython/rlib/runicode.py
+++ b/rpython/rlib/runicode.py
@@ -1903,7 +1903,9 @@
                 if MultiByteToWideChar(CP_ACP, flags,
                                        dataptr, size, buf.raw, usize) == 0:
                     _decode_mbcs_error(s, errorhandler)
-                return buf.str(usize), size
+                ret = buf.str(usize)
+                assert ret is not None
+                return ret, size
 
     def unicode_encode_mbcs(s, size, errors, errorhandler=None,
                             force_replace=True):
diff --git a/rpython/translator/revdb/src-revdb/revdb_include.h b/rpython/translator/revdb/src-revdb/revdb_include.h
--- a/rpython/translator/revdb/src-revdb/revdb_include.h
+++ b/rpython/translator/revdb/src-revdb/revdb_include.h
@@ -285,6 +285,8 @@
 #define OP_GC_RAWREFCOUNT_NEXT_DEAD(r)   \
     r = rpy_reverse_db_rawrefcount_next_dead()
 
+#define OP_GC_INCREASE_ROOT_STACK_DEPTH(depth, r)   /* nothing */
+
 
 RPY_EXTERN void rpy_reverse_db_flush(void);  /* must be called with the lock */
 RPY_EXTERN void rpy_reverse_db_fetch(const char *file, int line);


More information about the pypy-commit mailing list