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