Open mathause opened 4 years ago
Great observation @mathause . I think there are two parts of this:
da.longitude
to raise a mypy error? That may be a tradeoff with raising the true error on da.isel
DataWithCoords
or add some Dataset_Or_DataArray
-like typeHaving methods like isel
typed would be a win I think
Do we want other libraries which do da.longitude to raise a mypy error? That may be a tradeoff with raising the true error on da.jsel
Good point. Given that the accessors are also going via __getattr__
I would not remove the typing. Due to the accessors it also needs to be -> Any
. In conclusion DataWithCoords
only makes sense as a mixin.
Good point re accessors, I hadn't considered those. So sounds like raising an error on da.isel
isn't possible regardless...
I think we can probably safely add @no_type_check
to __getattr__
here, though it's true DataWithCoords
was only intended as a mix-in.
Looking up coordinates with attributes like da.longitude
is a shortcut mostly intended for interactive use-cases. If you are type-checking your code for safely, you should likely prefer writing da['longitude']
to remove ambiguity about whether ds.longitude
is a method, accessor or DataArray object.
I can open a PR but is there a clean way to handle accessors?
Do you prefer ABC
s or NotImplementedError
for the missing methods in DataWithCoords
?
Has anyone tried this recently? For me mypy ignores the @no_type_check
decorator and never raises an error anyway.
I think raising errors on not defined attributes is useful for typos but will likely annoy people that use custom accessors or use the variable shortcut (although the latter apparently don't care about type checking anyway).
Has anyone tried this recently? For me mypy ignores the
@no_type_check
decorator and never raises an error anyway.
Figured it out: @no_type_check
only removes typing for arguments and returns, so basically the function behaves as untyped. What we want is that mypy thinks this method does not exist at all. This can only be done by wrapping the complete method definition with if not TYPE_CHECKING
.
In https://github.com/pydata/xarray/pull/8204 I have noticed that defining __getattr__
will make the class pass any Protocol checks. (Maybe that's a Mypy bug or just a very bad side effect that should raise a Mypy warning if done).
In #4592 I had the issue that mypy did not raise an error on a missing method:
This is because
DataWithCoords
implements__getattr__
:The solution seems to be to not typecheck
__getattr__
(see https://github.com/python/mypy/issues/6251#issuecomment-457287161):The only
__getattr__
within xarray is here:https://github.com/pydata/xarray/blob/17358922d480c038e66430735bf4c365a7677df8/xarray/core/common.py#L221
Using
@no_type_check
leads to 24 errors and not all of them can be trivially solved. E.g.DataWithCoords
wants of useself.isel
but does not implement the method. The solution is probably to addisel
toDataWithCoords
as anABC
or usingNotImplemented
.Thoughts?
All errors
Edit: one problem is certainly the method injection, as mypy cannot detect those types.