Skip to content

Beartype 0.13.0

Compare
Choose a tag to compare
@github-actions github-actions released this 08 Apr 04:57
· 324 commits to main since this release

This minor release delivers pulse-quickening support for pandera (pandas) type hints, PEP 484, PEP 585, PEP 591, PEP 647, PEP 3119, and pseudo-callables. This release resolves 12 issues and merges 2 pull requests. But first: a quiet word from our wondrous sponsors. They are monocled QA wizards who serve justice while crushing bugs for humanity. High fives, please!

Beartype Sponsors

Thunderous applause echoes through the cavernous confines of the Bear Den. 👏 🐻‍❄️ 👏

And now... the moment we've waited for. A heinous display of plaintext that assaults all five senses simultaneously.

Compatibility Added

  • Pandera (pandas) type hints (i.e., ad-hoc PEP-noncompliant type hints validating pandas DataFrame objects, produced by subscripting factories published by the pandera.typing subpackage and validated only by user-defined callables decorated by the ad-hoc PEP-noncompliant @pandera.check_types runtime type-checking decorator), resolving feature request #227 kindly submitted by @ulfaslakprecis (Ulf Aslak) the Big Boss Typer. @beartype now:
    • Transparently supports pandera's PEP-noncompliant @pandera.check_types decorator for deeply runtime type-checking arbitrary pandas objects.
    • Always performs a rudimentary O(1) isinstance()-based type-check for each pandera type hint. Doing so substantially improves usability in common use cases, including:
      • Callables annotated by one or more pandera type hints that are correctly decorated by @beartype but incorrectly not decorated by the pandera-specific @pandera.check_types decorator.
      • (Data)classes annotated by one or more pandera type hints.
      • Pandera type hints passed as the second argument to statement-level @beartype type-checkers – including:
        • beartype.door.is_bearable().
        • beartype.door.die_if_unbearable().
    • Implements a non-trivial trie data structure to efficiently detect all type hints produced by subscriptable factories in the pandera.typing submodule. Let us pretend this never happened, @ulfaslakprecis.
  • PEP 484- and 585-compliant generator constraints. This release relaxes prior constraints erroneously imposed by @beartype prohibiting both asynchronous and synchronous generator callables from being annotated as returning unsubscripted standard abstract base classes (ABCs) defined by the collections.abc module. Now, @beartype permits:
    • Asynchronous generator callables to be annotated as returning the unsubscripted collections.abc.AsyncGenerator type.
    • Synchronous generator callables to be annotated as returning the unsubscripted collections.abc.Generator type.
  • PEP 591 (i.e., typing.Final[...] type hints), partially resolving issue #223 kindly submitted by the acronym known only as @JWCS (Jude). @beartype now trivially reduces all typing.Final[{hint}] type hints to merely {hint} (e.g., typing.Final[int] to int). In other words, @beartype no longer raises exceptions when confronted with final type hints and instead at least tries to do the right thing. This still isn't quite what everyone wants @beartype to do here; ideally, @beartype should also raise exceptions on detecting attempts to redefine instance and class variables annotated as Final[...]. Doing so is definitely feasible and exactly what @beartype should eventually do – but also non-trivial, because whatever @beartype eventually does needs to preserve compatibility with all implementations of the @dataclass decorator across all versions of Python now and forever. Cue that head-throbbing migraine. It's comin'! Oh, I can feel it!
  • PEP 647 (i.e., typing.TypeGuard[...] type hints), resolving feature request #221 kindly submitted by Google X researcher extraordinaire @patrick-kidger. @beartype now trivially reduces all typing.TypeGuard[...] type hints to the builtin bool type.

Compatibility Improved

  • PEP 3119. @beartype now detects both non-isinstanceable classes (i.e., classes whose metaclasses define PEP 3119-compliant __instancecheck__() dunder methods unconditionally raising TypeError exceptions) and non-issubclassable classes (i.e., classes whose metaclasses define PEP 3119-compliant __subclasscheck__() dunder methods unconditionally raising TypeError exceptions) more narrowly for safety, resolving issue #220 kindly submitted by extraordinary Google X researcher @patrick-kidger (Patrick Kidger). Notably, @beartype now only accepts TypeError exceptions as connoting non-isinstanceability and non-issubclassability. Previously, @beartype broadly treated any class raising any exception whatsoever when passed as the second parameter to isinstance() and issubclass() as non-isinstanceable and non-issubclassable. Sadly, doing so erroneously raises false positives for isinstanceable and issubclassable metaclasses that have yet to be fully "initialized" at the early time the @beartype decorator performs this detection.

Features Added

  • Pseudo-callable monkey-patching support. @beartype now supports pseudo-callables (i.e., otherwise uncallable objects masquerading as callable by defining the __call__() dunder method), resolving feature request #211 kindly submitted by Google X typing guru @patrick-kidger (Patrick Kidger). When passed a pseudo-callable whose __call__() method is annotated by one or more type hints, @beartype runtime type-checks that method in the standard way.

Documentation Revised

  • Literally everything, also known as the release that migrated README.rst -> Read the Docs (RtD), resolving both issue #203 kindly submitted by @LittleBigGene (AKA the dynamo of the cell) and ancient issue #8 kindly submitted by @felix-hilden (AKA the Finnish computer vision art genius that really made all of this possible). Readable documentation slowly emerges from the primordial soup of @beartype's shameless past for which we cannot be blamed. @leycec was young and "spirited" back then. This release:
    • Coerces our prior monolithic slab of unreadable README.rst documentation into a website graciously hosted by Read the Docs (RtD) subdividing that prior documentation into well-structured pages, resolving issue #203 kindly submitted by @LittleBigGene (AKA the dynamo of the cell).
    • Documents most previously undocumented public APIs in the @beartype codebase. Although a handful of public APIs remain undocumented (notably, the beartype.peps submodule), these undocumented APIs are assumed to either be sufficiently unpopular or non-useful to warrant investing additional scarce resources here.
    • Updates our installation instructions to note @beartype's recent availability as official packages in the official package repositories of various Linux distributions. Truly, this can only be the final mark of pride. These include:
      • Gentoo Linux's Portage tree.
      • Arch Linux's Arch User Repository (AUR).
    • Improves the Python code sample embedded in the "Are We on the Worst Timeline?" subsection of our Beartype Errors chapter. Thanks to @JWCS for their related pull request (PR) #210, which strongly inspired this bald-faced improvement to the usability of our beartype.typing API.
    • Circumvents multiple long-standing upstream issues in the PyData Sphinx theme regarding empty left sidebars via the requisite _templates/sidebar-nav-bs.html template hack shamelessly copy-pasted into literally every project requiring this theme. This includes @beartype, because why not spew boilerplate that nobody understands everywhere? Sadly, doing so requires pinning to a maximum obsolete version of this theme that will surely die soon. And this is why I facepalm. These issues include:
    • Truncates our README.rst documentation to a placeholder stub that just directs everyone to RtD instead.
    • Improves linecache integration commentary. Specifically, a pull request by @faangbait (AKA the little-known third member of Daft Punk) improves internal commentary in our private beartype._util.func.utilfuncmake.make_func() factory function responsible for dynamically synthesizing new in-memory functions on-the-fly. Our suspicious usage of None as the second item of tuples added as values to the standard linecache.cache global dictionary has now been documented. Thanks so much for this stupendous contribution, @faangbait!

Tests Improved

  • Mypy integration. This release improves our test_pep561_mypy() integration test to intentionally ignore unhelpful non-fatal warnings improperly emitted by mypy (which encourage usage of typing_extensions, oddly enough).
  • Sphinx integration. This release resolves multiple intersecting issues involving integration testing of Sphinx + @beartype, including:
    • test_beartype_in_sphinx() h0tfix is h0t. This release generalizes our test-specific test_beartype_in_sphinx() integration test to support arbitrary versions of Sphinx, resolving issue #209 kindly submitted by @danigm the sun-loving Málaga resident who frolics in the sea that Canadians everywhere are openly jealous of. Specifically, this release fundamentally refactors this integration test to fork a new Python interpreter as a subprocess of the current pytest process running the sphinx-build command.
    • A Python 3.7-specific failure in our continuous integration (CI) workflow caused by Sphinx attempting to call deprecated functionality of the third-party pkg_resources package. This release simply avoids installing Sphinx entirely under Python 3.7; although admittedly crude, it's unclear how else @beartype could possibly resolve this. Since Python 3.7 has almost hit its official End-Of-Life (EOL) and thus increasingly poses a security concern, this is hardly the worst resolution ever. Really! Believe what we're saying.

Break nothing! It's the @beartype way. This is why @leycec cries like a mewling cat with no milk. (Thrilling chills spill towards an untoward ontology!)