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

Co-authored-by: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com>
This commit is contained in:
Yurii Karabas 2021-07-29 22:44:48 +03:00 committed by GitHub
parent 6b61d74a3b
commit 8182c8329c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 1 deletions

View File

@ -3015,6 +3015,16 @@ class GetTypeHintTests(BaseTestCase):
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):

View File

@ -0,0 +1,3 @@
Add ``__module__`` to ``types.Union``. This also fixes
``types.Union`` issues with ``typing.Annotated``. Patch provided by
Yurii Karabas.

View File

@ -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,