Author: Armin Rigo <ar...@tunes.org>
Branch: 
Changeset: r83685:5319e039544e
Date: 2016-04-15 16:13 +0200
http://bitbucket.org/pypy/pypy/changeset/5319e039544e/

Log:    Two tests and two related fixes in typeobject (segfaults the
        translated pypy)

diff --git a/pypy/objspace/std/test/test_typeobject.py 
b/pypy/objspace/std/test/test_typeobject.py
--- a/pypy/objspace/std/test/test_typeobject.py
+++ b/pypy/objspace/std/test/test_typeobject.py
@@ -1073,6 +1073,24 @@
         class D(B, A):     # "best base" is A
             __slots__ = ("__weakref__",)
 
+    def test_crash_mro_without_object_1(self):
+        class X(type):
+            def mro(self):
+                return [self]
+        class C:
+            __metaclass__ = X
+        e = raises(TypeError, C)     # the lookup of '__new__' fails
+        assert str(e.value) == "cannot create 'C' instances"
+
+    def test_crash_mro_without_object_2(self):
+        class X(type):
+            def mro(self):
+                return [self, int]
+        class C(int):
+            __metaclass__ = X
+        C()    # the lookup of '__new__' succeeds in 'int',
+               # but the lookup of '__init__' fails
+
 
 class AppTestWithMethodCacheCounter:
     spaceconfig = {"objspace.std.withmethodcachecounter": True}
diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py
--- a/pypy/objspace/std/typeobject.py
+++ b/pypy/objspace/std/typeobject.py
@@ -618,6 +618,9 @@
             w_newfunc = None
         if w_newfunc is None:
             w_newtype, w_newdescr = self.lookup_where('__new__')
+            if w_newdescr is None:    # see test_crash_mro_without_object_1
+                raise oefmt(space.w_TypeError, "cannot create '%N' instances",
+                            self)
             w_newfunc = space.get(w_newdescr, self)
             if (space.config.objspace.std.newshortcut and
                 not we_are_jitted() and
@@ -630,9 +633,12 @@
         if (call_init and not (space.is_w(self, space.w_type) and
             not __args__.keywords and len(__args__.arguments_w) == 1)):
             w_descr = space.lookup(w_newobject, '__init__')
-            w_result = space.get_and_call_args(w_descr, w_newobject, __args__)
-            if not space.is_w(w_result, space.w_None):
-                raise oefmt(space.w_TypeError, "__init__() should return None")
+            if w_descr is not None:    # see test_crash_mro_without_object_2
+                w_result = space.get_and_call_args(w_descr, w_newobject,
+                                                   __args__)
+                if not space.is_w(w_result, space.w_None):
+                    raise oefmt(space.w_TypeError,
+                                "__init__() should return None")
         return w_newobject
 
     def descr_repr(self, space):
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to