Docs: Add a recipe for robust runtime introspection (#225)
diff --git a/doc/index.rst b/doc/index.rst index 177f8a1..f076ae3 100644 --- a/doc/index.rst +++ b/doc/index.rst
@@ -73,6 +73,57 @@ attributes directly. If some information is not available through a public attribute, consider opening an issue in CPython to add such an API. +Here is an example recipe for a general-purpose function that could be used for +reasonably performant runtime introspection of typing objects. The function +will be resilient against any potential changes in ``typing_extensions`` that +alter whether an object is reimplemented in ``typing_extensions``, rather than +simply being re-exported from the :mod:`typing` module:: + + import functools + import typing + import typing_extensions + from typing import Tuple, Any + + # Use an unbounded cache for this function, for optimal performance + @functools.lru_cache(maxsize=None) + def get_typing_objects_by_name_of(name: str) -> Tuple[Any, ...]: + result = tuple( + getattr(module, name) + # You could potentially also include mypy_extensions here, + # if your library supports mypy_extensions + for module in (typing, typing_extensions) + if hasattr(module, name) + ) + if not result: + raise ValueError( + f"Neither typing nor typing_extensions has an object called {name!r}" + ) + return result + + + # Use a cache here as well, but make it a bounded cache + # (the default cache size is 128) + @functools.lru_cache() + def is_typing_name(obj: object, name: str) -> bool: + return any(obj is thing for thing in get_typing_objects_by_name_of(name)) + +Example usage:: + + >>> import typing, typing_extensions + >>> from functools import partial + >>> from typing_extensions import get_origin + >>> is_literal = partial(is_typing_name, name="Literal") + >>> is_literal(typing.Literal) + True + >>> is_literal(typing_extensions.Literal) + True + >>> is_literal(typing.Any) + False + >>> is_literal(get_origin(typing.Literal[42])) + True + >>> is_literal(get_origin(typing_extensions.Final[42])) + False + Python version support ----------------------