Author: Ronan Lamy <[email protected]>
Branch: py3.6
Changeset: r97343:5c433fa743eb
Date: 2019-08-30 16:33 +0100
http://bitbucket.org/pypy/pypy/changeset/5c433fa743eb/

Log:    Check return type of __prepare__() (bpo-31588)

diff --git a/pypy/module/__builtin__/compiling.py 
b/pypy/module/__builtin__/compiling.py
--- a/pypy/module/__builtin__/compiling.py
+++ b/pypy/module/__builtin__/compiling.py
@@ -130,6 +130,16 @@
                          keywords=keywords,
                          keywords_w=kwds_w.values())
         w_namespace = space.call_args(w_prep, args)
+    if not space.ismapping_w(w_namespace):
+        if isclass:
+            raise oefmt(space.w_TypeError,
+                "%N.__prepare__ must return a mapping, not %T",
+                w_meta, w_namespace)
+        else:
+            raise oefmt(space.w_TypeError,
+                "<metaclass>.__prepare__ must return a mapping, not %T",
+                w_namespace)
+
     code = w_func.getcode()
     frame = space.createframe(code, w_func.w_func_globals, w_func)
     frame.setdictscope(w_namespace)
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
@@ -1277,6 +1277,23 @@
         assert C.foo == 42
         """
 
+    def test_prepare_error(self):
+        """
+        class BadMeta:
+            @classmethod
+            def __prepare__(cls, *args, **kwargs):
+                return 42
+        def make_class(meta):
+            class Foo(metaclass=meta):
+                pass
+        excinfo = raises(TypeError, make_class, BadMeta)
+        print(excinfo.value.args[0])
+        assert excinfo.value.args[0].startswith('BadMeta.__prepare__')
+        # Non-type as metaclass
+        excinfo = raises(TypeError, make_class, BadMeta())
+        assert excinfo.value.args[0].startswith('<metaclass>.__prepare__')
+        """
+
     def test_crash_mro_without_object_1(self):
         """
         class X(type):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to