[Upstream Bug] Please notify NumPy that `numpy.typing.DTypeLike` is broken
See original GitHub issueHi,
Once again I feel bad to open a new issue (although I learned more in the last one than in some Python tutorials). But there is once again a feature that would make beartype even better (for myself). I guess that the np.typing.DTypeLike
is not supported. Nevertheless, this issue is not urgent at all. There is a simple Annotation to implement an DTypeLike
type within beartype.
This time I was smart enough to execute my example as a script to get more helpful error messages. I am using Python==3.10.4
, beartype==0.10.4
and numpy==1.21.6
from typing import Annotated
import numpy as np
import numpy.typing as npt
from beartype import beartype
from beartype.vale import Is
@beartype
def f(x: npt.NDArray) -> npt.NDArray:
return x
# this runs fine
mat = np.zeros((4, 4))
f(mat)
DTypeLike = Annotated[
type, Is[lambda dtype: np.issubdtype(dtype, np.generic)],
]
@beartype
def g(x: npt.NDArray, dtype: DTypeLike) -> npt.NDArray:
return x.astype(dtype)
# runs fine
g(mat, dtype=np.float64)
# and throws expected error
g(mat, dtype='no_type')
@beartype
def h(x: npt.NDArray, dtype: npt.DTypeLike) -> npt.NDArray:
return x.astype(dtype)
# this runs following error
h(mat, dtype=np.float64)
Using the npt.DTypeLike
class throws following error:
/home/user/anaconda3/envs/mosaic/lib/python3.10/site-packages/beartype/_util/hint/pep/utilpeptest.py:317: BeartypeDecorHintPep585DeprecationWarning: PEP 484 type hint typing.Tuple[typing.Any, int] deprecated by PEP 585 scheduled for removal in the first Python version released after October 5th, 2025. To resolve this, import this hint from "beartype.typing" rather than "typing". See this discussion for further details and alternatives:
https://github.com/beartype/beartype#pep-585-deprecations
warn(
/home/user/anaconda3/envs/mosaic/lib/python3.10/site-packages/beartype/_util/hint/pep/utilpeptest.py:317: BeartypeDecorHintPep585DeprecationWarning: PEP 484 type hint typing.Tuple[typing.Any, typing.Any] deprecated by PEP 585 scheduled for removal in the first Python version released after October 5th, 2025. To resolve this, import this hint from "beartype.typing" rather than "typing". See this discussion for further details and alternatives:
https://github.com/beartype/beartype#pep-585-deprecations
warn(
/home/user/anaconda3/envs/mosaic/lib/python3.10/site-packages/beartype/_util/hint/pep/utilpeptest.py:317: BeartypeDecorHintPep585DeprecationWarning: PEP 484 type hint typing.List[typing.Any] deprecated by PEP 585 scheduled for removal in the first Python version released after October 5th, 2025. To resolve this, import this hint from "beartype.typing" rather than "typing". See this discussion for further details and alternatives:
https://github.com/beartype/beartype#pep-585-deprecations
warn(
Traceback (most recent call last):
File "/home/user/anaconda3/envs/mosaic/lib/python3.10/site-packages/beartype/_util/cls/pep/utilpep3119.py", line 124, in die_unless_type_isinstanceable
isinstance(None, cls) # type: ignore[arg-type]
File "/home/user/anaconda3/envs/mosaic/lib/python3.10/typing.py", line 1497, in __instancecheck__
raise TypeError("Instance and class checks can only be used with"
TypeError: Instance and class checks can only be used with @runtime_checkable protocols
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/user/Documents/test_beartype/dtype.py", line 35, in <module>
def h(x: npt.NDArray, dtype: npt.DTypeLike) -> npt.NDArray:
File "/home/user/anaconda3/envs/mosaic/lib/python3.10/site-packages/beartype/_decor/cache/cachedecor.py", line 77, in beartype
return beartype_args_mandatory(obj, conf)
File "/home/user/anaconda3/envs/mosaic/lib/python3.10/site-packages/beartype/_decor/_core.py", line 140, in beartype_args_mandatory
return _beartype_func(func=obj, conf=conf)
File "/home/user/anaconda3/envs/mosaic/lib/python3.10/site-packages/beartype/_decor/_core.py", line 171, in _beartype_func
func_wrapper_code = generate_code(func_data)
File "/home/user/anaconda3/envs/mosaic/lib/python3.10/site-packages/beartype/_decor/_code/codemain.py", line 222, in generate_code
code_check_params = _code_check_args(bear_call)
File "/home/user/anaconda3/envs/mosaic/lib/python3.10/site-packages/beartype/_decor/_code/codemain.py", line 470, in _code_check_args
reraise_exception_placeholder(
File "/home/user/anaconda3/envs/mosaic/lib/python3.10/site-packages/beartype/_util/error/utilerror.py", line 202, in reraise_exception_placeholder
raise exception.with_traceback(exception.__traceback__)
File "/home/user/anaconda3/envs/mosaic/lib/python3.10/site-packages/beartype/_decor/_code/codemain.py", line 445, in _code_check_args
) = pep_code_check_hint(hint)
File "/home/user/anaconda3/envs/mosaic/lib/python3.10/site-packages/beartype/_util/cache/utilcachecall.py", line 343, in _callable_cached
raise exception
File "/home/user/anaconda3/envs/mosaic/lib/python3.10/site-packages/beartype/_util/cache/utilcachecall.py", line 335, in _callable_cached
return_value = params_flat_to_return_value[params_flat] = func(
File "/home/user/anaconda3/envs/mosaic/lib/python3.10/site-packages/beartype/_decor/_code/_pep/_pephint.py", line 1951, in pep_code_check_hint
hint_curr_expr=add_func_scope_type(
File "/home/user/anaconda3/envs/mosaic/lib/python3.10/site-packages/beartype/_decor/_code/_pep/_pepscope.py", line 198, in add_func_scope_type
die_unless_type_isinstanceable(cls=cls, exception_prefix=exception_prefix)
File "/home/user/anaconda3/envs/mosaic/lib/python3.10/site-packages/beartype/_util/cls/pep/utilpep3119.py", line 165, in die_unless_type_isinstanceable
raise exception_cls(exception_message) from exception
beartype.roar.BeartypeDecorHintPep3119Exception: @beartyped g() parameter "dtype" type hint <class 'numpy.typing._dtype_like._SupportsDType'> uncheckable at runtime (i.e., not passable
Issue Analytics
- State:
- Created a year ago
- Comments:6 (4 by maintainers)
Top Results From Across the Web
Support for `numpy.typing.NDArray` · Issue #195 - GitHub
Right now, typeguard doesn't check that the dtype is respected, and doesn't emit notifications when passed a ndarray that has the wrong dtype...
Read more >Typing (numpy.typing) — NumPy v1.24 Manual
Users who want to write statically typed code should instead use the numpy.ndarray.view method to create a view of the array with a...
Read more >No module named 'numpy.typing'" - Stack Overflow
I am trying to import ArrayLike doing from numpy.typing import ArrayLike , and I get the error mentioned in the title:.
Read more >New Tumbleweed snapshot 20210710 released!
New Tumbleweed snapshot 20210710 released! ... Please note that this mail was generated by a script. The described changes are computed based on...
Read more >Contributing to the code base — pandas 1.5.2 documentation
This can be expressed as a string like "object" , a numpy.dtype like ... pandas uses mypy and pyright to statically analyze the...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@leycec thank you so much for this helpful answer. Once again you have brought a PEP to my attention. Thx for that 😃 I tried applying the
@runtime_checkable
to the_SupportDType
class, but it still seems to fail. I guess it is related with the other types used in theDTypeLike
union/definition, probably thedtype
class. I will open an issue on numpy this weekend, and will try to suggest a fix. Would be freaking cool contributing to numpy.Ah-ha! Thanks so much for yet another blisteringly smart feature request. Thankfully for my Tuesday evening, this (surprise!) is an upstream NumPy issue. Me: 😮
You Say Wut
Here’s why. Ever heard of PEP 544-style
typing.Protocol
-based structural subtyping? Gr8, m8. We laboriously continue. PEP 544 is more than slightly nonsensical, because it requires third-party protocol authors (…like NumPy) to explicitly opt-in to runtime type-checking. That is to say, you have to manually decorate every single protocol you ever declare with the otherwise useless@typing.runtime_checkable
decorator: e.g.,Guess which kind of protocols NumPy defines? Yes. That’s right, good friend. NumPy authors forgot to manually decorate their protocols with
@runtime_checkable
, which is why @beartype and other runtime type-checkers (e.g.,typeguard
) vomit all over themselves when presented with those protocols.This is why I growl to myself in an unseemly manner.
What We Goin’ Do Is Dis
Would you mind submitting this exact same issue to NumPy’s upstream issue tracker, @braniii? If you’d like to force a NumPy contribution into your already stunning resume, …always looks hot, bro 😎 you might even submit a PR resolving this.
Fortunately for your Tuesday evening, I’ve already dissected this for you. What you’d need to do is exactly this…
If you have even more spare open-source seconds to hurl at this demonstrable problem that will explosively blow up again and again in your face, you might also crawl through the
numpy.typing
subpackage and do the exact same thing for every other protocol. Notably, I see a similarly problematic:numpy.typing._array_like._SupportsArray
protocol.numpy.typing._nested_sequence._NestedSequence
protocol.Whatever you manage to do: thanks soooo much, Danny N.! You make the world a safer place for the quiet data scientists who prowl amongst us.