Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork10.9k
TYP: Typenp.ma.squeeze
andnp.ma.{mask_rows, mask_cols, mask_rowcols}
#28794
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
base:main
Are you sure you want to change the base?
Uh oh!
There was an error while loading.Please reload this page.
Conversation
@overload | ||
def mask_rows(a: _ArrayLike[_ScalarT_co]) -> MaskedArray[tuple[int, int], np.dtype[_ScalarT_co]]: ... | ||
@overload | ||
def mask_rows(a: ArrayLike) -> MaskedArray[tuple[int, int], np.dtype[Any]]: ... | ||
@overload | ||
def mask_cols(a: _ArrayLike[_ScalarT_co]) -> MaskedArray[tuple[int, int], np.dtype[_ScalarT_co]]: ... | ||
@overload | ||
def mask_cols(a: ArrayLike) -> MaskedArray[tuple[int, int], np.dtype[Any]]: ... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
technically these both accept aaxis
argument, but it emits a deprecationwarning, so i've left it out of the stops so as to discourage its usage
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
*stubs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Hmmstubtest
won't like that. What I usually do in these situations, is add another@overload
with theaxis
kwarg that has no default, and mark it as@deprecated
. See e.g.
numpy/numpy/_core/arrayprint.pyi
Lines 88 to 180 in1bc8764
# public numpy export | |
@overload# no style | |
defarray2string( | |
a:NDArray[Any], | |
max_line_width:int|None=None, | |
precision:SupportsIndex|None=None, | |
suppress_small:bool|None=None, | |
separator:str=" ", | |
prefix:str="", | |
style:_NoValueType= ..., | |
formatter:_FormatDict|None=None, | |
threshold:int|None=None, | |
edgeitems:int|None=None, | |
sign:_Sign|None=None, | |
floatmode:_FloatMode|None=None, | |
suffix:str="", | |
*, | |
legacy:_Legacy|None=None, | |
)->str: ... | |
@overload# style=<given> (positional), legacy="1.13" | |
defarray2string( | |
a:NDArray[Any], | |
max_line_width:int|None, | |
precision:SupportsIndex|None, | |
suppress_small:bool|None, | |
separator:str, | |
prefix:str, | |
style:_ReprFunc, | |
formatter:_FormatDict|None=None, | |
threshold:int|None=None, | |
edgeitems:int|None=None, | |
sign:_Sign|None=None, | |
floatmode:_FloatMode|None=None, | |
suffix:str="", | |
*, | |
legacy:Literal["1.13"], | |
)->str: ... | |
@overload# style=<given> (keyword), legacy="1.13" | |
defarray2string( | |
a:NDArray[Any], | |
max_line_width:int|None=None, | |
precision:SupportsIndex|None=None, | |
suppress_small:bool|None=None, | |
separator:str=" ", | |
prefix:str="", | |
*, | |
style:_ReprFunc, | |
formatter:_FormatDict|None=None, | |
threshold:int|None=None, | |
edgeitems:int|None=None, | |
sign:_Sign|None=None, | |
floatmode:_FloatMode|None=None, | |
suffix:str="", | |
legacy:Literal["1.13"], | |
)->str: ... | |
@overload# style=<given> (positional), legacy!="1.13" | |
@deprecated("'style' argument is deprecated and no longer functional except in 1.13 'legacy' mode") | |
defarray2string( | |
a:NDArray[Any], | |
max_line_width:int|None, | |
precision:SupportsIndex|None, | |
suppress_small:bool|None, | |
separator:str, | |
prefix:str, | |
style:_ReprFunc, | |
formatter:_FormatDict|None=None, | |
threshold:int|None=None, | |
edgeitems:int|None=None, | |
sign:_Sign|None=None, | |
floatmode:_FloatMode|None=None, | |
suffix:str="", | |
*, | |
legacy:_LegacyNoStyle|None=None, | |
)->str: ... | |
@overload# style=<given> (keyword), legacy="1.13" | |
@deprecated("'style' argument is deprecated and no longer functional except in 1.13 'legacy' mode") | |
defarray2string( | |
a:NDArray[Any], | |
max_line_width:int|None=None, | |
precision:SupportsIndex|None=None, | |
suppress_small:bool|None=None, | |
separator:str=" ", | |
prefix:str="", | |
*, | |
style:_ReprFunc, | |
formatter:_FormatDict|None=None, | |
threshold:int|None=None, | |
edgeitems:int|None=None, | |
sign:_Sign|None=None, | |
floatmode:_FloatMode|None=None, | |
suffix:str="", | |
legacy:_LegacyNoStyle|None=None, | |
)->str: ... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
thanks - how do you runstubtest
?
I've tried
spin run python -m mypy.stubtest numpy
but it seems to hang indefinitely. couldn't find anything else about it in the numpy repo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
At the moment stubtest is only used bynumtype. If you'd try to run it on numpy's bundled stubs, you'd get thousands of (accurate) errors. But properly fixing those would result in many breaking changes. And that'sone of the reasons for building numtype, actually. The plan is to eventually also be able to use stubtest in numpy, once the other features that I'm developing there (like shape-typing) are functional and sufficiently stable.
And as you've probably noted by now, I've been tracking yournp.ma
stubs changes, (numpy/numtype#456) with the intention of porting them over. So with that in mind, I'm trying to anticipate any stubtest errors. Because if those turn up when porting a numpy PR to numtype, then I'll eventually have to port those back from numtype to numpy again.
So to get the stubtest output, you could copy these changes to numtype (https://github.com/numpy/numtype/tree/main/src/numpy-stubs/ma), and thenuv run tool/stubtest.py
(seehttps://numpy.org/numtype/dev/ for details). It's also an option to first submit yourma
PR's there, and then port them over to numpy. It sounds pretty inefficient, but it ensures that thatstubtest
, mypy, and pyright (configured in the strictest of modes), are also happy.
And just to be clear; submitting your pr's to numpy is no problem as far as I'm concerned. It's just that we're a bit more in the dark here, CI-wise.
@overload | ||
def mask_rows(a: _ArrayLike[_ScalarT_co]) -> MaskedArray[tuple[int, int], np.dtype[_ScalarT_co]]: ... | ||
@overload | ||
def mask_rows(a: ArrayLike) -> MaskedArray[tuple[int, int], np.dtype[Any]]: ... | ||
@overload | ||
def mask_cols(a: _ArrayLike[_ScalarT_co]) -> MaskedArray[tuple[int, int], np.dtype[_ScalarT_co]]: ... | ||
@overload | ||
def mask_cols(a: ArrayLike) -> MaskedArray[tuple[int, int], np.dtype[Any]]: ... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Hmmstubtest
won't like that. What I usually do in these situations, is add another@overload
with theaxis
kwarg that has no default, and mark it as@deprecated
. See e.g.
numpy/numpy/_core/arrayprint.pyi
Lines 88 to 180 in1bc8764
# public numpy export | |
@overload# no style | |
defarray2string( | |
a:NDArray[Any], | |
max_line_width:int|None=None, | |
precision:SupportsIndex|None=None, | |
suppress_small:bool|None=None, | |
separator:str=" ", | |
prefix:str="", | |
style:_NoValueType= ..., | |
formatter:_FormatDict|None=None, | |
threshold:int|None=None, | |
edgeitems:int|None=None, | |
sign:_Sign|None=None, | |
floatmode:_FloatMode|None=None, | |
suffix:str="", | |
*, | |
legacy:_Legacy|None=None, | |
)->str: ... | |
@overload# style=<given> (positional), legacy="1.13" | |
defarray2string( | |
a:NDArray[Any], | |
max_line_width:int|None, | |
precision:SupportsIndex|None, | |
suppress_small:bool|None, | |
separator:str, | |
prefix:str, | |
style:_ReprFunc, | |
formatter:_FormatDict|None=None, | |
threshold:int|None=None, | |
edgeitems:int|None=None, | |
sign:_Sign|None=None, | |
floatmode:_FloatMode|None=None, | |
suffix:str="", | |
*, | |
legacy:Literal["1.13"], | |
)->str: ... | |
@overload# style=<given> (keyword), legacy="1.13" | |
defarray2string( | |
a:NDArray[Any], | |
max_line_width:int|None=None, | |
precision:SupportsIndex|None=None, | |
suppress_small:bool|None=None, | |
separator:str=" ", | |
prefix:str="", | |
*, | |
style:_ReprFunc, | |
formatter:_FormatDict|None=None, | |
threshold:int|None=None, | |
edgeitems:int|None=None, | |
sign:_Sign|None=None, | |
floatmode:_FloatMode|None=None, | |
suffix:str="", | |
legacy:Literal["1.13"], | |
)->str: ... | |
@overload# style=<given> (positional), legacy!="1.13" | |
@deprecated("'style' argument is deprecated and no longer functional except in 1.13 'legacy' mode") | |
defarray2string( | |
a:NDArray[Any], | |
max_line_width:int|None, | |
precision:SupportsIndex|None, | |
suppress_small:bool|None, | |
separator:str, | |
prefix:str, | |
style:_ReprFunc, | |
formatter:_FormatDict|None=None, | |
threshold:int|None=None, | |
edgeitems:int|None=None, | |
sign:_Sign|None=None, | |
floatmode:_FloatMode|None=None, | |
suffix:str="", | |
*, | |
legacy:_LegacyNoStyle|None=None, | |
)->str: ... | |
@overload# style=<given> (keyword), legacy="1.13" | |
@deprecated("'style' argument is deprecated and no longer functional except in 1.13 'legacy' mode") | |
defarray2string( | |
a:NDArray[Any], | |
max_line_width:int|None=None, | |
precision:SupportsIndex|None=None, | |
suppress_small:bool|None=None, | |
separator:str=" ", | |
prefix:str="", | |
*, | |
style:_ReprFunc, | |
formatter:_FormatDict|None=None, | |
threshold:int|None=None, | |
edgeitems:int|None=None, | |
sign:_Sign|None=None, | |
floatmode:_FloatMode|None=None, | |
suffix:str="", | |
legacy:_LegacyNoStyle|None=None, | |
)->str: ... |
@overload | ||
def squeeze( | ||
a: _ScalarT, | ||
axis: _ShapeLike | None = ..., | ||
) -> _ScalarT: ... | ||
@overload | ||
def squeeze( | ||
a: _ArrayLike[_ScalarT], | ||
axis: _ShapeLike | None = ..., | ||
) -> _MaskedArray[_ScalarT]: ... | ||
@overload | ||
def squeeze( | ||
a: ArrayLike, | ||
axis: _ShapeLike | None = ..., | ||
) -> _MaskedArray[Any]: ... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
So it turns out that stubtest doesn't accept these being actual functions, and instead requires them to be instances ofnumpy.ma.core._convert2ma
. You can see this innumpy/numtype#468. It's currently a WIP, but there I (attempted to) explain how the_convert2ma
can be made generic on it's__call__
signature, so that a callableProtocol
can be used to specify the signature. It's a bit messy, but I'm afraid that it's the only way that stubtest well be able to swallow it.
Are you willing to attempt doing this here as well, or would you prefer that we address this at a later point?
@overload | ||
def mask_rows(a: _ArrayLike[_ScalarT_co]) -> MaskedArray[tuple[int, int], np.dtype[_ScalarT_co]]: ... | ||
@overload | ||
def mask_rows(a: ArrayLike) -> MaskedArray[tuple[int, int], np.dtype[Any]]: ... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
defmask_rows(a:ArrayLike)->MaskedArray[tuple[int,int],np.dtype[Any]]: ... | |
defmask_rows(a:ArrayLike)->MaskedArray[tuple[int,int],np.dtype]: ... |
from .core import ( | ||
MaskedArray, | ||
dot, | ||
_ScalarT_co, | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
from .coreimport ( | |
MaskedArray, | |
dot, | |
_ScalarT_co, | |
) | |
from .coreimportMaskedArray,dot,_ScalarT_co |
from numpy.typing import ArrayLike | ||
from numpy._typing import _ArrayLike |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
nitpick: usually we also importArrayLike
from_typing
internally
fromnumpy.typingimportArrayLike | |
fromnumpy._typingimport_ArrayLike | |
fromnumpy._typingimportArrayLike,_ArrayLike |
@@ -29,6 +29,8 @@ MAR_V: MaskedNDArray[np.void] | |||
MAR_subclass: MaskedNDArraySubclass | |||
MAR_1d: np.ma.MaskedArray[tuple[int], np.dtype] | |||
MAR_2d: np.ma.MaskedArray[tuple[int, int], np.dtype[Any]] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
MAR_2d:np.ma.MaskedArray[tuple[int,int],np.dtype[Any]] | |
MAR_2d:np.ma.MaskedArray[tuple[int,int],np.dtype] |
assert_type(np.ma.mask_rows(MAR_f4), np.ma.MaskedArray[tuple[int, int], np.dtype[np.float32]]) | ||
assert_type(np.ma.mask_rows([[1,2,3]]), np.ma.MaskedArray[tuple[int, int], np.dtype]) | ||
# PyRight detects this one correctly, but mypy doesn't. | ||
assert_type(np.ma.mask_rows(MAR_2d), np.ma.MaskedArray[tuple[int, int], np.dtype]) # type: ignore[assert-type] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
what does mypy infer it as?
assert_type(np.ma.mask_rows(MAR_2d_f4), np.ma.MaskedArray[tuple[int, int], np.dtype[np.float32]]) | ||
assert_type(np.ma.mask_rows(MAR_f4), np.ma.MaskedArray[tuple[int, int], np.dtype[np.float32]]) | ||
assert_type(np.ma.mask_rows([[1,2,3]]), np.ma.MaskedArray[tuple[int, int], np.dtype]) | ||
# PyRight detects this one correctly, but mypy doesn't. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Athttps://github.com/microsoft/pyright it's written as "Pyright" 🤷🏻
#PyRight detects this one correctly, but mypy doesn't. | |
#Pyright detects this one correctly, but mypy doesn't. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
There are several-> MaskedArray[tuple[int, int], np.dtype[...]]
annotations in this module now. A private type-alias could help make it more dry.
needs a rebase |
No description provided.