pypi beartype 0.5.0
beartype v0.5.0

latest releases: 0.21.0, 0.21.0rc0, 0.20.2...
4 years ago

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.
  • Unhashable PEP-compliant type hints. @beartype now supports PEP-compliant type hints not hashable by the hash() 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, []], the typing.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-compliant typing.TYPE_CHECKING boolean constant by silently reducing to the identity decorator when this boolean is True (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 class beartype.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 existing typing 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.
  • 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 private beartype.roar._BeartypeUtilCallableCachedKwargsWarning warnings when passed one or more keyword arguments.

Issues Resolved

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 the beartype.cave submodule.
    • The test_api_cave_lib_setuptools() unit test exercising setuptools integration in the beartype.cave submodule.

API Changed

  • In the beartype.roar submodule:
    • Added:
      • BeartypeDecorHintPepDeprecatedWarning.
    • Removed:
      • BeartypeCallHintNonPepException.
      • BeartypeCallHintNonPepParamException.
      • BeartypeCallHintNonPepReturnException.

(Styled turnstiles burn mile-high piles of corrugated corruption!)

Don't miss a new beartype release

NewReleases is sending notifications on new releases.