]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-55664: Add warning when creating a type using a namespace dictionary with non...
authorFurkan Onder <furkanonder@protonmail.com>
Sun, 28 Jan 2024 23:05:29 +0000 (02:05 +0300)
committerGitHub <noreply@github.com>
Sun, 28 Jan 2024 23:05:29 +0000 (01:05 +0200)
Co-authored-by: Daniel Urban <durban@users.noreply.github.com>
Lib/test/test_descr.py
Misc/NEWS.d/next/Core and Builtins/2023-06-06-19-09-00.gh-issue-55664.vYYl0V.rst [new file with mode: 0644]
Objects/typeobject.c

index fd0af9b30a0a71a5672d1ab192d57f40b5507972..beeab6cb7f254c1e7d034684b7122cbbd8a294de 100644 (file)
@@ -4734,6 +4734,20 @@ class ClassPropertiesAndMethods(unittest.TestCase):
         with self.assertRaises(AttributeError):
             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):
         class FakeStr:
             __class__ = str
@@ -5151,7 +5165,8 @@ class MiscTests(unittest.TestCase):
             mykey = '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
         self.assertEqual(X.mykey, 'from Base')
         # mykey2 is read from Base2 because MyKey.__eq__ has set __bases__
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-06-19-09-00.gh-issue-55664.vYYl0V.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-06-19-09-00.gh-issue-55664.vYYl0V.rst
new file mode 100644 (file)
index 0000000..438be98
--- /dev/null
@@ -0,0 +1 @@
+Add warning when creating :class:`type` using a namespace dictionary with non-string keys. Patched by Daniel Urban and Furkan Onder.
index 114cf21f95e744bdcd9bae9cfb09c157c44f0d78..a850473cad813dde45782f16c9cba0296cfdbe29 100644 (file)
@@ -3828,6 +3828,17 @@ type_new_impl(type_new_ctx *ctx)
     // Put the proper slots in place
     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) {
         goto error;
     }