Beartype 0.12.0
Beartype 0.12.0 expands the infinitely vast (yet mostly empty) universe of @beartype into the hitherto uncharted realms of configuration, exception identification, Nuitka, typing.NamedTuple
, and Python 3.11. Also, other things were done. We swear it!
This minor release resolves 16 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 Improved
- Python 3.11. This is the first @beartype support to officially support the recently released Python 3.11. Notably, this release:
- Synchronizes our public
beartype.typing
subpackage against upstream changes in the standardtyping
module introduced in Python 3.11. - Supports PEP-compliant type hints subscripted by the empty tuple (e.g.,
typing.Tuple[()]
), whose low-level implementation fundamentally changed under Python 3.11. - Updates our GitHub Actions-based continuous integration (CI) workflow to exercise @beartype against Python 3.11.
- Synchronizes our public
- Nuitka. This is the first @beartype release to officially support Nuitka (i.e., the increasingly popular Python compiler that stuns us all), resolving feature request #197 kindly submitted by @shenwpo (also known as the giant flaming metallic letter e). This includes a new
test_nuitka()
integration test showing that Nuitka successfully compiles a minimal-length example (MLE) runtime type-checked by @beartype. typing.NamedTuple
. This release adds support for deeply type-checking subclasses of the PEP 484-complianttyping.NamedTuple
superclass. Specifically, this release improves the resiliency of our PEP 563 resolution mechanism (i.e., the publicbeartype.peps.resolve_pep563()
function) against callables whose__module__
dunder attributes lie. This includes alltyping.NamedTuple
subclasses, which synthesize callables whose__module__
dunder attributes erroneously claim to reside in the non-existent"namedtuple_Foo"
module. Doing so resolves issue #181 kindly submitted by probably ingenious "Probabilistic Machine Learning" author @murphyk (Kevin P. Murphy).
Features Added
- Beartype configuration API. This release publishes a new public API for externally configuring @beartype via the now-official
beartype.BeartypeConf
type andbeartype.BeartypeStrategy
enumeration. Specifically, this release adds:beartype.BeartypeConf.is_color
, a new tri-state boolean enabling end users to control how and whether beartype colours type-checking violations (i.e., :class:beartype.roar.BeartypeCallHintViolation
exceptions) with POSIX-compliant ANSI escape sequences for readability, resolving issue #178 kindly submitted by the foxy ZeroGuard and River Oakfield founder @foxx (Cal Leeming). Rejoice, typing acolytes, for you have now been freed from the prismatic shackles of the rainbow!beartype.BeartypeConf.is_pep484_tower
, a new standard boolean enabling end users to control whether @beartype supports the implicit numeric tower standardized by PEP 484 or not, resolving issue #174 kindly submitted by dashing French Canadian @felixchenier (Félix Chénier).beartype.BeartypeStrategy.O0
, a new no-time strategy (i.e., beartype configuration option generalizing the standard@typing.no_type_check
decorator). Enabling this strategy instructs the@beartype
decorator to recall and preserve previously applied no-time strategies; internally,@beartype
detects and reduces configurations resemblingconf=BeartypeConf(strategy=BeartypeStrategy.O0, ...)
to the@typing.no_type_check
decorator. Users may now blacklist specific callables from being type-checked by configuring this strategy as documented in our front-facingREADME.rst
documentation... somewhere. It's in there somewhere, people.
- Beartype exception API. This release publishes a new public API for externally identifying the cause of type-checking violations (i.e., instances of the
beartype.roar.BeartypeCallHintViolation
exception class) raised by @beartype. These exceptions now publicly expose the user-defined objects responsible for those violations via a newBeartypeCallHintViolation.culprits
property, resolving feature request #180 kindly submitted by @Jasha10 the Supremely Patient and Understanding GitHubber. For safety, this property dynamically returns a non-empty tuple of the one or more responsible culprits defined as either:- For each culprit that supports weak references and is still alive (i.e., has yet to be garbage-collected), that culprit as is.
- Else, the machine-readable string representation of that culprit truncated to a reasonable number of characters.
Features Deprecated
beartype.roar.BeartypeAbby*Exception
. This release deprecates all lingering remnants of the priorbeartype.abby
subpackage – including:beartype.roar.BeartypeAbbyException
, supplanted bybeartype.roar.BeartypeDoorException
.beartype.roar.BeartypeAbbyHintViolation
, supplanted bybeartype.roar.BeartypeDoorHintViolation
.beartype.roar.BeartypeAbbyTesterException
, supplanted bybeartype.roar.BeartypeDoorException
.
Static Type-checking Improved
- @beartype exports. This release terminally pacifies:
- Mypy by publicizing all exported attributes from the top-level
beartype
package via a newbeartype.__all__
dunder attribute. Thanks to the stylishly pink-haired @pinkwah (Zohar Malamant) for the rapid pull request (PR). pyright
by explicitly re-exporting all public attributes of the top-levelbeartype
package, resolving issue #169 kindly submitted by MIT AI mastermind @rsokl (Ryan Soklaski).
- Mypy by publicizing all exported attributes from the top-level
- Continuous integration (CI). This release integrates our GitHub Actions-based continuous integration (CI) workflow (i.e.,
.github/workflows/python_test.yml
) with third-party GitHub Actions statically type-checking beartype against bothmypy
andpyright
at CI time– including on every commit as well as pull request (PR). For both robustness and efficiency, this release prevents functional tests in our test suite that perform these same static type-checks from running under CI. Doing so resolves a furious spate of spurious CI complaints. So what we did there? We rhymed. Notably, this release:- Leverages @jakebailey's superb
jakebailey/pyright-action
action to exercise @beartype againstpyright
at CI time. - Manually installs and runs
mypy
in a low-level manner under CI without leveraging @jpetrucciani's otherwise stellarjpetrucciani/mypy-check
action -- which @beartype hopes to revisit at a later date when the issue tracker settles there a bit. Thanks so much, @jpetrucciani! You dah real QA MVP.
- Leverages @jakebailey's superb
Issue Resolved
beartype.door.TypeHint
comparisons. This release significantly improves the robustness of comparison operators overloaded by the object-orientedbeartype.door.TypeHint
API, resolving issue #198 kindly submitted by @wesselb the phenomenal Amsterdammer of Plum fame. This includes edge cases when:- Comparing unions against both other unions and non-unions (e.g.,
typing.Any
, isinstanceable classes). - Comparing tuple type hints against
typing.Any
.
- Comparing unions against both other unions and non-unions (e.g.,
beartype.BeartypeConf
caching. This release resolves a critical (yet ultimately trivial) caching issue with respect tobeartype.BeartypeConf
singletons, in which singletons initialized with different parameters could conceivably have been erroneously cached to the same object. Hash collisions! I see hash collisions everywhere!- Call stack iteration robustness. This release resolves an edge case in our private
beartype._util.func.utilfuncframe.iter_frames()
generator iterating over stack frames on the current call stack. Specifically, this generator now safely reduces to the empty generator (i.e., noop) when the caller requested that generator ignore more stack frames than exist on the call stack. Although raising an exception would also be feasible, doing so would only needlessly increase the fragility of this already fragile mission-critical generator.
Documentation Resolved
- Broken anchor links. This release repairs broken anchor links dotted throughout our monolithic
README.rst
to actually point to valid (sub)sections. - Sphinx configuration. This release reconfigures the lackluster coffin that is our Sphinx configuration, en-route to resolving issue #8 (!) kindly submitted a literal lifetime ago by visionary computer vision export and long-standing phenomenal Finn @felix-hilden (Felix Hildén). Specifically, this release:
- Enables Furo, switching from the default Read The Docs (RTD) Sphinx theme to the third-party Furo theme. We selected this theme according to mostly objective (albeit ultimately subjective) heuristic criteria. In descending order of importance, we selected the theme with:
- The most frequent git commit history.
- The open issues and pull requests (PRs).
- The most GitHub stars as a crude proxy for aggregate rating.
Furo handily bested all other themes across all three criteria. Furo is very well-maintained, frequently closes out open issues and merges open PRs, and sports the highest quantity of GitHub stars by an overwhelming margin.\o/
- Enables the builtin
intersphinx
extension, enabling attributes defined by the standard library (e.g., thetyping
module, thetypes.GenericAlias
type) to be cross-referenced as a fallback when not already defined by this project. - Reconfigures RTD through our top-level
.readthedocs.yml
configuration to:- Build under the most recent Long Term Service (LTS) release of Ubuntu.
- Build under the most recently released minor version of CPython.
- Configure Sphinx via our
doc/source/conf.py
script.
- Restores the standard
sys.path
hack – which, for unknown reasons, @leycec disabled but thankfully left commented out. Doing so re-resolves issue #120, kindly submitted by @kloczek (Tomasz Kłoczko) five friggin' months ago. Thanks so much for the fast patch and rapid turn-around, @kloczek! - Improves pathname robustness by intelligently detecting documentation paths via the standard
pathlib.Path
API. - Enables
autoapi
. This release successfully transitions from Sphinx's builtin (but insane)autodoc
andautosummary
extensions to Read The Doc (RTD)'s non-builtin (but sane)autoapi
extension. - Adds a local URI store (i.e., hidden reStructuredText (reST) document centralizing common URI links in reST format, automatically exposed to all other reST documents in this project via the
rst_epilog
setting inconf.py
) atdoc/src/_links.rst
. - Removes obsolete cruft, which accrues with time like entropic motes in God's eye. That was a reference to a Golden Age of Scifi book, people! Don't ask why God only has one eye. It's better not to contemplate these matters.
- Ruthlessly circumvents upstream issue sphinx-doc/sphinx#4961, causing Sphinx to emit literally hundreds of ignorable warnings resembling
"WARNING: more than one target found for cross-reference 'TypeHint':
beartype.door._doorcls.TypeHint, beartype.door.TypeHint"
with a trivial circumvention shamelessly pilfered from @RDFLib.
- Enables Furo, switching from the default Read The Docs (RTD) Sphinx theme to the third-party Furo theme. We selected this theme according to mostly objective (albeit ultimately subjective) heuristic criteria. In descending order of importance, we selected the theme with:
Documentation Added
- Beartype Object-oriented API. This release prefaces our "Beartype Object-oriented API" subsection with a human-readable discussion of the Decidedly Object-Oriented Runtime-checking (DOOR) – also known as "That API Which Breaks Hearts and Minds Alike."
- **Procedural Showcase. This release adds a new Procedural Showcase subsection containing a new Detect API Breakage subsubsection exhibiting a real-world usage for our recently published
beartype.door.is_subhint()
tester: detecting API breakage across the type hints annotating arbitrary callables in exactly ten lines of code. - Near-real-time FAQ entry. This release adds a new FAQ entry entitled What does "near-real-time" even mean?, justifying our recent categorization of @beartype as a "near-real-time runtime type-checker." Let's pretend @leycec knows what he's talking about.
- JAX, Numpy, and PyTorch FAQ entries. This release expands our existing FAQ with entries on typing JAX and NumPy arrays and PyTorch tensors to highlight the stupefying potential unlocked by the third-party
jaxtyping
,nptyping
, and TorchTyping packages, resolving issue #98 submitted a literal lifetime ago by Edinburgh NLP researcher @amitkparekh (Amit Parekh). - VSCode FAQ entry. This release rewrites our entire FAQ entry on
pyright
+ Pylance + VSCode to be significantly more charitable towardspyright
, resolving issue #170 kindly submitted by MIT AI mastermind @rsokl (Ryan Soklaski). - Type narrowing FAQ entry. This release adds a new FAQ entry on type narrowing, strongly inspired by (...wait for it) MIT AI mastermind @rsokl (Ryan Soklaski)'s equally masterful writing at issue #166.
(Powerful bowers full of flowers!)