@@ -73,6 +73,57 @@ the risk of compatibility issues:
73
73
attributes directly. If some information is not available through a public
74
74
attribute, consider opening an issue in CPython to add such an API.
75
75
76
+ Here is an example recipe for a general-purpose function that could be used for
77
+ reasonably performant runtime introspection of typing objects. The function
78
+ will be resilient against any potential changes in ``typing_extensions `` that
79
+ alter whether an object is reimplemented in ``typing_extensions ``, rather than
80
+ simply being re-exported from the :mod: `typing ` module::
81
+
82
+ import functools
83
+ import typing
84
+ import typing_extensions
85
+ from typing import Tuple, Any
86
+
87
+ # Use an unbounded cache for this function, for optimal performance
88
+ @functools.lru_cache(maxsize=None)
89
+ def get_typing_objects_by_name_of(name: str) -> Tuple[Any, ...]:
90
+ result = tuple(
91
+ getattr(module, name)
92
+ # You could potentially also include mypy_extensions here,
93
+ # if your library supports mypy_extensions
94
+ for module in (typing, typing_extensions)
95
+ if hasattr(module, name)
96
+ )
97
+ if not result:
98
+ raise ValueError(
99
+ f"Neither typing nor typing_extensions has an object called {name!r}"
100
+ )
101
+ return result
102
+
103
+
104
+ # Use a cache here as well, but make it a bounded cache
105
+ # (the default cache size is 128)
106
+ @functools.lru_cache()
107
+ def is_typing_name(obj: object, name: str) -> bool:
108
+ return any(obj is thing for thing in get_typing_objects_by_name_of(name))
109
+
110
+ Example usage::
111
+
112
+ >>> import typing, typing_extensions
113
+ >>> from functools import partial
114
+ >>> from typing_extensions import get_origin
115
+ >>> is_literal = partial(is_typing_name, name="Literal")
116
+ >>> is_literal(typing.Literal)
117
+ True
118
+ >>> is_literal(typing_extensions.Literal)
119
+ True
120
+ >>> is_literal(typing.Any)
121
+ False
122
+ >>> is_literal(get_origin(typing.Literal[42]))
123
+ True
124
+ >>> is_literal(get_origin(typing_extensions.Final[42]))
125
+ False
126
+
76
127
Python version support
77
128
----------------------
78
129
0 commit comments