]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-118895: Call PyType_Ready() on typing.NoDefault (#118897)
authorJelle Zijlstra <jelle.zijlstra@gmail.com>
Fri, 10 May 2024 15:42:00 +0000 (08:42 -0700)
committerGitHub <noreply@github.com>
Fri, 10 May 2024 15:42:00 +0000 (08:42 -0700)
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 8dde8aedd2a2b164b8bd8543e0fd701d17ec3427..81fea41e9b9823af3301410e50d406f2a61d3528 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
 
 
@@ -10236,15 +10236,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;
     }