diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2017-09-27 16:21:33 (GMT) |
---|---|---|
committer | Nick Coghlan <ncoghlan@gmail.com> | 2017-09-27 16:21:33 (GMT) |
commit | 084f80b82c564c8a3cef26fc6e56da188a379be2 (patch) | |
tree | 8cb66ebd9f41cb413dee48731c61a1fd37df8110 /Lib/test | |
parent | fdcf3e9629201ef725af629d99e02215a2d657c8 (diff) | |
download | cpython-084f80b82c564c8a3cef26fc6e56da188a379be2.zip cpython-084f80b82c564c8a3cef26fc6e56da188a379be2.tar.gz cpython-084f80b82c564c8a3cef26fc6e56da188a379be2.tar.bz2 |
[3.6] bpo-31588: Validate return value of __prepare__() methods (GH-3790)
Class execution requires that __prepare__() methods return
a proper execution namespace. Check for that immediately
after calling __prepare__(), rather than passing it through
to the code execution machinery and potentially triggering
SystemError (in debug builds) or a cryptic TypeError
(in release builds).
Patch by Oren Milman.
(cherry picked from commit 5837d0418f47933b2e3c139bdee8a79c248a943c)
Diffstat (limited to 'Lib/test')
-rw-r--r-- | Lib/test/test_types.py | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index 382ca03..d79429f 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -846,6 +846,28 @@ class ClassCreationTests(unittest.TestCase): self.assertIs(ns, expected_ns) self.assertEqual(len(kwds), 0) + def test_bad___prepare__(self): + # __prepare__() must return a mapping. + class BadMeta(type): + @classmethod + def __prepare__(*args): + return None + with self.assertRaisesRegex(TypeError, + r'^BadMeta\.__prepare__\(\) must ' + r'return a mapping, not NoneType$'): + class Foo(metaclass=BadMeta): + pass + # Also test the case in which the metaclass is not a type. + class BadMeta: + @classmethod + def __prepare__(*args): + return None + with self.assertRaisesRegex(TypeError, + r'^<metaclass>\.__prepare__\(\) must ' + r'return a mapping, not NoneType$'): + class Bar(metaclass=BadMeta()): + pass + def test_metaclass_derivation(self): # issue1294232: correct metaclass calculation new_calls = [] # to check the order of __new__ calls |