mirror of https://github.com/python/cpython
gh-55664: Add warning when creating a type using a namespace dictionary with non-string keys. (GH-105338)
Co-authored-by: Daniel Urban <durban@users.noreply.github.com>
This commit is contained in:
parent
3bb6912d88
commit
f7c05d7ad3
|
@ -4734,6 +4734,20 @@ class ClassPropertiesAndMethods(unittest.TestCase):
|
||||||
with self.assertRaises(AttributeError):
|
with self.assertRaises(AttributeError):
|
||||||
del X.__abstractmethods__
|
del X.__abstractmethods__
|
||||||
|
|
||||||
|
def test_gh55664(self):
|
||||||
|
# gh-55664: issue a warning when the
|
||||||
|
# __dict__ of a class contains non-string keys
|
||||||
|
with self.assertWarnsRegex(RuntimeWarning, 'MyClass'):
|
||||||
|
MyClass = type('MyClass', (), {1: 2})
|
||||||
|
|
||||||
|
class meta(type):
|
||||||
|
def __new__(mcls, name, bases, ns):
|
||||||
|
ns[1] = 2
|
||||||
|
return super().__new__(mcls, name, bases, ns)
|
||||||
|
|
||||||
|
with self.assertWarnsRegex(RuntimeWarning, 'MyClass'):
|
||||||
|
MyClass = meta('MyClass', (), {})
|
||||||
|
|
||||||
def test_proxy_call(self):
|
def test_proxy_call(self):
|
||||||
class FakeStr:
|
class FakeStr:
|
||||||
__class__ = str
|
__class__ = str
|
||||||
|
@ -5151,7 +5165,8 @@ class MiscTests(unittest.TestCase):
|
||||||
mykey = 'from Base2'
|
mykey = 'from Base2'
|
||||||
mykey2 = 'from Base2'
|
mykey2 = 'from Base2'
|
||||||
|
|
||||||
X = type('X', (Base,), {MyKey(): 5})
|
with self.assertWarnsRegex(RuntimeWarning, 'X'):
|
||||||
|
X = type('X', (Base,), {MyKey(): 5})
|
||||||
# mykey is read from Base
|
# mykey is read from Base
|
||||||
self.assertEqual(X.mykey, 'from Base')
|
self.assertEqual(X.mykey, 'from Base')
|
||||||
# mykey2 is read from Base2 because MyKey.__eq__ has set __bases__
|
# mykey2 is read from Base2 because MyKey.__eq__ has set __bases__
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Add warning when creating :class:`type` using a namespace dictionary with non-string keys. Patched by Daniel Urban and Furkan Onder.
|
|
@ -3828,6 +3828,17 @@ type_new_impl(type_new_ctx *ctx)
|
||||||
// Put the proper slots in place
|
// Put the proper slots in place
|
||||||
fixup_slot_dispatchers(type);
|
fixup_slot_dispatchers(type);
|
||||||
|
|
||||||
|
if (!_PyDict_HasOnlyStringKeys(type->tp_dict)) {
|
||||||
|
if (PyErr_WarnFormat(
|
||||||
|
PyExc_RuntimeWarning,
|
||||||
|
1,
|
||||||
|
"non-string key in the __dict__ of class %.200s",
|
||||||
|
type->tp_name) == -1)
|
||||||
|
{
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (type_new_set_names(type) < 0) {
|
if (type_new_set_names(type) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue