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
- ZeroGuard: The Modern Threat Hunting Platform. All the signals, All the time.
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 thepandera.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()
.
- Callables annotated by one or more pandera type hints that are correctly decorated by @beartype but incorrectly not decorated by the pandera-specific
- 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.
- Transparently supports pandera's PEP-noncompliant
- 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.
- Asynchronous generator callables to be annotated as returning the unsubscripted
- 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 alltyping.Final[{hint}]
type hints to merely{hint}
(e.g.,typing.Final[int]
toint
). 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 asFinal[...]
. 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 alltyping.TypeGuard[...]
type hints to the builtinbool
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 raisingTypeError
exceptions) and non-issubclassable classes (i.e., classes whose metaclasses define PEP 3119-compliant__subclasscheck__()
dunder methods unconditionally raisingTypeError
exceptions) more narrowly for safety, resolving issue #220 kindly submitted by extraordinary Google X researcher @patrick-kidger (Patrick Kidger). Notably, @beartype now only acceptsTypeError
exceptions as connoting non-isinstanceability and non-issubclassability. Previously, @beartype broadly treated any class raising any exception whatsoever when passed as the second parameter toisinstance()
andissubclass()
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 privatebeartype._util.func.utilfuncmake.make_func()
factory function responsible for dynamically synthesizing new in-memory functions on-the-fly. Our suspicious usage ofNone
as the second item of tuples added as values to the standardlinecache.cache
global dictionary has now been documented. Thanks so much for this stupendous contribution, @faangbait!
- Coerces our prior monolithic slab of unreadable
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 oftyping_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-specifictest_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 currentpytest
process running thesphinx-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!)