[pypy-svn] r59530 - in pypy/trunk/pypy/objspace/std: . test

arigo at codespeak.net arigo at codespeak.net
Thu Oct 30 10:54:47 CET 2008


Author: arigo
Date: Thu Oct 30 10:54:46 2008
New Revision: 59530

Modified:
   pypy/trunk/pypy/objspace/std/test/test_typeobject.py
   pypy/trunk/pypy/objspace/std/typeobject.py
Log:
Minimal checking for the return value of a custom mro() method.


Modified: pypy/trunk/pypy/objspace/std/test/test_typeobject.py
==============================================================================
--- pypy/trunk/pypy/objspace/std/test/test_typeobject.py	(original)
+++ pypy/trunk/pypy/objspace/std/test/test_typeobject.py	Thu Oct 30 10:54:46 2008
@@ -901,3 +901,18 @@
         raises(TypeError, setattr, list, 'foobar', 42)
         raises(TypeError, delattr, dict, 'keys')
         
+    def test_nontype_in_mro(self):
+        class OldStyle:
+            pass
+        class X(object):
+            pass
+
+        class mymeta1(type):
+            def mro(self):
+                return [self, OldStyle, object]
+        mymeta1("Foo1", (object,), {})      # works
+
+        class mymeta2(type):
+            def mro(self):
+                return [self, X(), object]
+        raises(TypeError, mymeta2, "Foo", (object,), {})

Modified: pypy/trunk/pypy/objspace/std/typeobject.py
==============================================================================
--- pypy/trunk/pypy/objspace/std/typeobject.py	(original)
+++ pypy/trunk/pypy/objspace/std/typeobject.py	Thu Oct 30 10:54:46 2008
@@ -545,11 +545,21 @@
         if not space.is_w(w_where, space.w_type):
             w_mro_meth = space.get(w_mro_func, w_self)
             w_mro = space.call_function(w_mro_meth)
-            w_self.mro_w = space.viewiterable(w_mro)
-            # do some checking here
+            mro_w = space.viewiterable(w_mro)
+            w_self.mro_w = validate_custom_mro(space, mro_w)
             return    # done
     w_self.mro_w = w_self.compute_default_mro()[:]
 
+def validate_custom_mro(space, mro_w):
+    # do some checking here.  Note that unlike CPython, strange MROs
+    # cannot really segfault PyPy.  At a minimum, we check that all
+    # the elements in the mro seem to be (old- or new-style) classes.
+    for w_class in mro_w:
+        if not space.abstract_isclass_w(w_class):
+            raise OperationError(space.w_TypeError,
+                                 space.wrap("mro() returned a non-class"))
+    return mro_w
+
 # ____________________________________________________________
 
 def call__Type(space, w_type, __args__):



More information about the Pypy-commit mailing list