Beartype 0.5.0 released.
This stable release implements full compliance for PEP 585 -- Type Hinting Generics in Standard Collections, where "full compliance" means "@beartype
deeply type-checks all categories of type hints deeply type-checked by prior stable releases and shallowly type-checks the remainder." See our compliance list and feature matrix for deeply exhausting, enervating, and deenergizing details.
Specific changes include:
Compatibility Improved
- PEP 585.
@beartype
is now fully compliant with PEP 585 -- Type Hinting Generics in Standard Collections. Since that PEP supercedes and largely obsoletes the overwhelming majority of PEP 484, compliance with PEP 585 is critical for all static and runtime type checkers to guarantee forward compatibility with Python's type-checking ecosystem. Note this compliance includes:- Deep type-checking support for all comparable type hints with deep type-checking support in prior
@beartype
versions, including:- Subscriptions of these C-based builtin types and pure-Python abstract base classes (ABCs) declared by the stdlib:
list
.tuple
.collections.abc.ByteString
.collections.abc.MutableSequence
.collections.abc.Sequence
.
- User-defined PEP 585-compliant generics (e.g.,
class ListOfInts(list[int]): pass
), which were implemented in a completely non-orthogonal manner to both PEP 484-compliant generics and PEP 544-compliant protocols and thus required "extreme" handling for PEP 585-specific edge cases.
- Subscriptions of these C-based builtin types and pure-Python abstract base classes (ABCs) declared by the stdlib:
- Deep type-checking support for all comparable type hints with deep type-checking support in prior
- Unhashable PEP-compliant type hints.
@beartype
now supports PEP-compliant type hints not hashable by thehash()
builtin and thus impermissible for use as dictionary keys, set members, and memoized callable parameters. While all PEP 484-compliant type hints are hashable, many such hints (e.g.,typing.Callable[[], str]
) are unhashable when converted into equivalent PEP 585-compliant type hints (e.g.,collections.abc.Callable[[], str]
), necessitating that@beartype
now permissively accept both hashable and unhashable type hints. The disadvantage of the latter is that the private@beartype._util.cache.utilcachecall.callable_cached
decorator underlying internal decoration-time memoization performed by@beartype
cannot, by definition, memoize calls passed one or more unhashable objects. Ergo, callables accepting one or more unhashable PEP-compliant type hints incur a performance penalty versus hashable PEP-compliant type hints. Note this penalty is only paid at decoration rather than call time and should thus be entirely negligible. Unhashable PEP-compliant type hints include:- PEP 585-compliant type hints subscripted by one or more unhashable objects (e.g., `collections.abc.Callable[[], str]).
- PEP 586-compliant type hints subscripted by an unhashable object (e.g.,
typing.Literal[[]]
, a literal empty list). - PEP 593-compliant type hints subscripted by one or more unhashable objects (e.g.,
typing.Annotated[typing.Any, []]
, thetyping.Any
singleton annotated by an empty list).
@typing.no_type_check
.@beartype
now supports the PEP 484-compliant@typing.no_type_check
decorator by silently ignoring (and thus reducing to a noop for) all callables decorated by that decorator.typing.TYPE_CHECKING.
@beartype
now supports the PEP 484-complianttyping.TYPE_CHECKING
boolean constant by silently reducing to the identity decorator when this boolean isTrue
(i.e., during external static type checking).
Compatibility Broken
- Call-time PEP-noncompliant type hint exception classes removed. Since all PEP-noncompliant type hints supported by
@beartype
(e.g., tuple unions) are now internally coerced into equivalent PEP-compliant type hints, PEP-noncompliant type hint exception classes are now obsolete and have been summarily removed. These include:beartype.roar.BeartypeCallHintNonPepException
.beartype.roar.BeartypeCallHintNonPepParamException
.beartype.roar.BeartypeCallHintNonPepReturnException
.
Features Deprecated
- PEP 484-compliant type hints deprecated by PEP 585.
@beartype
now emits non-fatal warnings of classbeartype.roar.BeartypeDecorHintPepDeprecatedWarning
under Python >= 3.9 for each PEP 484-compliant type hint deprecated by PEP 585 annotating each decorated callables. Critically, note that this deprecates most PEP 484-compliant type hints accepted without warning by prior stable releases and, indeed, most of the existingtyping
stdlib module. Affected type hints include subscriptions of any of the following objects:typing.AbstractSet
.typing.AsyncGenerator
.typing.AsyncIterable
.typing.AsyncIterator
.typing.Awaitable
.typing.ByteString
.typing.Callable
.typing.ChainMap
.typing.Collection
.typing.Container
.typing.ContextManager
.typing.Coroutine
.typing.Counter
.typing.DefaultDict
.typing.Deque
.typing.Dict
.typing.FrozenSet
.typing.Generator
.typing.ItemsView
.typing.Iterable
.typing.Iterator
.typing.KeysView
.typing.List
.typing.MappingView
.typing.Mapping
.typing.Match
.typing.MutableMapping
.typing.MutableSequence
.typing.MutableSet
.typing.Pattern
.typing.Reversible
.typing.Sequence
.typing.Set
.typing.Tuple
.typing.Type
.typing.ValuesView
.
Features Optimized
- Standard PEP-noncompliant class type hints.
@beartype
now efficiently registers type hints that are standard classes not explicitly compliant with any existing PEP at decoration time and accesses these hints at call time via the standard beartypistry singleton used to resolve all other type hints rather than inefficiently accessing these hints at call time via dictionary lookup into the__annotations__
dunder attribute of the decorated callable, eliminating one dictionary lookup for each such hint for each call to each callable annotated by one or more such hints. - Beartype-specific tuple unions < PEP 484 unions. Beartype-specific tuple unions are now a strict semantic subset of PEP 484 unions. Previously, tuple unions and PEP 484 unions were implemented in disparate subpackages -- and the subpackage implementing tuple unions has become poorly documented, maintained, and tested. To reduce bit-rot across the codebase and unify the implementation of tuple and PEP 484 unions,
@beartype
now silently coerces all tuple unions into the equivalent PEP 484 unions at decoration time. Doing so resolves all outstanding performance and usability issues with tuple unions, including:- Tuple unions are now efficiently registered at decoration time and accessed at call time via the standard beartypistry singleton used to resolve all other type hints rather than inefficiently accessed at call time via dictionary lookup on the
__annotations__
dunder attribute of the decorated callable, eliminating one dictionary lookup for each such hint for each call to each callable annotated by one or more such hints. - Duplicate types in tuple unions are now silently ignored rather than type-checked (e.g.,
(bool, str, bool)
is now type-checked as(bool, str)
). - Forward references in tuple unions (e.g.,
('muh.TypeName', str)
) are now efficiently resolved at call time via the standard beartypistry singleton used to resolve all other forward references rather than inefficiently resolved at call time via non-standard iteration hard-coded into all wrapper functions generated by@beartype
for callables annotated by these tuple unions. - Registration and optimized access of types in tuple unions via our internal beartypistry type registrar.
- Tuple unions are now efficiently registered at decoration time and accessed at call time via the standard beartypistry singleton used to resolve all other type hints rather than inefficiently accessed at call time via dictionary lookup on the
- Decoration-time memoization, particularly with respect to PEP 484 union type hints. All internal callables decorated by the private
@beartype._util.cache.utilcachecall.callable_cached
decorator are now efficiently called with positional arguments rather than inefficiently called with equivalent keyword arguments. Memoizing keyword arguments is substantially more space- and time-intensive than memoizing the equivalent positional arguments, partially defeating the purpose of memoization in the first place. To enforce this, these internal callables now emit new non-fatal privatebeartype.roar._BeartypeUtilCallableCachedKwargsWarning
warnings when passed one or more keyword arguments.
Issues Resolved
- "3.9+ PEP 585 - type hints for builtin types." This release resolves longstanding issue #4 by adding full support for PEP 585. Thanks for prodding us to jump onto this critical feature, @terrdavis!
Tests Improved
- Third-party package tests restored. Unit tests conditionally depending upon the importability of third-party packages have been restored to their prior working state after an embarassingly elongated period of being ignored. These include:
- The
test_api_cave_lib_numpy()
unit test exercising NumPy integration in thebeartype.cave
submodule. - The
test_api_cave_lib_setuptools()
unit test exercisingsetuptools
integration in thebeartype.cave
submodule.
- The
API Changed
- In the
beartype.roar
submodule:- Added:
BeartypeDecorHintPepDeprecatedWarning
.
- Removed:
BeartypeCallHintNonPepException
.BeartypeCallHintNonPepParamException
.BeartypeCallHintNonPepReturnException
.
- Added:
(Styled turnstiles burn mile-high piles of corrugated corruption!)