[Python-checkins] bpo-44662: Add ability to annotate types.Union (GH-27214) (GH-27461)

ambv webhook-mailer at python.org
Fri Jul 30 05:32:04 EDT 2021


https://github.com/python/cpython/commit/472997659b9c73089cdc22bd7eded6f6fdcffdfe
commit: 472997659b9c73089cdc22bd7eded6f6fdcffdfe
branch: 3.10
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: ambv <lukasz at langa.pl>
date: 2021-07-30T11:31:54+02:00
summary:

bpo-44662: Add ability to annotate types.Union (GH-27214) (GH-27461)

Co-authored-by: Ken Jin <28750310+Fidget-Spinner at users.noreply.github.com>
(cherry picked from commit 8182c8329c709f42218a8a17d81639ece5b7b627)

Co-authored-by: Yurii Karabas <1998uriyyo at gmail.com>

files:
A Misc/NEWS.d/next/Core and Builtins/2021-07-17-13-41-58.bpo-44662.q22kWR.rst
M Lib/test/test_typing.py
M Objects/unionobject.c

diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index f79675b4bdf9be..bbda6aa2f13b50 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -3009,6 +3009,16 @@ def barfoo3(x: BA2): ...
             get_type_hints(barfoo3, globals(), locals(), include_extras=True)["x"],
             BA2
         )
+        BA3 = typing.Annotated[int | float, "const"]
+        def barfoo4(x: BA3): ...
+        self.assertEqual(
+            get_type_hints(barfoo4, globals(), locals()),
+            {"x": int | float}
+        )
+        self.assertEqual(
+            get_type_hints(barfoo4, globals(), locals(), include_extras=True),
+            {"x": typing.Annotated[int | float, "const"]}
+        )
 
     def test_get_type_hints_annotated_refs(self):
 
diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-07-17-13-41-58.bpo-44662.q22kWR.rst b/Misc/NEWS.d/next/Core and Builtins/2021-07-17-13-41-58.bpo-44662.q22kWR.rst
new file mode 100644
index 00000000000000..c165774a4cacfb
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2021-07-17-13-41-58.bpo-44662.q22kWR.rst	
@@ -0,0 +1,3 @@
+Add ``__module__`` to ``types.Union``. This also fixes
+``types.Union`` issues with ``typing.Annotated``. Patch provided by
+Yurii Karabas.
diff --git a/Objects/unionobject.c b/Objects/unionobject.c
index 9e670b47b7e634..80c70389ab30d6 100644
--- a/Objects/unionobject.c
+++ b/Objects/unionobject.c
@@ -422,6 +422,28 @@ static PyNumberMethods union_as_number = {
         .nb_or = _Py_union_type_or, // Add __or__ function
 };
 
+static const char* const cls_attrs[] = {
+        "__module__",  // Required for compatibility with typing module
+        NULL,
+};
+
+static PyObject *
+union_getattro(PyObject *self, PyObject *name)
+{
+    unionobject *alias = (unionobject *)self;
+    if (PyUnicode_Check(name)) {
+        for (const char * const *p = cls_attrs; ; p++) {
+            if (*p == NULL) {
+                break;
+            }
+            if (_PyUnicode_EqualToASCIIString(name, *p)) {
+                return PyObject_GetAttr((PyObject *) Py_TYPE(alias), name);
+            }
+        }
+    }
+    return PyObject_GenericGetAttr(self, name);
+}
+
 PyTypeObject _PyUnion_Type = {
     PyVarObject_HEAD_INIT(&PyType_Type, 0)
     .tp_name = "types.UnionType",
@@ -435,7 +457,7 @@ PyTypeObject _PyUnion_Type = {
     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
     .tp_traverse = union_traverse,
     .tp_hash = union_hash,
-    .tp_getattro = PyObject_GenericGetAttr,
+    .tp_getattro = union_getattro,
     .tp_members = union_members,
     .tp_methods = union_methods,
     .tp_richcompare = union_richcompare,



More information about the Python-checkins mailing list