]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-118895: Call PyType_Ready() on typing.NoDefault (GH-118897) (#118914)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Fri, 10 May 2024 16:36:33 +0000 (18:36 +0200)
committerGitHub <noreply@github.com>
Fri, 10 May 2024 16:36:33 +0000 (16:36 +0000)
(cherry picked from commit 13d7cf997bc9c22cf67c42fd799413e8325e0039)

Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Include/internal/pycore_typevarobject.h
Lib/test/test_typing.py
Misc/NEWS.d/next/Library/2024-05-10-05-24-32.gh-issue-118895.wUm5r2.rst [new file with mode: 0644]
Modules/_typingmodule.c

index 80a2daf4efc16a2b9df9d15f724cd497a8e8c9d9..a368edebd622a163b3bc9de07bff1e219fd85d29 100644 (file)
@@ -18,6 +18,7 @@ extern int _Py_initialize_generic(PyInterpreterState *);
 extern void _Py_clear_generic_types(PyInterpreterState *);
 
 extern PyTypeObject _PyTypeAlias_Type;
+extern PyTypeObject _PyNoDefault_Type;
 extern PyObject _Py_NoDefaultStruct;
 
 #ifdef __cplusplus
index fff81f7997764d585b9d203ce5c05e3163746e2d..f6fe95321babd7bbf489800e625c61d26f6a5b92 100644 (file)
@@ -45,7 +45,7 @@ import typing
 import weakref
 import types
 
-from test.support import captured_stderr, cpython_only, infinite_recursion
+from test.support import captured_stderr, cpython_only, infinite_recursion, requires_docstrings
 from test.typinganndata import ann_module695, mod_generics_cache, _typed_dict_helper
 
 
@@ -10247,15 +10247,34 @@ class NoDefaultTests(BaseTestCase):
     def test_constructor(self):
         self.assertIs(NoDefault, type(NoDefault)())
         with self.assertRaises(TypeError):
-            NoDefault(1)
+            type(NoDefault)(1)
 
     def test_repr(self):
         self.assertEqual(repr(NoDefault), 'typing.NoDefault')
 
+    @requires_docstrings
+    def test_doc(self):
+        self.assertIsInstance(NoDefault.__doc__, str)
+
+    def test_class(self):
+        self.assertIs(NoDefault.__class__, type(NoDefault))
+
     def test_no_call(self):
         with self.assertRaises(TypeError):
             NoDefault()
 
+    def test_no_attributes(self):
+        with self.assertRaises(AttributeError):
+            NoDefault.foo = 3
+        with self.assertRaises(AttributeError):
+            NoDefault.foo
+
+        # TypeError is consistent with the behavior of NoneType
+        with self.assertRaises(TypeError):
+            type(NoDefault).foo = 3
+        with self.assertRaises(AttributeError):
+            type(NoDefault).foo
+
 
 class AllTests(BaseTestCase):
     """Tests for __all__."""
diff --git a/Misc/NEWS.d/next/Library/2024-05-10-05-24-32.gh-issue-118895.wUm5r2.rst b/Misc/NEWS.d/next/Library/2024-05-10-05-24-32.gh-issue-118895.wUm5r2.rst
new file mode 100644 (file)
index 0000000..226c8d6
--- /dev/null
@@ -0,0 +1,2 @@
+Setting attributes on :data:`typing.NoDefault` now raises
+:exc:`AttributeError` instead of :exc:`TypeError`.
index 09fbb3c5e8b91d790a6e7a0c29195f919a6b865e..37af00f3071e1d51627f859d4f6bb40484097596 100644 (file)
@@ -63,6 +63,9 @@ _typing_exec(PyObject *m)
     if (PyModule_AddObjectRef(m, "TypeAliasType", (PyObject *)&_PyTypeAlias_Type) < 0) {
         return -1;
     }
+    if (PyType_Ready(&_PyNoDefault_Type) < 0) {
+        return -1;
+    }
     if (PyModule_AddObjectRef(m, "NoDefault", (PyObject *)&_Py_NoDefaultStruct) < 0) {
         return -1;
     }