Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-44524: Add missed __name__ and __qualname__ to typing module objects #27237

Merged
merged 6 commits into from Jul 19, 2021
Merged
@@ -4498,6 +4498,67 @@ def test_no_isinstance(self):
issubclass(int, TypeGuard)


class SpecialAttrsTests(BaseTestCase):
def test_special_attrs(self):
cls_to_check = (
# ABC classes
typing.AbstractSet,
typing.AsyncContextManager,
typing.AsyncGenerator,
typing.AsyncIterable,
typing.AsyncIterator,
typing.Awaitable,
typing.ByteString,
typing.Callable,
typing.ChainMap,
typing.Collection,
typing.Container,
typing.ContextManager,
typing.Coroutine,
typing.Counter,
typing.DefaultDict,
typing.Deque,
typing.Dict,
typing.FrozenSet,
typing.Generator,
typing.Hashable,
typing.ItemsView,
typing.Iterable,
typing.Iterator,
typing.KeysView,
typing.List,
typing.Mapping,
typing.MappingView,
typing.MutableMapping,
typing.MutableSequence,
typing.MutableSet,
typing.OrderedDict,
typing.Reversible,
typing.Sequence,
typing.Set,
typing.Sized,
typing.Tuple,
typing.Type,
typing.ValuesView,
# Special Forms
typing.Any,
typing.NoReturn,
typing.ClassVar,
typing.Final,
typing.Union,
typing.Optional,
typing.Literal,
typing.TypeAlias,
typing.Concatenate,
typing.TypeGuard,
)

for cls in cls_to_check:
This conversation was marked as resolved by uriyyo

This comment has been minimized.

@Fidget-Spinner

Fidget-Spinner Jul 19, 2021
Contributor

Please use unittest.subTest here https://docs.python.org/3/library/unittest.html#subtests. In case we break multiple types at once.

This comment has been minimized.

@uriyyo

uriyyo Jul 19, 2021
Author Member

Fixed, thanks)

with self.subTest(cls=cls):
self.assertEqual(cls.__name__, cls._name)
self.assertEqual(cls.__qualname__, cls._name)
self.assertEqual(cls.__module__, 'typing')

class AllTests(BaseTestCase):
"""Tests for __all__."""

@@ -358,6 +358,12 @@ def __init__(self, getitem):
self._name = getitem.__name__
self.__doc__ = getitem.__doc__

def __getattr__(self, item):
if item in {'__name__', '__qualname__'}:
return self._name

raise AttributeError(item)

def __mro_entries__(self, bases):
raise TypeError(f"Cannot subclass {self!r}")

@@ -935,6 +941,9 @@ def __mro_entries__(self, bases):
return tuple(res)

def __getattr__(self, attr):
if attr in {'__name__', '__qualname__'}:
return self._name
This conversation was marked as resolved by uriyyo

This comment has been minimized.

@ambv

ambv Jul 19, 2021
Contributor

You can't use _name in both. __name__ should be the simple name whereas __qualname__ should include a "typing." prefix, just like Guido requested on the issue.

This comment has been minimized.

@uriyyo

uriyyo Jul 19, 2021
Author Member

Thanks, fixed.

I am curios about why we should include typing. prefix at __qualname__?

From what I saw __qualname__ does not include module name but rather include path to object at scope of module:

class A:
    pass

    class B:
        pass

        class C:
            pass


print(A.__qualname__)
print(A.B.__qualname__)
print(A.B.C.__qualname__)
A
A.B
A.B.C

# We are careful for copy and pickle.
# Also for simplicity we just don't relay all dunder names
if '__origin__' in self.__dict__ and not _is_dunder(attr):
@@ -0,0 +1,2 @@
Add missing ``__name__`` and ``__qualname__`` attributes to ``typing`` module
classes. Patch provided by Yurii Karabas.