Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 minor 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](https://zeroguard.com). *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 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 *ex*traordinary 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)](https://beartype.readthedocs.io), 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. Specifically, 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](https://beartype.readthedocs.io/en/latest/api_roar/#are-we-on-the-worst-timeline). 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: * pydata/pydata-sphinx-theme#90. * pydata/pydata-sphinx-theme#221. * pydata/pydata-sphinx-theme#1181. * 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!*)
- Loading branch information