Author: Matti Picus <matti.pi...@gmail.com>
Branch: 
Changeset: r97783:f089d461d2ee
Date: 2019-10-16 08:14 +0300
http://bitbucket.org/pypy/pypy/changeset/f089d461d2ee/

Log:    merge branch to fix descrmismatch exception

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/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-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/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -419,6 +419,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/_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/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/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),
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)
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to