Beartype 0.6.0 released.
This release brings explicit support for None
, subscripted generics, and PEP 561 compliance after resolving 10 issues and merging 8 pull requests. Changes include:
Compatibility Improved
- PEP 484-compliant
None
singleton. As a return type hint,None
is typically used to annotate callables containing no explicitreturn
statement and thus implicitly returningNone
.@beartype
now implicitly reducesNone
at all nesting levels of type hints to that singleton's type per PEP 484. - PEP 561 compliance.
beartype
now fully conforms to PEP 561, resolving issue #25 kindly submitted by best macOS package manager ever @harens. In useful terms, this means that:beartype
now complies with mypy, Python's popular third-party static type checker. If your package had no mypy errors or warnings before addingbeartype
as a mandatory dependency, your package will still have no mypy errors or warnings after addingbeartype
as a mandatory dependency.beartype
preserves PEP 561 compliance. If your package was PEP 561-compliant before addingbeartype
as a mandatory dependency, your package will still be PEP 561-compliant after addingbeartype
as a mandatory dependency. Of course, if your package currently is not PEP 561-compliant,beartype
can't help you there. We'd love to, really. It's us. Not you.- The
beartype
codebase is now mostly statically rather than dynamically typed, much to our public shame. Thus begins the eternal struggle to preserve duck typing in a world that hates bugs. - The
beartype
package now contains a top-levelpy.typed
file, publicly declaring this package to be PEP 561-compliant.
- Subscripted generics (i.e., user-defined generics subscripted by one or more type hints), resolving issue #29 kindly submitted by indefatigable test engineer and anthropomorphic Siberian Husky @eehusky. Since it's best not to ask too many questions about subscripted generics, we instead refer you to the issue report that nearly broke a Canadian man.
Compatibility Broken
- None. This release preserves backward compatibility with the prior stable release.
Packaging Improved
- New optional installation-time extras, enabling both
beartype
developers and automation tooling to trivially install recommended (but technically optional) dependencies. These include:pip install -e .[dev]
, installingbeartype
in editable mode as well as all dependencies required to both locally testbeartype
and build documentation forbeartype
from the command line.pip install beartype[doc-rtd]
, installingbeartype
as well as all dependencies required to build documentation from the external third-party Read The Docs (RTD) host.
- Homebrew- and MacPorts-based macOS installation. Our front-facing
README.rst
file now documentsbeartype
installation with both Homebrew and MacPorts on macOS, entirely courtesy the third-party Homebrew tap and Portfile maintained by build automation specialist and mild-mannered student @harens. Thanks a London pound, Haren!
Features Added
-
New
beartype.cave
types and type tuples, including:beartype.cave.CallableCTypes
, a tuple of all C-based callable types (i.e., types whose instances are callable objects implemented in low-level C rather than high-level Python).beartype.cave.HintGenericSubscriptedType
, the C-based type of all subscripted generics if the active Python interpreter targets Python >= 3.9 orbeartype.cave.UnavailableType
otherwise. This type was previously namedbeartype.cave.HintPep585Type
before we belatedly realized this type broadly applies to numerous categories of PEP-compliant type hints, including PEP 484-compliant subscripted generics.
Features Optimized
O(n)
→O(1)
exception handling.@beartype
now internally raises human-readable exceptions in the event of type-checking violations with anO(1)
rather thanO(n)
algorithm, significantly reducing time complexity for the edge case of invalid large sequences either passed to or returned from@beartype
-decorated callables. For forward compatibility with a future version ofbeartype
enabling users to explicitly switch between constant- and linear-time checking, the priorO(n)
exception-handling algorithm has been preserved in a presently disabled form.O(n)
→O(1)
callable introspection during internal memoization.@beartype
now avoids calling the inefficient stdlibinspect
module from our private@beartype._util.cache.utilcachecall.callable_cached
decorator memoizing functions throughout thebeartype
codebase. The priorO(n)
logic performed by that call has been replaced by equivalentO(1) logic performed by a call to our newly defined
beartype._util.func.utilfuncargsubmodule, optimizing function argument introspection without the unnecessary overhead of
inspect`.- Code object caching.
@beartype
now temporarily caches the code object for the currently decorated callable to support efficient introspection of that callable throughout the decoration process. Relatedly, this also has the beneficial side effect of explicitly raising human-readable exceptions from the@beartype
decorator on attempting to decorate C-based callables, which@beartype
now explicitly does not support, because C-based callables have no code objects and thus no efficient means of introspection. Fortunately, sane code only ever applies@beartype
to pure-Python callables anyway. ...right, sane code? Right!?!?
Features Deprecated
- The ambiguously named
beartype.cave.HintPep585Type
type, to be officially removed inbeartype
0.1.0.
Issues Resolved
- Unsafe
str.replace()
calls.@beartype
now wraps all unsafe internal calls to the low-levelstr.replace()
method with calls to the considerably safer high-levelbeartype._util.text.utiltextmunge.replace_str_substrs()
function, guaranteeing that memoized placeholder strings are properly unmemoized during decoration-time code generation. Thanks to temperate perennial flowering plant @Heliotrop3 for this astute observation and resolution to long-standing background issue #11. KeyPool
release validation.@beartype
now validates that objects passed to therelease()
method of the privatebeartype._util.cache.pool.utilcachepool.KeyPool
class have been previously returned from theacquire()
method of that class. Thanks to @Heliotrop3, the formidable bug assassin, for their unswerving dedication to the cause of justice with this resolution to issue #13.- Least Recently Used (LRU) cache.
@beartype
now internally provides a highly microoptimized Least Recently Used (LRU) cache for subsequent use throughout the codebase, particularly with respect to caching iterators over dictionaries, sets, and other non-sequence containers. This resolves issue #17, again graciously submitted by open-source bug mercenary @Heliotrop3. - Callable labelling.
@beartype
now internally provides a privatebeartype._util.func.utilfuncorigin.get_callable_origin_label
getter synthesizing human-readable labels for the files declaring arbitrary callables, a contribution by master code-mangler @Heliotrop3 resolving issue #18. Thanks again for all the insidious improvements, Tyler! You are the master of everyone's code domain. - Release automation. Our release workflow has now been migrated from the unmaintained
create-release
GitHub Action to @ncipollo's actively maintainedrelease-action
, resolving issue #22 kindly submitted by human-AI-hybrid @Heliotrop3.
Tests Improved
- Microsoft Windows and macOS exercised under CI, resolving issue #21. Since doing so increases our consumption of Microsoft resources that we care deeply about, care has been taken to reduce the cost of our CI workflow. This includes:
- Replacing our prior use of the external third-party
tox-gh-actions
GitHub Action streamliningtox
usage with our own ad-hoc build matrix that appears to be simpler and faster despite offering basically identical functionality. - Removing our prior installation of optional dependencies, especially including NumPy. Yeah. Let's not do that anymore.
Thanks to dedicated issue reporter @Heliotrop3 for his unsustainable deep-code trawling of thebeartype
codebase for unresolvedFIXME:
comments.
- Replacing our prior use of the external third-party
- PyPy 3.7 exercised under CI. Our
tox
and GitHub Actions-based continuous integration (CI) configurations now both correctly exercise themselves against both PyPy 3.6 and 3.7, resolving the upstream actions/setup-python#171 issue forbeartype
. - CI thresholded. Our CI configuration now caps tests to a sane maximum duration of time to avoid a repeat of the pull request we do not talk about here. Okay, it was #23. I blame only myself.
- New functional tests, including:
- A CPython-specific mypy functional test, optionally exercising our conformance to static type-checking standards when the third-party
mypy
package is installed under CPython. This test is sufficiently critical that we perform it under our CI workflow, guaranteeing test failures on any push or PR violating mypy expectations. - A
README.rst
functional test, optionally exercising the syntactic validity of our front-facingREADME.rst
documentation when the third-partydocutils
package (i.e., the reference reST parser) is installed. This test is sufficiently expensive that we currently avoid performing it under our CI workflow.
- A CPython-specific mypy functional test, optionally exercising our conformance to static type-checking standards when the third-party
- New unit tests, including:
- Text munging unit tests, exercising the private
beartype._util.text.utiltextmunge
submodule with lavish attention to regex-based fuzzy testing of the criticalnumber_lines()
function. Humblegit log
shout outs go out to @Heliotrop3 for this mythic changeset that warps the fragile fabric of the GitHub cloud to its own pellucid yet paradoxically impenetrable intentions, resolving issue #24.
- Text munging unit tests, exercising the private
Documentation Revised
- Sphinx skeleton. The
beartype
repository now defines a largely unpopulated skeleton for Sphinx-generated documentation formatted as reST and typically converted to HTML to be hosted at Read The Docs (RTD), generously contributed by @felix-hilden, Finnish computer vision expert and our first contributor! This skeleton enables:- An HTTP 404 redirect page on missing page hits.
- The standard retinue of builtin Sphinx extensions (e.g.,
autodoc
,viewcode
). - MathJax configured for remote implicit downloads.
- Napolean configured for NumPy-formatted docstrings.
- An optional dependency on
sphinx_rtd_theme
, a third-party Sphinx extension providing RTD's official Sphinx HTML. - A badge (i.e., shield, status icon) on our front-facing
README.rst
documentation signifying the success of the most recent attempt to build and host this skeleton at RTD. - A top-level
sphinx
script, building Sphinx-based package documentation when manually run from the command line by interactive developers.
- A beautiful banner graphic that makes grown adults openly weep, featuring the official
beartype
mascot "Mr. Nectar Palm" – again courtesy @felix-hilden, because sleep is for the weak and Felix has never known the word. - A new prefacing "tl;dr" section that's redundant with numerous other sections, but we're surprisingly okay with that.
- A new "Usage" section that accidentally became a new tutorial and division of the existing "Overview" section into various subsections highlighting tradeoffs between
beartype
and existing type checkers, resolving clarity concerns raised by @kevinjacobs-progenity at issue #7. Thanks for the invaluable commentary, Kevin! - A new "Frequently Asked Questions (FAQ)" section, inspired by the admission from several prospective users that they have utterly no idea what @leycec is talking about. Fair play, users. You win this round.
- A new "Workflow" subsection of the "Developer" section, listing developer-specific instructions for forking, cloning, installing, modifying, and submitting PRs for
beartype
in a live manner. - Properly rendered code blocks, kindly reported by humane human extraordinaire @harens in discussion topic #28. Thanks and may the little-seen English sun eternally shine upon ye, Haren!
API Changed
- Added:
beartype.cave.CallableCTypes
.beartype.cave.HintGenericSubscriptedType
.
- Deprecated:
beartype.cave.HintPep585Type
.
(Exogenous exhaustion!)