eval-type-backport
Like `typing._eval_type`, this tiny package provides a replacement to support newer typing features (such as `X | Y` for unions from PEP 604 and `list[X]` for generic built-ins from PEP 585) in older Python versions (>=3.7). It allows libraries like Pydantic to maintain modern type hint syntax while supporting a wider range of Python environments. It is currently at version 0.3.1 and sees updates as needed for compatibility.
Warnings
- gotcha This library is primarily intended for use by other libraries (e.g., Pydantic) that need to evaluate type annotations at runtime for compatibility with modern Python typing features on older Python versions. Direct usage by end-user applications is generally rare unless you have a specific, advanced use case mirroring `typing._eval_type`.
- breaking If you are using modern type hint syntax (e.g., `X | Y` for unions, `list[X]` for generic built-ins) in a project targeting Python <3.10 or <3.9 respectively, you may encounter `TypeError` or `ImportError` at runtime. `eval-type-backport` provides the mechanism to resolve these types dynamically.
- gotcha While `eval-type-backport` provides a compatibility layer, the recommended long-term solution for leveraging modern Python typing features is to upgrade your Python interpreter. Python 3.9+ natively supports generic built-in types (e.g., `list[int]`), and Python 3.10+ natively supports the `X | Y` union syntax.
Install
-
pip install eval-type-backport
Imports
- eval_type_backport
from eval_type_backport import eval_type_backport
Quickstart
import sys
from __future__ import annotations
from eval_type_backport import eval_type_backport
class MyModel:
field: str | None
def demonstrate_eval(cls):
# Simulate a scenario where `str | None` might not be directly evaluable
# e.g., on Python < 3.10 without __future__.annotations, or in certain contexts.
# The backport ensures it resolves to typing.Union[str, None].
# For this example, we're just showing the direct usage of the function.
# Get the annotation for 'field'
annotation = cls.__annotations__['field']
# Evaluate it using the backport function
evaluated_type = eval_type_backport(annotation, globalns=sys.modules[__name__].__dict__, localns={})
print(f"Original annotation: {annotation!r}")
print(f"Evaluated type: {evaluated_type!r}")
if __name__ == "__main__":
demonstrate_eval(MyModel)