gh-109653: typing.py: improve import time by creating soft-deprecated members on demand (#109651)

Co-authored-by: Thomas Grainger <tagrain@gmail.com>
This commit is contained in:
Alex Waygood 2023-09-23 08:46:35 +01:00 committed by GitHub
parent 62c7015e89
commit e8be0c9c5a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 8 deletions

View file

@ -9373,6 +9373,10 @@ class AllTests(BaseTestCase):
self.assertIn('SupportsComplex', a) self.assertIn('SupportsComplex', a)
def test_all_exported_names(self): def test_all_exported_names(self):
# ensure all dynamically created objects are actualised
for name in typing.__all__:
getattr(typing, name)
actual_all = set(typing.__all__) actual_all = set(typing.__all__)
computed_all = { computed_all = {
k for k, v in vars(typing).items() k for k, v in vars(typing).items()

View file

@ -23,10 +23,8 @@ import collections
from collections import defaultdict from collections import defaultdict
import collections.abc import collections.abc
import copyreg import copyreg
import contextlib
import functools import functools
import operator import operator
import re as stdlib_re # Avoid confusion with the typing.re namespace on <=3.11
import sys import sys
import types import types
from types import WrapperDescriptorType, MethodWrapperType, MethodDescriptorType, GenericAlias from types import WrapperDescriptorType, MethodWrapperType, MethodDescriptorType, GenericAlias
@ -2580,8 +2578,6 @@ MappingView = _alias(collections.abc.MappingView, 1)
KeysView = _alias(collections.abc.KeysView, 1) KeysView = _alias(collections.abc.KeysView, 1)
ItemsView = _alias(collections.abc.ItemsView, 2) ItemsView = _alias(collections.abc.ItemsView, 2)
ValuesView = _alias(collections.abc.ValuesView, 1) ValuesView = _alias(collections.abc.ValuesView, 1)
ContextManager = _alias(contextlib.AbstractContextManager, 1, name='ContextManager')
AsyncContextManager = _alias(contextlib.AbstractAsyncContextManager, 1, name='AsyncContextManager')
Dict = _alias(dict, 2, inst=False, name='Dict') Dict = _alias(dict, 2, inst=False, name='Dict')
DefaultDict = _alias(collections.defaultdict, 2, name='DefaultDict') DefaultDict = _alias(collections.defaultdict, 2, name='DefaultDict')
OrderedDict = _alias(collections.OrderedDict, 2) OrderedDict = _alias(collections.OrderedDict, 2)
@ -3238,10 +3234,6 @@ class TextIO(IO[str]):
pass pass
Pattern = _alias(stdlib_re.Pattern, 1)
Match = _alias(stdlib_re.Match, 1)
def reveal_type[T](obj: T, /) -> T: def reveal_type[T](obj: T, /) -> T:
"""Reveal the inferred type of a variable. """Reveal the inferred type of a variable.
@ -3426,3 +3418,21 @@ def get_protocol_members(tp: type, /) -> frozenset[str]:
if not is_protocol(tp): if not is_protocol(tp):
raise TypeError(f'{tp!r} is not a Protocol') raise TypeError(f'{tp!r} is not a Protocol')
return frozenset(tp.__protocol_attrs__) return frozenset(tp.__protocol_attrs__)
def __getattr__(attr):
"""Improve the import time of the typing module.
Soft-deprecated objects which are costly to create
are only created on-demand here.
"""
if attr in {"Pattern", "Match"}:
import re
obj = _alias(getattr(re, attr), 1)
elif attr in {"ContextManager", "AsyncContextManager"}:
import contextlib
obj = _alias(getattr(contextlib, f"Abstract{attr}"), 1, name=attr)
else:
raise AttributeError(f"module {__name__!r} has no attribute {attr!r}")
globals()[attr] = obj
return obj

View file

@ -0,0 +1,2 @@
Reduce the import time of :mod:`typing` by around a third.
Patch by Alex Waygood.