]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-132285: Fix that `__annotate__` is not deleted when `__annotations__` is deleted...
authorsobolevn <mail@sobolevn.me>
Wed, 9 Apr 2025 17:36:08 +0000 (20:36 +0300)
committerGitHub <noreply@github.com>
Wed, 9 Apr 2025 17:36:08 +0000 (10:36 -0700)
Lib/test/test_type_annotations.py
Misc/NEWS.d/next/Core_and_Builtins/2025-04-09-12-37-31.gh-issue-132286.1ZdsOa.rst [new file with mode: 0644]
Objects/typeobject.c

index 9c70d27d29e89cc802a44cea293fef5e79bf66c1..29e2c7a0cd837e27ae8e4dc241746e1053fbd777 100644 (file)
@@ -57,6 +57,26 @@ class TypeAnnotationTests(unittest.TestCase):
         del C.__annotations__
         self.assertFalse("__annotations__" in C.__dict__)
 
+    def test_del_annotations_and_annotate(self):
+        # gh-132285
+        called = False
+        class A:
+            def __annotate__(format):
+                nonlocal called
+                called = True
+                return {'a': int}
+
+        self.assertEqual(A.__annotations__, {'a': int})
+        self.assertTrue(called)
+        self.assertTrue(A.__annotate__)
+
+        del A.__annotations__
+        called = False
+
+        self.assertEqual(A.__annotations__, {})
+        self.assertFalse(called)
+        self.assertIs(A.__annotate__, None)
+
     def test_descriptor_still_works(self):
         class C:
             def __init__(self, name=None, bases=None, d=None):
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-04-09-12-37-31.gh-issue-132286.1ZdsOa.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-04-09-12-37-31.gh-issue-132286.1ZdsOa.rst
new file mode 100644 (file)
index 0000000..82dcbd3
--- /dev/null
@@ -0,0 +1,2 @@
+Fix that :attr:`type.__annotate__` was not deleted, when
+:attr:`type.__annotations__` was deleted.
index b92eaefc90d0afacfbc62f1ab4aceec98f2b5c12..75c23ddd91b1a1e9a07ec17812e75a160131ddd0 100644 (file)
@@ -2066,8 +2066,7 @@ type_set_annotations(PyObject *tp, PyObject *value, void *Py_UNUSED(closure))
     if (result < 0) {
         Py_DECREF(dict);
         return -1;
-    }
-    else if (result == 0) {
+    } else {  // result can be 0 or 1
         if (PyDict_Pop(dict, &_Py_ID(__annotate__), NULL) < 0) {
             PyType_Modified(type);
             Py_DECREF(dict);