pydata / xarray

N-D labeled arrays and datasets in Python
https://xarray.dev
Apache License 2.0
3.57k stars 1.07k forks source link

mypy 1.10.0 fails with matplotlib wrappers #9155

Open singledoggy opened 3 months ago

singledoggy commented 3 months ago

What is your issue?

Pyright is a full-featured, standards-based static type checker for Python, recently I tried it with xarray and get an error. And mypy generates the same error. So I wonder if we can fix this error, although this error won't have any impacts except for static type checker errors.

I have been using xarray for several years and recently began using Pyright. However, I encountered the following error: Argument missing for parameter 'self' Although my code still executes normally, I am curious about the cause of this error. Is this behavior expected?

import xarray as xr
import matplotlib.pyplot as plt
data = xr.DataArray([1, 2, 3], dims=['x'])
fig, ax= plt.subplots(ncols=1, nrows=1)
data.plot(ax=ax)

It seems to related to the codes here:

    plot = utils.UncachedAccessor(DataArrayPlotAccessor)
class UncachedAccessor(Generic[_Accessor]):
    """Acts like a property, but on both classes and class instances

    This class is necessary because some tools (e.g. pydoc and sphinx)
    inspect classes for which property returns itself and not the
    accessor.
    """

    def __init__(self, accessor: type[_Accessor]) -> None:
        self._accessor = accessor

    @overload
    def __get__(self, obj: None, cls) -> type[_Accessor]: ...

    @overload
    def __get__(self, obj: object, cls) -> _Accessor: ...

    def __get__(self, obj: None | object, cls) -> type[_Accessor] | _Accessor:
        if obj is None:
            return self._accessor

        return self._accessor(obj)  # type: ignore  # assume it is a valid accessor!

Here is my xarray version:

xarray                    2023.2.0           pyhd8ed1ab_0    conda-forge

Originally posted by @singledoggy in https://github.com/pydata/xarray/discussions/9150

Pyright is behaving correctly here. Not surprisingly, mypy generates the same error.

The problem appears to be in the xarray library here:

class DataArrayPlotAccessor:
    ...
    @functools.wraps(dataarray_plot.plot, assigned=("__doc__", "__annotations__"))
    def __call__(self, **kwargs) -> Any:
        return dataarray_plot.plot(self._da, **kwargs)

Originally posted by @erictraut in https://github.com/microsoft/pyright/discussions/8203#discussioncomment-9846958

welcome[bot] commented 3 months ago

Thanks for opening your first issue here at xarray! Be sure to follow the issue template! If you have an idea for a solution, we would really welcome a Pull Request with proposed changes. See the Contributing Guide for more. It may take us a while to respond here, but we really value your contribution. Contributors like you help make xarray better. Thank you!

max-sixty commented 3 months ago

Is the error still present on a recent version of xarray?

singledoggy commented 3 months ago

Before, I only read through the latest code and didn't find any relevant changes. I just had time to test the latest version, but the issue still persists.

max-sixty commented 3 months ago

OK. Mypy does pass — so if you find a mypy error in the current version then that's news, we'd like to understand that.

We do have a pyright job in CI, but it doesn't pass and so the check is allowed to fail. We're definitely open to contributions that improve it, and probably we'd be happy to turn on the check if we could get everything to pass.

Though it's not feasible to have an open issue for every pyright error so we can close this unless there's more info; hope that's reasonable.

singledoggy commented 3 months ago

mypy also get this error

As @erictraut points out here, mypy wil generate the same error. I also tested it with command: mypy test.py with the latest version (v2024.06.0) by myself.

It's reasonable if you choose to close this issue.

import xarray as xr
import matplotlib.pyplot as plt

data = xr.DataArray([1, 2, 3], dims=["x"])
fig, ax = plt.subplots(ncols=1, nrows=1)
data.plot(ax=ax)
test.py:6: error: Missing positional argument "self" in call to "__call__" of "_Wrapped"  [call-arg]
Found 1 error in 1 file (checked 1 source file)

Version information

INSTALLED VERSIONS
------------------
commit: None
python: 3.10.12 | packaged by conda-forge | (main, Jun 23 2023, 22:39:40) [Clang 15.0.7 ]
python-bits: 64
OS: Darwin
OS-release: 22.3.0
machine: x86_64
processor: i386
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8
LOCALE: ('en_US', 'UTF-8')
libhdf5: 1.12.2
libnetcdf: 4.9.1

xarray: 2024.6.0
pandas: 2.2.2
numpy: 1.25.2
scipy: 1.11.2
netCDF4: 1.6.3
pydap: None
h5netcdf: None
h5py: None
zarr: None
cftime: 1.6.2
nc_time_axis: None
iris: None
bottleneck: None
dask: 2023.8.1
distributed: 2023.8.1
matplotlib: 3.8.4
cartopy: 0.23.0
seaborn: 0.13.2
numbagg: None
fsspec: 2023.6.0
cupy: None
pint: None
sparse: None
flox: None
numpy_groupies: None
setuptools: 68.1.2
pip: 23.2.1
conda: None
pytest: None
mypy: 1.10.0
IPython: 8.14.0
max-sixty commented 3 months ago

Thanks for the example and mypy output.

I see now — it's that our mypy version in CI is a bit out of date, and it does indeed raise an error with the newer mypy 1.10.0. Thanks for helping debug it.

I'll adjust the title of the issue if that's OK

max-sixty commented 3 months ago

I (edit: can't) immediately see what's going on, so I'll have to leave it for the moment. (If anyone wants to dive in, that would be great).

Thanks for finding it @singledoggy

headtr1ck commented 3 months ago

Just ran into the same problem. Also when running mypy on xarray codebase (-> 70 errors)

headtr1ck commented 3 months ago

Looks like https://github.com/python/mypy/issues/17166