-
-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This commit adds official support for the third-party `nptyping` package to @beartype, resolving feature requests #303 and #304 kindly submitted by shades-wearing Serbian superhero @peske (Aleksandar Pesic). Note this significant caveat to this support: **`nptyping` is currently unmaintained, suffers over 20 severe issues, and emits 7 severe NumPy deprecation warnings.** In other words, `nptyping` is a ticking time bomb likely to explode your codebase into tiny fragments that are steaming and shredding your fragile keyboard. All @beartype users are strongly advised to immediately transition from `nptyping` to @patrick-kidger's `jaxtyping`. Unlike `nptyping`, `jaxtyping` provides well-maintained type hints covering NumPy, JAX, PyTorch, and TensorFlow. It's pretty intense. It's also @beartype's [official FAQ recommendation for type-checking NumPy arrays](https://beartype.readthedocs.io/en/latest/faq/#numpy-arrays). Deprecations emitted by merely importing `nptyping` include: ``` /usr/lib/python3.12/site-packages/nptyping/typing_.py:51: DeprecationWarning: `np.bool8` is a deprecated alias for `np.bool_`. (Deprecated NumPy 1.24) Bool8 = np.bool8 /usr/lib/python3.12/site-packages/nptyping/typing_.py:54: DeprecationWarning: `np.object0` is a deprecated alias for ``np.object0` is a deprecated alias for `np.object_`. `object` can be used instead. (Deprecated NumPy 1.24)`. (Deprecated NumPy 1.24) Object0 = np.object0 /usr/lib/python3.12/site-packages/nptyping/typing_.py:66: DeprecationWarning: `np.int0` is a deprecated alias for `np.intp`. (Deprecated NumPy 1.24) Int0 = np.int0 /usr/lib/python3.12/site-packages/nptyping/typing_.py:80: DeprecationWarning: `np.uint0` is a deprecated alias for `np.uintp`. (Deprecated NumPy 1.24) UInt0 = np.uint0 /usr/lib/python3.12/site-packages/nptyping/typing_.py:107: DeprecationWarning: `np.void0` is a deprecated alias for `np.void`. (Deprecated NumPy 1.24) Void0 = np.void0 /usr/lib/python3.12/site-packages/nptyping/typing_.py:112: DeprecationWarning: `np.bytes0` is a deprecated alias for `np.bytes_`. (Deprecated NumPy 1.24) Bytes0 = np.bytes0 /usr/lib/python3.12/site-packages/nptyping/typing_.py:114: DeprecationWarning: `np.str0` is a deprecated alias for `np.str_`. (Deprecated NumPy 1.24) Str0 = np.str0 ``` Devbros don't let devbros import `nptyping`. *Not even once.* (*Casual dual assignation of a mutual assassination of casuistry!*)
- Loading branch information
Showing
11 changed files
with
227 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
107 changes: 107 additions & 0 deletions
107
beartype_test/a00_unit/a70_decor/a40_code/a00_module/test_decor_nptyping.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
#!/usr/bin/env python3 | ||
# --------------------( LICENSE )-------------------- | ||
# Copyright (c) 2014-2023 Beartype authors. | ||
# See "LICENSE" for further details. | ||
|
||
''' | ||
**Beartype decorator PEP-noncompliant** :mod:`nptyping` **type hint unit | ||
tests.** | ||
This submodule unit tests the :func:`beartype.beartype` decorator with respect | ||
to **PEP-noncompliant** :mod:`nptyping` **type hints** (i.e., | ||
:mod:`nptyping`-specific annotations *not* compliant with annotation-centric | ||
PEPs). | ||
''' | ||
|
||
# ....................{ IMPORTS }.................... | ||
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
# WARNING: To raise human-readable test errors, avoid importing from | ||
# package-specific submodules at module scope. | ||
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
from beartype_test._util.mark.pytskip import ( | ||
skip_if_python_version_less_than, | ||
skip_unless_package, | ||
) | ||
|
||
# ....................{ TESTS }.................... | ||
# If the active Python interpreter targets Python < 3.10.0, this interpreter | ||
# fails to support PEP 604-compliant new unions (e.g., "int | str") and thus the | ||
# entire point of this unit test. In this case, skip this test. | ||
@skip_if_python_version_less_than('3.10.0') | ||
@skip_unless_package('nptyping') | ||
def test_decor_nptyping() -> None: | ||
''' | ||
Test that the :func:`beartype.beartype` decorator successfully type-checks | ||
callables annotated by :mod:`nptyping` type hints. | ||
:mod:`nptyping` type hints violate Python typing standards in various ways. | ||
Notably, :mod:`nptyping` type hint factories dynamically generate unique | ||
classes that nonetheless share the same fully-qualified names, complicating | ||
caching in the :func:`beartype.beartype` decorator. | ||
Whereas this test suite automates testing of PEP-compliant type hints via | ||
the :mod:`beartype_test.a00_unit.data` subpackage, :mod:`nptyping` type | ||
hints are fundamentally non-standard and thus *cannot* be automated in this | ||
standard manner. These hints can *only* be tested with a non-standard | ||
workflow implemented by this unit test. | ||
''' | ||
|
||
# ....................{ IMPORTS }.................... | ||
# Defer test-specific imports. | ||
# | ||
# Note that nptyping requires NumPy. Ergo, NumPy is safely importable here. | ||
from beartype import beartype | ||
from beartype.roar import BeartypeCallHintParamViolation | ||
from numpy import ( | ||
array, | ||
float64, | ||
int64, | ||
sum as numpy_sum, | ||
) | ||
from nptyping import ( | ||
Float64, | ||
Int64, | ||
NDArray, | ||
Shape, | ||
) | ||
from pytest import raises | ||
|
||
# ....................{ LOCALS }.................... | ||
# Arbitrary NumPy arrays satisfied by "nptyping" type hints defined below. | ||
flashed_like_strong_inspiration = array( | ||
[[1., 2.], [3., 4.]], dtype=float64) | ||
till_meaning_on_his_vacant_mind = array( | ||
[1, 2, 3, 4, 5, 6], dtype=int64) | ||
|
||
# ....................{ FUNCTIONS }.................... | ||
@beartype | ||
def suspended_he_that_task( | ||
but_ever_gazed: NDArray[Shape['N, N'], Float64] | None = None, | ||
and_gazed: NDArray[Shape['*' ], Int64] | None = None, | ||
) -> int64 | None: | ||
''' | ||
Arbitrary callable annotated by two :pep:`604`-compliant new unions of | ||
distinct :mod:`nptyping` type hints and arbitrary other types. | ||
This callable exercises a `prominent edge case`_. | ||
.. _prominent edge case: | ||
https://github.com/beartype/beartype/issues/304 | ||
''' | ||
|
||
# Bend it like Bender. | ||
return None if and_gazed is None else numpy_sum(and_gazed) | ||
|
||
# ....................{ PASS }.................... | ||
# Assert that this callable returns the expected value when passed NumPy | ||
# arrays satisfying the "nptyping" type hints annotating this callable. | ||
assert suspended_he_that_task( | ||
but_ever_gazed=flashed_like_strong_inspiration, | ||
and_gazed=till_meaning_on_his_vacant_mind, | ||
) == 21 | ||
|
||
# ....................{ FAIL }.................... | ||
# Assert that this callable raises the expected exception when passed NumPy | ||
# arrays violating the "nptyping" type hints annotating this callable. | ||
with raises(BeartypeCallHintParamViolation): | ||
suspended_he_that_task(till_meaning_on_his_vacant_mind) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters