-
-
Notifications
You must be signed in to change notification settings - Fork 10.8k
ENH: Make np.number
generic with respect to its precision
#17540
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@BvB93 this makes me slightly worried about the extreme complexity involved. But this is just about the scalar types, right? I.e. no mixed scalars-arrays, no array-array operations? And also it is just about the basic math operators? In that case, I suppose its special enough to just do this. More generically for array-ops and ufuncs, there is no reason to get access to runtime behaviour? Promotion rules are not simple and I would like promotion rules to be customizable (not that it should be used a lot, but there are tricky cases e.g. for datetimes). There is another difficulty here, which maybe you can ignore. In that 0-D arrays, use "value-based promotion" and their precision is sometimes demoted. It would be great to get rid of that in the long run (except probably for Python floats/ints), but we are not close. |
Correct, this PR only affects the basic scalar + scalar bitwise and arithmetic operations.
Can you clarify what you mean with this statement?
Yup, for the number types themselves (integer, floating, etc) there is no escaping the duplication process.
Yes, I've noticed this in previous PRs when typing |
The CI failure is expected as the tests still have to be updated. |
* Removed redundant `type: ignore` messages * Set the return precision as `Union[_NBit_co, _NBit]` * Type the precision of `builtins.int` operations as `Any`
Mypy uses a `*` whenever an annotation or one of its parameters is based on a TypeVar. Its added value is neglible and it unnecessarily complicates the `reveal` tests so lets just ignore them. Note that this is done after running mypy, so it won't affect cases where `*` is used as multiplication operator.
Any further comments on this PR? |
It seems to be desirable to use more generic expressions but I do think it would be nice to have a shorter alias like |
Thanks @BvB93 |
I completely agree with this. |
This pull request makes
np.number
generic with respect to its precision, the latter beingrepresented by a hierarchical set of subclasses during while type checking.
The Problem
A challenge which became apparent during the typing of the arithmetic magic methods was
"how to deal with the issue of numerical precision?", e.g. how to express
float16 + int64 -> float64
.The most "straightforward" option would be to brute force the issue and simply add more
overloads, or if we're feeling particularly fancy to let a mypy plugin deal with the precision.
Both approaches suffer from a serious drawback though, namely that its scope will be limited
to a small subset of predetermined functions/methods (e.g. the arithmetic and bitwise ops).
This is undesirable for such a common pattern.
The Solution
This PR attempts to resolve the precision issue via an alternative approach the , one where
np.number
is made generic w.r.t its precision. The latter allows one to, quite compactly,annotate any function in a manner as demonstrated below:
The Details
To accomplish this the PR does the following two things:
number
s numerical precision(
numpy.typing.NBitBase
). The classes hierarchical structure makes it easy to infer the returntypes' precision, i.e. find the common baseclass (a task which impossible with
Literal
s for example).np.number
generic w.r.t. the newly introducedNBitBase
class.As is demonstrated below, a consequence of this approach is that while the likes of
float64
are stillsubtypes of
floating
they are no longer treated as formal subclasses (while type checking that is).TODO