From 76280ad723a7028d3661f8fb7df7218ddc086e3f Mon Sep 17 00:00:00 2001 From: Guido Imperiale Date: Fri, 17 Jan 2020 16:55:08 +0000 Subject: [PATCH 1/8] Fix mypy --strict --- doc/whats-new.rst | 2 ++ xarray/__init__.py | 53 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index a60419f89a3..a2c2dd709fb 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -87,6 +87,8 @@ Bug fixes - Fix a regression in :py:meth:`Dataset.drop`: allow passing any iterable when dropping variables (:issue:`3552`, :pull:`3693`) By `Justus Magin `_. +- Fixed errors emitted by ``mypy --strict`` in modules that import xarray. + (:issue:`3695) by `Guido Imperiale `_. Documentation ~~~~~~~~~~~~~ diff --git a/xarray/__init__.py b/xarray/__init__.py index 394dd0f80bc..0b44c293b3f 100644 --- a/xarray/__init__.py +++ b/xarray/__init__.py @@ -1,5 +1,4 @@ """ isort:skip_file """ -# flake8: noqa from ._version import get_versions @@ -42,3 +41,55 @@ from . import testing from .core.common import ALL_DIMS + +# A hardcoded __all__ variable is necessary to appease +# `mypy --strict` running in projects that import xarray. +__all__ = ( + # Sub-packages + "ufuncs", + "testing", + "tutorial", + # Top-level functions + "align", + "apply_ufunc", + "as_variable", + "auto_combine", + "broadcast", + "cftime_range", + "combine_by_coords", + "combine_nested", + "concat", + "decode_cf", + "dot", + "full_like", + "load_dataarray", + "load_dataset", + "map_blocks", + "merge", + "ones_like", + "open_dataarray", + "open_dataset", + "open_mfdataset", + "open_rasterio", + "open_zarr", + "register_dataarray_accessor", + "register_dataset_accessor", + "save_mfdataset", + "set_options", + "show_versions", + "where", + "zeros_like", + # Classes + "CFTimeIndex", + "Coordinate", + "DataArray", + "Dataset", + "IndexVariable", + "Variable", + # Exceptions + "MergeError", + "SerializationWarning", + # Constants + "__version__", + "ALL_DIMS", +) From 2b30d56554f746b3c5f8cf73313de135bd28488f Mon Sep 17 00:00:00 2001 From: Guido Imperiale Date: Fri, 17 Jan 2020 16:55:21 +0000 Subject: [PATCH 2/8] isort --- xarray/core/dataset.py | 2 +- xarray/core/duck_array_ops.py | 2 +- xarray/core/parallel.py | 2 +- xarray/tests/test_accessor_dt.py | 3 +-- xarray/tests/test_units.py | 1 + 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index 4564dc80a8a..e069537348a 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -92,8 +92,8 @@ IndexVariable, Variable, as_variable, - broadcast_variables, assert_unique_multiindex_level_names, + broadcast_variables, ) if TYPE_CHECKING: diff --git a/xarray/core/duck_array_ops.py b/xarray/core/duck_array_ops.py index 98b371ab7c3..3fa97f0b448 100644 --- a/xarray/core/duck_array_ops.py +++ b/xarray/core/duck_array_ops.py @@ -11,7 +11,7 @@ import numpy as np import pandas as pd -from . import dask_array_ops, dask_array_compat, dtypes, npcompat, nputils +from . import dask_array_compat, dask_array_ops, dtypes, npcompat, nputils from .nputils import nanfirst, nanlast from .pycompat import dask_array_type diff --git a/xarray/core/parallel.py b/xarray/core/parallel.py index e4fb5803191..facfa06b23c 100644 --- a/xarray/core/parallel.py +++ b/xarray/core/parallel.py @@ -13,8 +13,8 @@ from typing import ( Any, Callable, - Dict, DefaultDict, + Dict, Hashable, Mapping, Sequence, diff --git a/xarray/tests/test_accessor_dt.py b/xarray/tests/test_accessor_dt.py index 67ca12532c7..f178720a6e1 100644 --- a/xarray/tests/test_accessor_dt.py +++ b/xarray/tests/test_accessor_dt.py @@ -11,8 +11,7 @@ requires_cftime, requires_dask, ) - -from .test_dask import raise_if_dask_computes, assert_chunks_equal +from .test_dask import assert_chunks_equal, raise_if_dask_computes class TestDatetimeAccessor: diff --git a/xarray/tests/test_units.py b/xarray/tests/test_units.py index 2cb1550c088..6f9128839a7 100644 --- a/xarray/tests/test_units.py +++ b/xarray/tests/test_units.py @@ -7,6 +7,7 @@ import xarray as xr from xarray.core import formatting from xarray.core.npcompat import IS_NEP18_ACTIVE + from .test_variable import VariableSubclassobjects pint = pytest.importorskip("pint") From 572ee5755bd95f05a123389bdf56c8a45a549337 Mon Sep 17 00:00:00 2001 From: Guido Imperiale Date: Fri, 17 Jan 2020 17:08:14 +0000 Subject: [PATCH 3/8] mypy version bump --- .pre-commit-config.yaml | 2 +- ci/requirements/py36-min-all-deps.yml | 2 +- ci/requirements/py36.yml | 2 +- ci/requirements/py37-windows.yml | 2 +- ci/requirements/py37.yml | 2 +- xarray/core/computation.py | 2 +- xarray/core/dataset.py | 6 +++--- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 502120cd5dc..ed62c1c256e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,7 +11,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.730 # Must match ci/requirements/*.yml + rev: v0.761 # Must match ci/requirements/*.yml hooks: - id: mypy # run these occasionally, ref discussion https://github.com/pydata/xarray/pull/3194 diff --git a/ci/requirements/py36-min-all-deps.yml b/ci/requirements/py36-min-all-deps.yml index 3f10a158f91..e7756172311 100644 --- a/ci/requirements/py36-min-all-deps.yml +++ b/ci/requirements/py36-min-all-deps.yml @@ -25,7 +25,7 @@ dependencies: - iris=2.2 - lxml=4.4 # Optional dep of pydap - matplotlib=3.1 - - mypy=0.730 # Must match .pre-commit-config.yaml + - mypy=0.761 # Must match .pre-commit-config.yaml - nc-time-axis=1.2 - netcdf4=1.4 - numba=0.44 diff --git a/ci/requirements/py36.yml b/ci/requirements/py36.yml index 820160b19cc..7450fafbd86 100644 --- a/ci/requirements/py36.yml +++ b/ci/requirements/py36.yml @@ -21,7 +21,7 @@ dependencies: - iris - lxml # optional dep of pydap - matplotlib - - mypy=0.730 # Must match .pre-commit-config.yaml + - mypy=0.761 # Must match .pre-commit-config.yaml - nc-time-axis - netcdf4 - numba diff --git a/ci/requirements/py37-windows.yml b/ci/requirements/py37-windows.yml index 614a3bb1fab..d9e634c74ae 100644 --- a/ci/requirements/py37-windows.yml +++ b/ci/requirements/py37-windows.yml @@ -21,7 +21,7 @@ dependencies: - iris - lxml # Optional dep of pydap - matplotlib - - mypy=0.730 # Must match .pre-commit-config.yaml + - mypy=0.761 # Must match .pre-commit-config.yaml - nc-time-axis - netcdf4 - numba diff --git a/ci/requirements/py37.yml b/ci/requirements/py37.yml index 4a7aaf7d32b..2f879e29f87 100644 --- a/ci/requirements/py37.yml +++ b/ci/requirements/py37.yml @@ -21,7 +21,7 @@ dependencies: - iris - lxml # Optional dep of pydap - matplotlib - - mypy=0.730 # Must match .pre-commit-config.yaml + - mypy=0.761 # Must match .pre-commit-config.yaml - nc-time-axis - netcdf4 - numba diff --git a/xarray/core/computation.py b/xarray/core/computation.py index 643c1137d6c..34de5edefc5 100644 --- a/xarray/core/computation.py +++ b/xarray/core/computation.py @@ -304,7 +304,7 @@ def _as_variables_or_variable(arg): def _unpack_dict_tuples( result_vars: Mapping[Hashable, Tuple[Variable, ...]], num_outputs: int ) -> Tuple[Dict[Hashable, Variable], ...]: - out = tuple({} for _ in range(num_outputs)) # type: ignore + out: Tuple[Dict[Hashable, Variable], ...] = tuple({} for _ in range(num_outputs)) for name, values in result_vars.items(): for value, results_dict in zip(values, out): results_dict[name] = value diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index e069537348a..82ddc8a535f 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -897,11 +897,11 @@ def _replace( if dims is not None: self._dims = dims if attrs is not _default: - self._attrs = attrs # type: ignore # FIXME need mypy 0.750 + self._attrs = attrs if indexes is not _default: - self._indexes = indexes # type: ignore # FIXME need mypy 0.750 + self._indexes = indexes if encoding is not _default: - self._encoding = encoding # type: ignore # FIXME need mypy 0.750 + self._encoding = encoding obj = self else: if variables is None: From 7f976baef9acd6b3b3b6341cebc95b8d7656a986 Mon Sep 17 00:00:00 2001 From: Guido Imperiale Date: Fri, 17 Jan 2020 17:12:12 +0000 Subject: [PATCH 4/8] trivial --- doc/whats-new.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index a2c2dd709fb..fef1b988f01 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -88,7 +88,7 @@ Bug fixes iterable when dropping variables (:issue:`3552`, :pull:`3693`) By `Justus Magin `_. - Fixed errors emitted by ``mypy --strict`` in modules that import xarray. - (:issue:`3695) by `Guido Imperiale `_. + (:issue:`3695`) by `Guido Imperiale `_. Documentation ~~~~~~~~~~~~~ From 4af98249c10c3e24b462ae8dc79a2c6e65018016 Mon Sep 17 00:00:00 2001 From: Guido Imperiale Date: Fri, 17 Jan 2020 17:19:14 +0000 Subject: [PATCH 5/8] testing.__all__ and ufuncs.__all__ --- doc/conf.py | 3 +- xarray/testing.py | 7 +++++ xarray/ufuncs.py | 70 +++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 71 insertions(+), 9 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index 11abda6bb63..a3d4b266d98 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -20,12 +20,13 @@ import sys from contextlib import suppress +import xarray + # make sure the source version is preferred (#3567) root = pathlib.Path(__file__).absolute().parent.parent os.environ["PYTHONPATH"] = str(root) sys.path.insert(0, str(root)) -import xarray allowed_failures = set() diff --git a/xarray/testing.py b/xarray/testing.py index 5c3ca8a3cca..ac189f7e023 100644 --- a/xarray/testing.py +++ b/xarray/testing.py @@ -10,6 +10,13 @@ from xarray.core.indexes import default_indexes from xarray.core.variable import IndexVariable, Variable +__all__ = ( + "assert_allclose", + "assert_chunks_equal", + "assert_equal", + "assert_identical", +) + def _decode_string_data(data): if data.dtype.kind == "S": diff --git a/xarray/ufuncs.py b/xarray/ufuncs.py index ae2c5c574b6..8ab2b7cfe31 100644 --- a/xarray/ufuncs.py +++ b/xarray/ufuncs.py @@ -132,14 +132,68 @@ def _create_op(name): return func -__all__ = """logaddexp logaddexp2 conj exp log log2 log10 log1p expm1 sqrt - square sin cos tan arcsin arccos arctan arctan2 hypot sinh cosh - tanh arcsinh arccosh arctanh deg2rad rad2deg logical_and - logical_or logical_xor logical_not maximum minimum fmax fmin - isreal iscomplex isfinite isinf isnan signbit copysign nextafter - ldexp fmod floor ceil trunc degrees radians rint fix angle real - imag fabs sign frexp fmod - """.split() +__all__ = ( # noqa: F822 + "angle", + "arccos", + "arccosh", + "arcsin", + "arcsinh", + "arctan", + "arctan2", + "arctanh", + "ceil", + "conj", + "copysign", + "cos", + "cosh", + "deg2rad", + "degrees", + "exp", + "expm1", + "fabs", + "fix", + "floor", + "fmax", + "fmin", + "fmod", + "fmod", + "frexp", + "hypot", + "imag", + "iscomplex", + "isfinite", + "isinf", + "isnan", + "isreal", + "ldexp", + "log", + "log10", + "log1p", + "log2", + "logaddexp", + "logaddexp2", + "logical_and", + "logical_not", + "logical_or", + "logical_xor", + "maximum", + "minimum", + "nextafter", + "rad2deg", + "radians", + "real", + "rint", + "sign", + "signbit", + "sin", + "sinh", + "sqrt", + "square", + "tan", + "tanh", + "trunc", +) + for name in __all__: globals()[name] = _create_op(name) From 6d4d0f2d4f50f4b35726fabc58fc1750cca18787 Mon Sep 17 00:00:00 2001 From: Guido Imperiale Date: Fri, 17 Jan 2020 17:21:40 +0000 Subject: [PATCH 6/8] isort --- properties/test_pandas_roundtrip.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/properties/test_pandas_roundtrip.py b/properties/test_pandas_roundtrip.py index a8005d319d6..5fc097f1f5e 100644 --- a/properties/test_pandas_roundtrip.py +++ b/properties/test_pandas_roundtrip.py @@ -1,20 +1,20 @@ """ Property-based tests for roundtripping between xarray and pandas objects. """ -import pytest - -pytest.importorskip("hypothesis") - from functools import partial -import hypothesis.extra.numpy as npst -import hypothesis.extra.pandas as pdst -import hypothesis.strategies as st -from hypothesis import given import numpy as np import pandas as pd +import pytest + import xarray as xr +pytest.importorskip("hypothesis") +import hypothesis.extra.numpy as npst # isort:skip +import hypothesis.extra.pandas as pdst # isort:skip +import hypothesis.strategies as st # isort:skip +from hypothesis import given # isort:skip + numeric_dtypes = st.one_of( npst.unsigned_integer_dtypes(), npst.integer_dtypes(), npst.floating_dtypes() ) From 161823a762d71c0b35b6621d74dbd5a40ed38554 Mon Sep 17 00:00:00 2001 From: Guido Imperiale Date: Fri, 17 Jan 2020 17:31:27 +0000 Subject: [PATCH 7/8] Revert mypy version bump --- .pre-commit-config.yaml | 2 +- ci/requirements/py36-min-all-deps.yml | 2 +- ci/requirements/py36.yml | 2 +- ci/requirements/py37-windows.yml | 2 +- ci/requirements/py37.yml | 2 +- xarray/core/computation.py | 2 +- xarray/core/dataset.py | 6 +++--- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ed62c1c256e..502120cd5dc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,7 +11,7 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.761 # Must match ci/requirements/*.yml + rev: v0.730 # Must match ci/requirements/*.yml hooks: - id: mypy # run these occasionally, ref discussion https://github.com/pydata/xarray/pull/3194 diff --git a/ci/requirements/py36-min-all-deps.yml b/ci/requirements/py36-min-all-deps.yml index e7756172311..3f10a158f91 100644 --- a/ci/requirements/py36-min-all-deps.yml +++ b/ci/requirements/py36-min-all-deps.yml @@ -25,7 +25,7 @@ dependencies: - iris=2.2 - lxml=4.4 # Optional dep of pydap - matplotlib=3.1 - - mypy=0.761 # Must match .pre-commit-config.yaml + - mypy=0.730 # Must match .pre-commit-config.yaml - nc-time-axis=1.2 - netcdf4=1.4 - numba=0.44 diff --git a/ci/requirements/py36.yml b/ci/requirements/py36.yml index 7450fafbd86..820160b19cc 100644 --- a/ci/requirements/py36.yml +++ b/ci/requirements/py36.yml @@ -21,7 +21,7 @@ dependencies: - iris - lxml # optional dep of pydap - matplotlib - - mypy=0.761 # Must match .pre-commit-config.yaml + - mypy=0.730 # Must match .pre-commit-config.yaml - nc-time-axis - netcdf4 - numba diff --git a/ci/requirements/py37-windows.yml b/ci/requirements/py37-windows.yml index d9e634c74ae..614a3bb1fab 100644 --- a/ci/requirements/py37-windows.yml +++ b/ci/requirements/py37-windows.yml @@ -21,7 +21,7 @@ dependencies: - iris - lxml # Optional dep of pydap - matplotlib - - mypy=0.761 # Must match .pre-commit-config.yaml + - mypy=0.730 # Must match .pre-commit-config.yaml - nc-time-axis - netcdf4 - numba diff --git a/ci/requirements/py37.yml b/ci/requirements/py37.yml index 2f879e29f87..4a7aaf7d32b 100644 --- a/ci/requirements/py37.yml +++ b/ci/requirements/py37.yml @@ -21,7 +21,7 @@ dependencies: - iris - lxml # Optional dep of pydap - matplotlib - - mypy=0.761 # Must match .pre-commit-config.yaml + - mypy=0.730 # Must match .pre-commit-config.yaml - nc-time-axis - netcdf4 - numba diff --git a/xarray/core/computation.py b/xarray/core/computation.py index 34de5edefc5..643c1137d6c 100644 --- a/xarray/core/computation.py +++ b/xarray/core/computation.py @@ -304,7 +304,7 @@ def _as_variables_or_variable(arg): def _unpack_dict_tuples( result_vars: Mapping[Hashable, Tuple[Variable, ...]], num_outputs: int ) -> Tuple[Dict[Hashable, Variable], ...]: - out: Tuple[Dict[Hashable, Variable], ...] = tuple({} for _ in range(num_outputs)) + out = tuple({} for _ in range(num_outputs)) # type: ignore for name, values in result_vars.items(): for value, results_dict in zip(values, out): results_dict[name] = value diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index 82ddc8a535f..e069537348a 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -897,11 +897,11 @@ def _replace( if dims is not None: self._dims = dims if attrs is not _default: - self._attrs = attrs + self._attrs = attrs # type: ignore # FIXME need mypy 0.750 if indexes is not _default: - self._indexes = indexes + self._indexes = indexes # type: ignore # FIXME need mypy 0.750 if encoding is not _default: - self._encoding = encoding + self._encoding = encoding # type: ignore # FIXME need mypy 0.750 obj = self else: if variables is None: From 63a120058dbe0b3719c37450fa30a5fc91174ab0 Mon Sep 17 00:00:00 2001 From: Guido Imperiale Date: Fri, 17 Jan 2020 17:34:13 +0000 Subject: [PATCH 8/8] Revert isort --- doc/conf.py | 3 +-- properties/test_pandas_roundtrip.py | 16 ++++++++-------- xarray/core/dataset.py | 2 +- xarray/core/duck_array_ops.py | 2 +- xarray/core/parallel.py | 2 +- xarray/tests/test_accessor_dt.py | 3 ++- xarray/tests/test_units.py | 1 - 7 files changed, 14 insertions(+), 15 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index a3d4b266d98..11abda6bb63 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -20,13 +20,12 @@ import sys from contextlib import suppress -import xarray - # make sure the source version is preferred (#3567) root = pathlib.Path(__file__).absolute().parent.parent os.environ["PYTHONPATH"] = str(root) sys.path.insert(0, str(root)) +import xarray allowed_failures = set() diff --git a/properties/test_pandas_roundtrip.py b/properties/test_pandas_roundtrip.py index 5fc097f1f5e..a8005d319d6 100644 --- a/properties/test_pandas_roundtrip.py +++ b/properties/test_pandas_roundtrip.py @@ -1,20 +1,20 @@ """ Property-based tests for roundtripping between xarray and pandas objects. """ +import pytest + +pytest.importorskip("hypothesis") + from functools import partial +import hypothesis.extra.numpy as npst +import hypothesis.extra.pandas as pdst +import hypothesis.strategies as st +from hypothesis import given import numpy as np import pandas as pd -import pytest - import xarray as xr -pytest.importorskip("hypothesis") -import hypothesis.extra.numpy as npst # isort:skip -import hypothesis.extra.pandas as pdst # isort:skip -import hypothesis.strategies as st # isort:skip -from hypothesis import given # isort:skip - numeric_dtypes = st.one_of( npst.unsigned_integer_dtypes(), npst.integer_dtypes(), npst.floating_dtypes() ) diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index e069537348a..4564dc80a8a 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -92,8 +92,8 @@ IndexVariable, Variable, as_variable, - assert_unique_multiindex_level_names, broadcast_variables, + assert_unique_multiindex_level_names, ) if TYPE_CHECKING: diff --git a/xarray/core/duck_array_ops.py b/xarray/core/duck_array_ops.py index 3fa97f0b448..98b371ab7c3 100644 --- a/xarray/core/duck_array_ops.py +++ b/xarray/core/duck_array_ops.py @@ -11,7 +11,7 @@ import numpy as np import pandas as pd -from . import dask_array_compat, dask_array_ops, dtypes, npcompat, nputils +from . import dask_array_ops, dask_array_compat, dtypes, npcompat, nputils from .nputils import nanfirst, nanlast from .pycompat import dask_array_type diff --git a/xarray/core/parallel.py b/xarray/core/parallel.py index facfa06b23c..e4fb5803191 100644 --- a/xarray/core/parallel.py +++ b/xarray/core/parallel.py @@ -13,8 +13,8 @@ from typing import ( Any, Callable, - DefaultDict, Dict, + DefaultDict, Hashable, Mapping, Sequence, diff --git a/xarray/tests/test_accessor_dt.py b/xarray/tests/test_accessor_dt.py index f178720a6e1..67ca12532c7 100644 --- a/xarray/tests/test_accessor_dt.py +++ b/xarray/tests/test_accessor_dt.py @@ -11,7 +11,8 @@ requires_cftime, requires_dask, ) -from .test_dask import assert_chunks_equal, raise_if_dask_computes + +from .test_dask import raise_if_dask_computes, assert_chunks_equal class TestDatetimeAccessor: diff --git a/xarray/tests/test_units.py b/xarray/tests/test_units.py index 6f9128839a7..2cb1550c088 100644 --- a/xarray/tests/test_units.py +++ b/xarray/tests/test_units.py @@ -7,7 +7,6 @@ import xarray as xr from xarray.core import formatting from xarray.core.npcompat import IS_NEP18_ACTIVE - from .test_variable import VariableSubclassobjects pint = pytest.importorskip("pint")