]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-99275: Fix `SystemError` in `ctypes` during `__initsubclass__` (#99283)
authorNikita Sobolev <mail@sobolevn.me>
Sun, 13 Nov 2022 19:22:45 +0000 (22:22 +0300)
committerGitHub <noreply@github.com>
Sun, 13 Nov 2022 19:22:45 +0000 (11:22 -0800)
Lib/test/test_ctypes/test_struct_fields.py
Misc/NEWS.d/next/Library/2022-11-09-12-16-35.gh-issue-99275.klOqoL.rst [new file with mode: 0644]
Modules/_ctypes/stgdict.c

index ee8415f3e630c29d08f6188a5b9e2085011f3b18..fefeaea1496a3e8f35bf384cb35683840fe83031 100644 (file)
@@ -54,6 +54,15 @@ class StructFieldsTestCase(unittest.TestCase):
         x.char = b'a\0b\0'
         self.assertEqual(bytes(x), b'a\x00###')
 
+    def test_gh99275(self):
+        class BrokenStructure(Structure):
+            def __init_subclass__(cls, **kwargs):
+                cls._fields_ = []  # This line will fail, `stgdict` is not ready
+
+        with self.assertRaisesRegex(TypeError,
+                                    'ctypes state is not initialized'):
+            class Subclass(BrokenStructure): ...
+
     # __set__ and __get__ should raise a TypeError in case their self
     # argument is not a ctype instance.
     def test___set__(self):
diff --git a/Misc/NEWS.d/next/Library/2022-11-09-12-16-35.gh-issue-99275.klOqoL.rst b/Misc/NEWS.d/next/Library/2022-11-09-12-16-35.gh-issue-99275.klOqoL.rst
new file mode 100644 (file)
index 0000000..2bf05a3
--- /dev/null
@@ -0,0 +1,2 @@
+Fix ``SystemError`` in :mod:`ctypes` when exception was not set during
+``__initsubclass__``.
index 1c69a290ee22e6ca97f7b416ea7aa5f952b54f6f..9f031b0f4b0feed845fd17bd8fdd05e0bebb2bd7 100644 (file)
@@ -424,8 +424,11 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct
     }
 
     stgdict = PyType_stgdict(type);
-    if (!stgdict)
+    if (!stgdict) {
+        PyErr_SetString(PyExc_TypeError,
+                        "ctypes state is not initialized");
         return -1;
+    }
     /* If this structure/union is already marked final we cannot assign
        _fields_ anymore. */