You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
numpy.typing uint8 becomes signedinteger on multiplication #22631
When using numpy.typing, multiplying an array with dtype uint8 by any integer converts the typing dtype to signedinteger
Reproduce the code example:
importnumpyasnpfromnumpy.typingimportNDArraydefget_uint8() ->NDArray[np.uint8]:
returnnp.random.rand(3).astype(np.uint8)
a=get_uint8() # a is correctly NDArray[np.uint8]b=a*1# b is NDArray[signedinteger]
Error message:
`b`in the code shows as `NDArray[signedinteger]`, instead of `NDArray[np.uint8]`
I'm using numpy.typing to differentiate between some arrays of type uint8 and some arrays of type float32. However, I have to use a cast every time I multiply an array by a number, which compromises the effectiveness of type checking.
I believe this is due to numpy's type promotion rules to prevent data loss from mathematical operations. You can test this behavior with np.result_type, and see the linked page for details.
>>> np.result_type(np.uint8, int)
dtype('int64')
I agree this is annoying for static type checking, and I understand numpy's rationales for doing type promotion. Certainly, static type annotations currently have no influence on the actual numpy data types at the moment.
Replacing constant with uint8 is dangerous if the other side may be a scalar with a small value currently.
From a runtime perspective, I guess you are effectively getting what you want (although you probably want NEP 50). As I understand it, the problem with typing, although I am not sure if there can be a reasonable solution without NEP 50 (or similar) to remove the value-dependency of the current results.
Activity
kwsp commentedon Nov 20, 2022
I believe this is due to numpy's type promotion rules to prevent data loss from mathematical operations. You can test this behavior with
np.result_type, and see the linked page for details.I agree this is annoying for static type checking, and I understand numpy's rationales for doing type promotion. Certainly, static type annotations currently have no influence on the actual numpy data types at the moment.
hughperkins commentedon Nov 20, 2022
How to work around it? Need to replace all constants with e.g.
np.array([1], np.uint8)?hughperkins commentedon Nov 20, 2022
(Just checked, and this workaround does work)
seberg commentedon Dec 7, 2022
Replacing constant with uint8 is dangerous if the other side may be a scalar with a small value currently.
From a runtime perspective, I guess you are effectively getting what you want (although you probably want NEP 50). As I understand it, the problem with typing, although I am not sure if there can be a reasonable solution without NEP 50 (or similar) to remove the value-dependency of the current results.
hughperkins commentedon Jan 7, 2025
awesome 🙌