diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index c9c0b720c35..15c971907f6 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,6 +2,6 @@ - [ ] Closes #xxxx - [ ] Tests added - - [ ] Passes `isort -rc . && black . && mypy . && flake8` + - [ ] Passes `isort . && black . && mypy . && flake8` - [ ] User visible changes (including notable bug fixes) are documented in `whats-new.rst` - [ ] New functions/methods are listed in `api.rst` diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 447f0007fc2..9fd92a50c16 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,10 +2,9 @@ repos: # isort should run before black as black sometimes tweaks the isort output - repo: https://github.com/timothycrosley/isort - rev: 4.3.21-2 + rev: 5.1.0 hooks: - id: isort - files: .+\.py$ # https://github.com/python/black#version-control-integration - repo: https://github.com/python/black rev: stable @@ -16,7 +15,7 @@ repos: hooks: - id: blackdoc - repo: https://gitlab.com/pycqa/flake8 - rev: 3.7.9 + rev: 3.8.3 hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy diff --git a/azure-pipelines.yml b/azure-pipelines.yml index e04c8f74f68..8061c9895ca 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -95,7 +95,7 @@ jobs: - template: ci/azure/install.yml - bash: | source activate xarray-tests - isort -rc --check . + isort --check . displayName: isort formatting checks - job: MinimumVersionsPolicy diff --git a/ci/requirements/py36-min-all-deps.yml b/ci/requirements/py36-min-all-deps.yml index b14582ca9c2..c11c52bd19f 100644 --- a/ci/requirements/py36-min-all-deps.yml +++ b/ci/requirements/py36-min-all-deps.yml @@ -23,7 +23,7 @@ dependencies: - hdf5=1.10 - hypothesis - iris=2.2 - - isort=4.3.21 + - isort - lxml=4.4 # Optional dep of pydap - matplotlib=3.1 - mypy=0.761 # Must match .pre-commit-config.yaml diff --git a/ci/requirements/py36.yml b/ci/requirements/py36.yml index 9ff2c6c49ca..a500173f277 100644 --- a/ci/requirements/py36.yml +++ b/ci/requirements/py36.yml @@ -19,7 +19,7 @@ dependencies: - hdf5 - hypothesis - iris - - isort=4.3.21 + - isort - lxml # Optional dep of pydap - matplotlib - mypy=0.761 # Must match .pre-commit-config.yaml diff --git a/ci/requirements/py37-windows.yml b/ci/requirements/py37-windows.yml index 19285a35eca..e9e5c7a900a 100644 --- a/ci/requirements/py37-windows.yml +++ b/ci/requirements/py37-windows.yml @@ -19,7 +19,7 @@ dependencies: - hdf5 - hypothesis - iris - - isort=4.3.21 + - isort - lxml # Optional dep of pydap - matplotlib - mypy=0.761 # Must match .pre-commit-config.yaml diff --git a/ci/requirements/py37.yml b/ci/requirements/py37.yml index 3fcb4efd009..dba3926596e 100644 --- a/ci/requirements/py37.yml +++ b/ci/requirements/py37.yml @@ -19,7 +19,7 @@ dependencies: - hdf5 - hypothesis - iris - - isort=4.3.21 + - isort - lxml # Optional dep of pydap - matplotlib - mypy=0.761 # Must match .pre-commit-config.yaml diff --git a/ci/requirements/py38-all-but-dask.yml b/ci/requirements/py38-all-but-dask.yml index 4e6f0dd5387..a375d9e1e5a 100644 --- a/ci/requirements/py38-all-but-dask.yml +++ b/ci/requirements/py38-all-but-dask.yml @@ -16,7 +16,7 @@ dependencies: - h5py - hdf5 - hypothesis - - isort=4.3.21 + - isort - lxml # Optional dep of pydap - matplotlib - mypy=0.761 # Must match .pre-commit-config.yaml diff --git a/ci/requirements/py38.yml b/ci/requirements/py38.yml index 4598fcd2790..7dff3a1bd97 100644 --- a/ci/requirements/py38.yml +++ b/ci/requirements/py38.yml @@ -19,7 +19,7 @@ dependencies: - hdf5 - hypothesis - iris - - isort=4.3.21 + - isort - lxml # Optional dep of pydap - matplotlib - mypy=0.780 # Must match .pre-commit-config.yaml diff --git a/conftest.py b/conftest.py index 712af1d3759..ddce5e0d593 100644 --- a/conftest.py +++ b/conftest.py @@ -27,6 +27,7 @@ def pytest_runtest_setup(item): def add_standard_imports(doctest_namespace): import numpy as np import pandas as pd + import xarray as xr doctest_namespace["np"] = np diff --git a/doc/contributing.rst b/doc/contributing.rst index 9e6a3c250e9..975f4e67ba2 100644 --- a/doc/contributing.rst +++ b/doc/contributing.rst @@ -368,7 +368,7 @@ xarray uses several tools to ensure a consistent code format throughout the proj and then run from the root of the Xarray repository:: - isort -rc . + isort . black -t py36 . blackdoc -t py36 . flake8 diff --git a/xarray/backends/scipy_.py b/xarray/backends/scipy_.py index 9863285d6de..b7d91a840fe 100644 --- a/xarray/backends/scipy_.py +++ b/xarray/backends/scipy_.py @@ -57,9 +57,10 @@ def __setitem__(self, key, value): def _open_scipy_netcdf(filename, mode, mmap, version): - import scipy.io import gzip + import scipy.io + # if the string ends with .gz, then gunzip and open as netcdf file if isinstance(filename, str) and filename.endswith(".gz"): try: diff --git a/xarray/conventions.py b/xarray/conventions.py index fc0572944f3..700dcbc0fc4 100644 --- a/xarray/conventions.py +++ b/xarray/conventions.py @@ -567,8 +567,8 @@ def decode_cf( ------- decoded : Dataset """ - from .core.dataset import Dataset from .backends.common import AbstractDataStore + from .core.dataset import Dataset if isinstance(obj, Dataset): vars = obj._variables diff --git a/xarray/convert.py b/xarray/convert.py index 0c86b090f34..395581bace7 100644 --- a/xarray/convert.py +++ b/xarray/convert.py @@ -254,6 +254,7 @@ def from_iris(cube): """ Convert a Iris cube into an DataArray """ import iris.exceptions + from xarray.core.pycompat import dask_array_type name = _name(cube) diff --git a/xarray/core/common.py b/xarray/core/common.py index 67dc0fda461..c95df77313e 100644 --- a/xarray/core/common.py +++ b/xarray/core/common.py @@ -1088,9 +1088,9 @@ def resample( """ # TODO support non-string indexer after removing the old API. + from ..coding.cftimeindex import CFTimeIndex from .dataarray import DataArray from .resample import RESAMPLE_DIM - from ..coding.cftimeindex import CFTimeIndex if keep_attrs is None: keep_attrs = _get_keep_attrs(default=False) @@ -1283,8 +1283,8 @@ def isin(self, test_elements): numpy.isin """ from .computation import apply_ufunc - from .dataset import Dataset from .dataarray import DataArray + from .dataset import Dataset from .variable import Variable if isinstance(test_elements, Dataset): diff --git a/xarray/core/computation.py b/xarray/core/computation.py index d8a0c53e817..94d4c6b1540 100644 --- a/xarray/core/computation.py +++ b/xarray/core/computation.py @@ -976,8 +976,8 @@ def earth_mover_distance(first_samples, .. [2] http://docs.scipy.org/doc/numpy/reference/c-api.generalized-ufuncs.html .. [3] http://xarray.pydata.org/en/stable/computation.html#wrapping-custom-computation """ - from .groupby import GroupBy from .dataarray import DataArray + from .groupby import GroupBy from .variable import Variable if input_core_dims is None: diff --git a/xarray/core/concat.py b/xarray/core/concat.py index 7741cbb826b..b42c91c232d 100644 --- a/xarray/core/concat.py +++ b/xarray/core/concat.py @@ -116,8 +116,8 @@ def concat( # TODO: add ignore_index arguments copied from pandas.concat # TODO: support concatenating scalar coordinates even if the concatenated # dimension already exists - from .dataset import Dataset from .dataarray import DataArray + from .dataset import Dataset try: first_obj, objs = utils.peek_at(objs) diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index 5bfddaa710b..1b0e01914f2 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -4144,7 +4144,7 @@ def interpolate_na( numpy.interp scipy.interpolate """ - from .missing import interp_na, _apply_over_vars_with_dim + from .missing import _apply_over_vars_with_dim, interp_na new = _apply_over_vars_with_dim( interp_na, @@ -4178,7 +4178,7 @@ def ffill(self, dim: Hashable, limit: int = None) -> "Dataset": ------- Dataset """ - from .missing import ffill, _apply_over_vars_with_dim + from .missing import _apply_over_vars_with_dim, ffill new = _apply_over_vars_with_dim(ffill, self, dim=dim, limit=limit) return new @@ -4203,7 +4203,7 @@ def bfill(self, dim: Hashable, limit: int = None) -> "Dataset": ------- Dataset """ - from .missing import bfill, _apply_over_vars_with_dim + from .missing import _apply_over_vars_with_dim, bfill new = _apply_over_vars_with_dim(bfill, self, dim=dim, limit=limit) return new diff --git a/xarray/core/groupby.py b/xarray/core/groupby.py index 04c0fabae6a..aa7aa1f5e86 100644 --- a/xarray/core/groupby.py +++ b/xarray/core/groupby.py @@ -64,8 +64,8 @@ def unique_value_groups(ar, sort=True): def _dummy_copy(xarray_obj): - from .dataset import Dataset from .dataarray import DataArray + from .dataset import Dataset if isinstance(xarray_obj, Dataset): res = Dataset( diff --git a/xarray/core/indexing.py b/xarray/core/indexing.py index ab049a0a4b4..28ed2cfb16f 100644 --- a/xarray/core/indexing.py +++ b/xarray/core/indexing.py @@ -50,8 +50,8 @@ def _expand_slice(slice_, size): def _sanitize_slice_element(x): - from .variable import Variable from .dataarray import DataArray + from .variable import Variable if isinstance(x, (Variable, DataArray)): x = x.values diff --git a/xarray/core/nanops.py b/xarray/core/nanops.py index f9989c2c8c9..41c8d258d7a 100644 --- a/xarray/core/nanops.py +++ b/xarray/core/nanops.py @@ -6,6 +6,7 @@ try: import dask.array as dask_array + from . import dask_array_compat except ImportError: dask_array = None @@ -118,7 +119,7 @@ def nansum(a, axis=None, dtype=None, out=None, min_count=None): def _nanmean_ddof_object(ddof, value, axis=None, dtype=None, **kwargs): """ In house nanmean. ddof argument will be used in _nanvar method """ - from .duck_array_ops import count, fillna, _dask_or_eager_func, where_method + from .duck_array_ops import _dask_or_eager_func, count, fillna, where_method valid_count = count(value, axis=axis) value = fillna(value, 0) diff --git a/xarray/core/parallel.py b/xarray/core/parallel.py index 86044e72dd2..07d61e595c9 100644 --- a/xarray/core/parallel.py +++ b/xarray/core/parallel.py @@ -2,6 +2,7 @@ import dask import dask.array from dask.highlevelgraph import HighLevelGraph + from .dask_array_compat import meta_from_array except ImportError: diff --git a/xarray/tests/test_backends.py b/xarray/tests/test_backends.py index 6a840e6303e..9f987e7fdf2 100644 --- a/xarray/tests/test_backends.py +++ b/xarray/tests/test_backends.py @@ -3207,7 +3207,7 @@ def test_load_dataarray(self): @pytest.mark.filterwarnings("ignore:The binary mode of fromstring is deprecated") class TestPydap: def convert_to_pydap_dataset(self, original): - from pydap.model import GridType, BaseType, DatasetType + from pydap.model import BaseType, DatasetType, GridType ds = DatasetType("bears", **original.attrs) for key, var in original.data_vars.items(): @@ -3747,9 +3747,10 @@ def test_platecarree(self): def test_notransform(self): # regression test for https://github.com/pydata/xarray/issues/1686 - import rasterio import warnings + import rasterio + # Create a geotiff file with warnings.catch_warnings(): # rasterio throws a NotGeoreferencedWarning here, which is @@ -4097,8 +4098,8 @@ def test_rasterio_vrt_with_transform_and_size(self): # Test open_rasterio() support of WarpedVRT with transform, width and # height (issue #2864) import rasterio - from rasterio.warp import calculate_default_transform from affine import Affine + from rasterio.warp import calculate_default_transform with create_tmp_geotiff() as (tmp_file, expected): with rasterio.open(tmp_file) as src: diff --git a/xarray/tests/test_coding_times.py b/xarray/tests/test_coding_times.py index 1efd4b02bf8..457e68f5593 100644 --- a/xarray/tests/test_coding_times.py +++ b/xarray/tests/test_coding_times.py @@ -222,9 +222,10 @@ def test_decode_non_standard_calendar_inside_timestamp_range(calendar): @requires_cftime @pytest.mark.parametrize("calendar", _ALL_CALENDARS) def test_decode_dates_outside_timestamp_range(calendar): - import cftime from datetime import datetime + import cftime + units = "days since 0001-01-01" times = [datetime(1, 4, 1, h) for h in range(1, 5)] time = cftime.date2num(times, units, calendar=calendar) @@ -358,9 +359,10 @@ def test_decode_nonstandard_calendar_multidim_time_inside_timestamp_range(calend @requires_cftime @pytest.mark.parametrize("calendar", _ALL_CALENDARS) def test_decode_multidim_time_outside_timestamp_range(calendar): - import cftime from datetime import datetime + import cftime + units = "days since 0001-01-01" times1 = [datetime(1, 4, day) for day in range(1, 6)] times2 = [datetime(1, 5, day) for day in range(1, 6)] diff --git a/xarray/tests/test_dataarray.py b/xarray/tests/test_dataarray.py index 793090cc122..e0da3f1527f 100644 --- a/xarray/tests/test_dataarray.py +++ b/xarray/tests/test_dataarray.py @@ -6417,8 +6417,8 @@ def test_name_in_masking(): class TestIrisConversion: @requires_iris def test_to_and_from_iris(self): - import iris import cf_units # iris requirement + import iris # to iris coord_dict = {} @@ -6488,9 +6488,9 @@ def test_to_and_from_iris(self): @requires_iris @requires_dask def test_to_and_from_iris_dask(self): + import cf_units # iris requirement import dask.array as da import iris - import cf_units # iris requirement coord_dict = {} coord_dict["distance"] = ("distance", [-2, 2], {"units": "meters"}) @@ -6623,8 +6623,8 @@ def test_da_name_from_cube(self, std_name, long_name, var_name, name, attrs): ], ) def test_da_coord_name_from_cube(self, std_name, long_name, var_name, name, attrs): - from iris.cube import Cube from iris.coords import DimCoord + from iris.cube import Cube latitude = DimCoord( [-90, 0, 90], standard_name=std_name, var_name=var_name, long_name=long_name @@ -6637,8 +6637,8 @@ def test_da_coord_name_from_cube(self, std_name, long_name, var_name, name, attr @requires_iris def test_prevent_duplicate_coord_names(self): - from iris.cube import Cube from iris.coords import DimCoord + from iris.cube import Cube # Iris enforces unique coordinate names. Because we use a different # name resolution order a valid iris Cube with coords that have the @@ -6659,8 +6659,8 @@ def test_prevent_duplicate_coord_names(self): [["IA", "IL", "IN"], [0, 2, 1]], # non-numeric values # non-monotonic values ) def test_fallback_to_iris_AuxCoord(self, coord_values): - from iris.cube import Cube from iris.coords import AuxCoord + from iris.cube import Cube data = [0, 0, 0] da = xr.DataArray(data, coords=[coord_values], dims=["space"])