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
BUG: Shouldn't numpy's floating types (e.g. np.float_) and python's native float type be compatible? #23663
When trying to type hint functions accepting scalars, I get unexpected error messages from my type checker (Pylance). As np.float_ is a subtype of python's native float type, I would expect to be able to pass a variable with type np.float_ when a native float is expected.
Argument of type"float_" cannot be assigned to parameter "x" of type"float"infunction"idx""float_" is incompatible with "float" Pylance (reportGeneralTypeIssues)
Runtime information:
1.24.1
3.11.0 | packaged by conda-forge | (main, Jan 14 2023, 12:27:40) [GCC 11.3.0]
WARNING: threadpoolctl not found in system! Install it by pip install threadpoolctl. Once installed, try np.show_runtime again for more detailed build information
[{'simd_extensions': {'baseline': ['SSE', 'SSE2', 'SSE3'],
'found': ['SSSE3',
'SSE41',
'POPCNT',
'SSE42',
'AVX',
'F16C',
'FMA3',
'AVX2'],
'not_found': ['AVX512F',
'AVX512CD',
'AVX512_KNL',
'AVX512_KNM',
'AVX512_SKX',
'AVX512_CLX',
'AVX512_CNL',
'AVX512_ICL']}}]
None
Context for the issue:
This issue makes it either impossible or much harder to correctly type hint functions such that they are compatible with numpy.
changed the title [-]BUG: Shouldn't numpy's floating types (e.g. `np.float_`) and python's native `float` types be compatible?[/-][+]BUG: Shouldn't numpy's floating types (e.g. `np.float_`) and python's native `float` type be compatible?[/+]on Apr 25, 2023
FWIW, I'd probably just not use np.float_ there. Idiomatically, I'd just use dtype=float or dtype=np.float64. np.float_ and np.int_ are really there more for reference than for use in dtype= arguments.
You could, though the reason why the likes of np.floating subclasses (among a few others) are modeled as parametrized generics in the stub files is because, to put it mildly, it's incredibly difficult to determine the output bitsize for a given operation with the currently available typing tools and as such we generally have to resort to simply returning np.floating[Any] (arbitrary/unknown-sized float). Now, due to the presence of the Any-parameter and the fact that the likes of np.float64 are treated as sub-types but not proper subclasses, it means that you can freely cast from one to the other (while you cannot do the same for superclass -> subclass without some heavy handed use of typing.cast lest typecheckers can and will complain).
The downside of this approach is that information about the float superclass is lost from np.float64, simply because the various np.floating sub-types are all treated as exactly equivalent (barring their bit size). It might be an option instead to pretend that np.floating as a whole inherits from float (and the similarly with np.complexfloating and complex). This would technically be a lie, though I suspect it's a minor one and one that might be worth the effort (especially with the autrocious state of statically duck-typing scalars).
Activity
[-]BUG: Shouldn't numpy's floating types (e.g. `np.float_`) and python's native `float` types be compatible?[/-][+]BUG: Shouldn't numpy's floating types (e.g. `np.float_`) and python's native `float` type be compatible?[/+]MatteoRaso commentedon Apr 25, 2023
That's what the documentation says, but it seems that this isn't actually the case.Since this isn't actually the Python float type (only equivalent to it), this is probably why PyLance thinks that the two are incompatible.
rkern commentedon Apr 25, 2023
np.float64(whichnp.float_is just an alias for) is a subclass offloat.rkern commentedon Apr 25, 2023
FWIW, I'd probably just not use
np.float_there. Idiomatically, I'd just usedtype=floatordtype=np.float64.np.float_andnp.int_are really there more for reference than for use indtype=arguments.simonaltrogge commentedon May 9, 2023
Even if I change
np.float_tonp.float64, I still get an equivalent error message. I have submitted a corresponding bug report to microsoft/pylance-release (see microsoft/pylance-release#4332).rchiodo commentedon May 9, 2023
I think Pylance is correct here. The type float64 (at least in the type stubs) is defined like this:
where
floatingis a class that isn't derived from float:The MRO list at runtime isn't used by Pylance/Pyright. It's determined solely by the type heirarchy we can query statically.
If I change the definition of floating in the type stub to be like so:
Then the error reported by Pylance goes away.
rkern commentedon May 9, 2023
Well,
floatingdoesn't subclass fromfloat, onlyfloat64is.hmc-cs-mdrissi commentedon May 10, 2023
Hmm then similarly you could define float64 as,
BvB93 commentedon May 12, 2023
You could, though the reason why the likes of
np.floatingsubclasses (among a few others) are modeled as parametrized generics in the stub files is because, to put it mildly, it's incredibly difficult to determine the output bitsize for a given operation with the currently available typing tools and as such we generally have to resort to simply returningnp.floating[Any](arbitrary/unknown-sized float). Now, due to the presence of theAny-parameter and the fact that the likes ofnp.float64are treated as sub-types but not proper subclasses, it means that you can freely cast from one to the other (while you cannot do the same for superclass -> subclass without some heavy handed use oftyping.castlest typecheckers can and will complain).The downside of this approach is that information about the
floatsuperclass is lost fromnp.float64, simply because the variousnp.floatingsub-types are all treated as exactly equivalent (barring their bit size). It might be an option instead to pretend thatnp.floatingas a whole inherits fromfloat(and the similarly withnp.complexfloatingandcomplex). This would technically be a lie, though I suspect it's a minor one and one that might be worth the effort (especially with the autrocious state of statically duck-typing scalars).jorenham commentedon Aug 17, 2024
I believe that this is a duplicate of #21906