summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Waygood <Alex.Waygood@Gmail.com>2023-09-23 07:46:35 (GMT)
committerGitHub <noreply@github.com>2023-09-23 07:46:35 (GMT)
commite8be0c9c5a7c2327b3dd64009f45ee0682322dcb (patch)
tree250854f1b2ae6587fdeb344dd24ea1022da0d159
parent62c7015e89cbdedb5218d4fedd45f971885f67a8 (diff)
downloadcpython-e8be0c9c5a7c2327b3dd64009f45ee0682322dcb.zip
cpython-e8be0c9c5a7c2327b3dd64009f45ee0682322dcb.tar.gz
cpython-e8be0c9c5a7c2327b3dd64009f45ee0682322dcb.tar.bz2
gh-109653: `typing.py`: improve import time by creating soft-deprecated members on demand (#109651)
Co-authored-by: Thomas Grainger <tagrain@gmail.com>
-rw-r--r--Lib/test/test_typing.py4
-rw-r--r--Lib/typing.py26
-rw-r--r--Misc/NEWS.d/next/Library/2023-09-21-19-42-22.gh-issue-109653.bL3iLH.rst2
3 files changed, 24 insertions, 8 deletions
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index 4d1c0f2..9e891f1 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -9373,6 +9373,10 @@ class AllTests(BaseTestCase):
self.assertIn('SupportsComplex', a)
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__)
computed_all = {
k for k, v in vars(typing).items()
diff --git a/Lib/typing.py b/Lib/typing.py
index 183d5b2..639be75 100644
--- a/Lib/typing.py
+++ b/Lib/typing.py
@@ -23,10 +23,8 @@ import collections
from collections import defaultdict
import collections.abc
import copyreg
-import contextlib
import functools
import operator
-import re as stdlib_re # Avoid confusion with the typing.re namespace on <=3.11
import sys
import types
from types import WrapperDescriptorType, MethodWrapperType, MethodDescriptorType, GenericAlias
@@ -2580,8 +2578,6 @@ MappingView = _alias(collections.abc.MappingView, 1)
KeysView = _alias(collections.abc.KeysView, 1)
ItemsView = _alias(collections.abc.ItemsView, 2)
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')
DefaultDict = _alias(collections.defaultdict, 2, name='DefaultDict')
OrderedDict = _alias(collections.OrderedDict, 2)
@@ -3238,10 +3234,6 @@ class TextIO(IO[str]):
pass
-Pattern = _alias(stdlib_re.Pattern, 1)
-Match = _alias(stdlib_re.Match, 1)
-
-
def reveal_type[T](obj: T, /) -> T:
"""Reveal the inferred type of a variable.
@@ -3426,3 +3418,21 @@ def get_protocol_members(tp: type, /) -> frozenset[str]:
if not is_protocol(tp):
raise TypeError(f'{tp!r} is not a Protocol')
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
diff --git a/Misc/NEWS.d/next/Library/2023-09-21-19-42-22.gh-issue-109653.bL3iLH.rst b/Misc/NEWS.d/next/Library/2023-09-21-19-42-22.gh-issue-109653.bL3iLH.rst
new file mode 100644
index 0000000..9f794bb
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-09-21-19-42-22.gh-issue-109653.bL3iLH.rst
@@ -0,0 +1,2 @@
+Reduce the import time of :mod:`typing` by around a third.
+Patch by Alex Waygood.