pypi beartype 0.4.0
beartype v0.4.0

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

Beartype 0.4.0 released.

This stable release significantly improves beartype's compliance with Python Enhancement Proposals (PEPs), including full compliance with:

  • PEP 483 -- The Theory of Type Hints.
  • PEP 484 -- Type Hints.
  • PEP 544 -- Protocols: Structural subtyping (static duck typing).
  • PEP 560 -- Core support for typing module and generic types.
  • PEP 563 -- Postponed Evaluation of Annotations.
  • PEP 593 -- Flexible function and variable annotations.

With respect to PEPs 483 and 484, "full compliance" means "beartype deeply type-checks a lot and at least shallowly type-checks the remainder." With respect to the remaining PEPs, "full compliance" means "beartype deeply type-checks everything."

Specific changes include:

Compatibility Broken

  • Call-time type hint exception classes renamed. For orthogonality with decoration-time type hint exception classes, all call-time type hint exception classes have been renamed from beartype.roar.BeartypeCallCheck*Exception to beartype.roar.BeartypeCallHint*Exception (e.g., from beartype.roar.BeartypeCallCheckPepParamException to beartype.roar.BeartypeCallHintPepParamException).

Features Added

  • Deep typing.Annotated type-checking. Under Python ≥ 3.9, the @beartype decorator now deeply type-checks parameters and return values annotated by PEP 593 (i.e., "Flexible function and variable annotations")-compliant typing.Annotated type hints in guaranteed constant time.
  • Deep typing.Generic type-checking. The @beartype decorator now type-checks both the shallow types and deep contents of parameters and return values annotated by PEP 484-compliant generics (i.e., type hints subclassing a combination of one or more of the typing.Generic superclass and/or other typing non-class pseudo-superclasses) in guaranteed constant time. Specifically, beartype iteratively walks up the superclass hierarchy of each generic and deeply type-checks that the current parameter or return value satisfies all constraints implied by that superclass. This includes:
    • typing.IO. This was no small feat, as this abstract base class (ABC) fails to leverage structural subtyping (e.g., via the PEP 544-compliant typing.Protocol ABC) and is thus unusable at runtime... like most typing objects, sadly. Our solution is to ignore the existing implementation of these classes, declare our own internal typing.Protocol-based variants of these classes, and implicitly substitute all instances of these classes with our own variants during our breadth-first traversal (BFS) over PEP-compliant type hints.
    • typing.BinaryIO.
    • typing.TextIO.
  • Deep typing.NewType support. The @beartype decorator now deeply type-checks parameters and return values annotated by PEP 484-compliant new types (i.e., closures generated by the typing.NewType closure factory) in guaranteed constant time.
  • Deep typing.NoReturn support. The @beartype decorator now fully type-checks that callables annotated by the typing.NoReturn singleton return no values (i.e., either halt the active Python process or raise an exception) in guaranteed constant time.
  • Deep typing.Protocol type-checking. Under Python ≥ 3.8, the @beartype decorator now type-checks both the shallow types and deep contents of parameters and return values annotated by PEP 544 (i.e., "Protocols: Structural subtyping (static duck typing)")-compliant protocols (i.e., type hints subclassing a combination of one or more of the typing.Protocol superclass and/or other typing non-class pseudo-superclasses) in guaranteed constant time, similarly to how beartype type-checks generics. This includes:
    • typing.SupportsAbs.
    • typing.SupportsBytes.
    • typing.SupportsComplex.
    • typing.SupportsIndex.
    • typing.SupportsInt.
    • typing.SupportsFloat.
    • typing.SupportsRound.
  • Deep typing.Tuple type-checking. The @beartype decorator now type-checks both the shallow types and deep contents of parameters and return values annotated by PEP 484-compliant typing.Tuple type hints in guaranteed constant time. The three syntactic variants standardized by PEP 484 are all supported, including:
    • typing.Tuple[()], type-checking empty tuples.
    • typing.Tuple[{typename}, ...], type-checking tuples containing arbitrarily many items all satisfying the PEP-compliant child hint {typename} (e.g., typing.Tuple[str, ...], a tuple of strings).
    • typing.Tuple[{typename1}, ..., {typenameN}], type-checking tuples containing exactly N items each satisfying a unique PEP-compliant child hint {typenameI} (e.g., typing.Tuple[str, int, float], a tuple containing exactly one string, one integer, and one floating-point number in that order).
  • Shallow typing.AsyncContextManager, typing.ContextManager, typing.Match, and typing.Pattern support. The @beartype decorator now type-checks the shallow types (but not deep contents) of parameters and return values annotated by the PEP 484-compliant typing.AsyncContextManager, typing.ContextManager, typing.Match, and typing.Pattern objects. This was no small feat, as the implementations of:
    • typing.AsyncContextManager and typing.ContextManager define __repr__() dunder methods returning erroneous machine-readable representations obstructing proper support under prior releases.
    • typing.Match and typing.Pattern under Python 3.6 are non-trivially obtuse and basically broken at runtime.
  • Shallow type variable support. The @beartype decorator now shallowly type-checks all otherwise supported PEP-compliant type hints parametrized by one or more type variables (e.g., List[T], where T = TypeVar('T')). Previously, this decorator raised exceptions when decorating callables with such hints. This decorator does not yet deeply type-check type variables to be constrained across callable parameters and return values or class methods. For def muh_func(muh_param: List[T]) -> T: return muh_param[0], as example, this decorator now shallowly type-checks the passed parameter muh_param to be a list but does not yet deeply type-check that this function returns values of the same types as items of this list.

Features Optimized

  • Nested PEP-compliant type hint type-checking. Under Python ≥ 3.8, the @beartype decorator now generates optimized code when deeply type-checking items contained in arbitrarily nested PEP-compliant type hints (e.g., typing.List[typing.Union[bool, str, typing.List[int]]]) with PEP 572-style assignment expressions, generalizing similar sequence-specific optimizations introduced with beartype 0.3.0.
  • PEP-compliant type hint breadth-first search (BFS). The @beartype decorator now internally catalogues PEP-compliant type hints during the breadth-first search (BFS) it performs over these hints as simple tuples rather than fixed lists, as the former are both mildly faster than the latter and significantly more maintainable (which is the main gain here).

Issues Resolved

  • PEP-compliant type hint code generation memoization. The @beartype decorator now properly memoizes the type-checking code it generates for PEP-compliant type hints. Prior beartype releases silently failed to memoize this code across different callables annotated by the same hints.

API Changed

  • In the beartype.cave submodule, added:
    • A new public beartype.cave.HintPep585Type attribute, defined as the C-based type of all PEP 585-compliant type hints (i.e., C-based type hint instantiated by subscripting either a concrete builtin container class like list or tuple or an abstract base class (ABC) declared by the collections.abc submodule like collections.abc.Iterable or collections.abc.Sequence) if the active Python interpreter targets at least Python 3.9.0 or beartype.cave.UnavailableType otherwise. This is a prerequisite for PEP 585 support in a subsequent stable release.
  • In the beartype.roar submodule, renamed:
    • BeartypeCallCheckException to BeartypeCallHintException.
    • BeartypeCallCheckPepException to BeartypeCallHintPepException.
    • BeartypeCallCheckPepParamException to
      BeartypeCallHintPepParamException.
    • BeartypeCallCheckPepReturnException to
      BeartypeCallHintPepReturnException.
    • BeartypeCallCheckNonPepException to
      BeartypeCallHintNonPepException.
    • BeartypeCallCheckNonPepParamException to
      BeartypeCallHintNonPepParamException.
    • BeartypeCallCheckNonPepReturnException to
      BeartypeCallHintNonPepReturnException.

Don't miss a new beartype release

NewReleases is sending notifications on new releases.