From 02c296905f9e12299eccbe3267049c2ce6ccf933 Mon Sep 17 00:00:00 2001 From: Deepak Cherian Date: Tue, 22 Oct 2019 18:30:43 +0000 Subject: [PATCH 1/5] Add cftime git tip to upstream-dev + temporarily pin cftime (#3431) * Add cftime git tip to upstream-dev + temporarily pin cftime * specify cftime min version as 1.0.0 * Min cftime version 1.0.3 * wn --- ci/azure/install.yml | 3 ++- ci/requirements/py36-min-all-deps.yml | 2 +- ci/requirements/py36.yml | 2 +- ci/requirements/py37-windows.yml | 2 +- ci/requirements/py37.yml | 2 +- doc/whats-new.rst | 5 +++++ 6 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ci/azure/install.yml b/ci/azure/install.yml index 8d72ffce124..f1192f4424f 100644 --- a/ci/azure/install.yml +++ b/ci/azure/install.yml @@ -24,7 +24,8 @@ steps: --upgrade \ git+https://github.com/dask/dask \ git+https://github.com/dask/distributed \ - git+https://github.com/zarr-developers/zarr + git+https://github.com/zarr-developers/zarr \ + git+https://github.com/Unidata/cftime condition: eq(variables['UPSTREAM_DEV'], 'true') displayName: Install upstream dev dependencies diff --git a/ci/requirements/py36-min-all-deps.yml b/ci/requirements/py36-min-all-deps.yml index 3f10a158f91..bbc51d09ce2 100644 --- a/ci/requirements/py36-min-all-deps.yml +++ b/ci/requirements/py36-min-all-deps.yml @@ -13,7 +13,7 @@ dependencies: - cartopy=0.17 - cdms2=3.1 - cfgrib=0.9 - - cftime=1.0 + - cftime=1.0.3 - coveralls - dask=1.2 - distributed=1.27 diff --git a/ci/requirements/py36.yml b/ci/requirements/py36.yml index 4d6d778f884..54ab9b5be7a 100644 --- a/ci/requirements/py36.yml +++ b/ci/requirements/py36.yml @@ -9,7 +9,7 @@ dependencies: - cartopy - cdms2 - cfgrib - - cftime + - cftime=1.0.3.4 - coveralls - dask - distributed diff --git a/ci/requirements/py37-windows.yml b/ci/requirements/py37-windows.yml index 78784b48f3c..3318d837257 100644 --- a/ci/requirements/py37-windows.yml +++ b/ci/requirements/py37-windows.yml @@ -9,7 +9,7 @@ dependencies: - cartopy # - cdms2 # Not available on Windows # - cfgrib>=0.9.2 # Causes Python interpreter crash on Windows - - cftime + - cftime=1.0.3.4 - coveralls - dask - distributed diff --git a/ci/requirements/py37.yml b/ci/requirements/py37.yml index 38e5db641b7..5cdb634649c 100644 --- a/ci/requirements/py37.yml +++ b/ci/requirements/py37.yml @@ -9,7 +9,7 @@ dependencies: - cartopy - cdms2 - cfgrib - - cftime + - cftime=1.0.3.4 - coveralls - dask - distributed diff --git a/doc/whats-new.rst b/doc/whats-new.rst index abe472cc6bb..ede18c3b147 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -18,6 +18,11 @@ What's New v0.14.1 (unreleased) -------------------- +Breaking changes +~~~~~~~~~~~~~~~~ + +- Minimum cftime version is now 1.0.3. By `Deepak Cherian `_. + New Features ~~~~~~~~~~~~ - Added integration tests against `pint `_. From e258b88ae9229217095e55ea451d3c9546d8fe6e Mon Sep 17 00:00:00 2001 From: Anderson Banihirwe Date: Tue, 22 Oct 2019 12:31:34 -0600 Subject: [PATCH 2/5] Sync with latest version of cftime (v1.0.4) (#3430) * Remove `dayofwk=-1`-- not needed for cftime>=1.0.4 * Maintain backwards compatibility Co-Authored-By: Spencer Clark * Maintain backwards compatibility Co-Authored-By: Spencer Clark * Maintain backwards compatibility * Add missing import * Update whats-new --- doc/whats-new.rst | 4 ++++ xarray/coding/cftime_offsets.py | 16 +++++++++++----- xarray/coding/cftimeindex.py | 14 ++++++++------ 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index ede18c3b147..2fbfd58ddba 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -41,6 +41,10 @@ Bug fixes - Fix regression introduced in v0.14.0 that would cause a crash if dask is installed but cloudpickle isn't (:issue:`3401`) by `Rhys Doyle `_ +- Sync with cftime by removing `dayofwk=-1` for cftime>=1.0.4. + By `Anderson Banihirwe `_. + + Documentation ~~~~~~~~~~~~~ diff --git a/xarray/coding/cftime_offsets.py b/xarray/coding/cftime_offsets.py index af46510f7c4..8471ed1a558 100644 --- a/xarray/coding/cftime_offsets.py +++ b/xarray/coding/cftime_offsets.py @@ -50,6 +50,7 @@ from ..core.pdcompat import count_not_none from .cftimeindex import CFTimeIndex, _parse_iso8601_with_reso from .times import format_cftime_datetime +from distutils.version import LooseVersion def get_date_type(calendar): @@ -222,6 +223,8 @@ def _adjust_n_years(other, n, month, reference_day): def _shift_month(date, months, day_option="start"): """Shift the date to a month start or end a given number of months away. """ + import cftime + delta_year = (date.month + months) // 12 month = (date.month + months) % 12 @@ -237,11 +240,14 @@ def _shift_month(date, months, day_option="start"): day = _days_in_month(reference) else: raise ValueError(day_option) - # dayofwk=-1 is required to update the dayofwk and dayofyr attributes of - # the returned date object in versions of cftime between 1.0.2 and - # 1.0.3.4. It can be removed for versions of cftime greater than - # 1.0.3.4. - return date.replace(year=year, month=month, day=day, dayofwk=-1) + if LooseVersion(cftime.__version__) < LooseVersion("1.0.4"): + # dayofwk=-1 is required to update the dayofwk and dayofyr attributes of + # the returned date object in versions of cftime between 1.0.2 and + # 1.0.3.4. It can be removed for versions of cftime greater than + # 1.0.3.4. + return date.replace(year=year, month=month, day=day, dayofwk=-1) + else: + return date.replace(year=year, month=month, day=day) def roll_qtrday(other, n, month, day_option, modby=3): diff --git a/xarray/coding/cftimeindex.py b/xarray/coding/cftimeindex.py index 434d55d6569..559c5e16287 100644 --- a/xarray/coding/cftimeindex.py +++ b/xarray/coding/cftimeindex.py @@ -96,6 +96,8 @@ def parse_iso8601(datetime_string): def _parse_iso8601_with_reso(date_type, timestr): + import cftime + default = date_type(1, 1, 1) result = parse_iso8601(timestr) replace = {} @@ -107,12 +109,12 @@ def _parse_iso8601_with_reso(date_type, timestr): # TODO: Consider adding support for sub-second resolution? replace[attr] = int(value) resolution = attr - - # dayofwk=-1 is required to update the dayofwk and dayofyr attributes of - # the returned date object in versions of cftime between 1.0.2 and - # 1.0.3.4. It can be removed for versions of cftime greater than - # 1.0.3.4. - replace["dayofwk"] = -1 + if LooseVersion(cftime.__version__) < LooseVersion("1.0.4"): + # dayofwk=-1 is required to update the dayofwk and dayofyr attributes of + # the returned date object in versions of cftime between 1.0.2 and + # 1.0.3.4. It can be removed for versions of cftime greater than + # 1.0.3.4. + replace["dayofwk"] = -1 return default.replace(**replace), resolution From a3e43e6f1f5827cb635b48ba69ec4c1ac312d811 Mon Sep 17 00:00:00 2001 From: Huite Date: Tue, 22 Oct 2019 20:45:23 +0200 Subject: [PATCH 3/5] Avoid multiplication DeprecationWarning in rasterio backend (#3428) --- xarray/backends/rasterio_.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xarray/backends/rasterio_.py b/xarray/backends/rasterio_.py index 7430633c5c0..1f9b9943573 100644 --- a/xarray/backends/rasterio_.py +++ b/xarray/backends/rasterio_.py @@ -257,8 +257,8 @@ def open_rasterio(filename, parse_coordinates=None, chunks=None, cache=None, loc if parse: nx, ny = riods.width, riods.height # xarray coordinates are pixel centered - x, _ = (np.arange(nx) + 0.5, np.zeros(nx) + 0.5) * riods.transform - _, y = (np.zeros(ny) + 0.5, np.arange(ny) + 0.5) * riods.transform + x, _ = riods.transform * (np.arange(nx) + 0.5, np.zeros(nx) + 0.5) + _, y = riods.transform * (np.zeros(ny) + 0.5, np.arange(ny) + 0.5) coords["y"] = y coords["x"] = x else: From 72be873857a0a56659c905ce491ca1f94b44fd5c Mon Sep 17 00:00:00 2001 From: Deepak Cherian Date: Tue, 22 Oct 2019 19:42:08 +0000 Subject: [PATCH 4/5] Test that Dataset and DataArray resampling are identical (#3412) --- xarray/tests/test_dataset.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/xarray/tests/test_dataset.py b/xarray/tests/test_dataset.py index dce417f27f9..006d6881b5a 100644 --- a/xarray/tests/test_dataset.py +++ b/xarray/tests/test_dataset.py @@ -3593,6 +3593,19 @@ def test_resample_old_api(self): with raises_regex(TypeError, r"resample\(\) no longer supports"): ds.resample("1D", dim="time") + def test_resample_ds_da_are_the_same(self): + time = pd.date_range("2000-01-01", freq="6H", periods=365 * 4) + ds = xr.Dataset( + { + "foo": (("time", "x"), np.random.randn(365 * 4, 5)), + "time": time, + "x": np.arange(5), + } + ) + assert_identical( + ds.resample(time="M").mean()["foo"], ds.foo.resample(time="M").mean() + ) + def test_ds_resample_apply_func_args(self): def func(arg1, arg2, arg3=0.0): return arg1.mean("time") + arg2 + arg3 From c8dac5866d2c54ee6b262b5060a701e0be1e40cb Mon Sep 17 00:00:00 2001 From: crusaderky Date: Wed, 23 Oct 2019 02:06:09 +0100 Subject: [PATCH 5/5] MAGA (Make Azure Green Again) (#3436) * Support for patch version in min_deps_check.py * Fix requirements * Fix requirements * cftime is 1.0.4 incompatible * Use cftime PR#127 * trivial * trivial --- ci/azure/install.yml | 5 +- ci/min_deps_check.py | 72 ++++++++++++++++----------- ci/requirements/py36-min-all-deps.yml | 2 +- ci/requirements/py36.yml | 4 +- ci/requirements/py37-windows.yml | 6 +-- ci/requirements/py37.yml | 4 +- doc/whats-new.rst | 2 +- 7 files changed, 55 insertions(+), 40 deletions(-) diff --git a/ci/azure/install.yml b/ci/azure/install.yml index f1192f4424f..2911e227172 100644 --- a/ci/azure/install.yml +++ b/ci/azure/install.yml @@ -15,17 +15,18 @@ steps: --no-deps \ --pre \ --upgrade \ - numpy \ matplotlib \ pandas \ scipy + # numpy \ # FIXME https://github.com/pydata/xarray/issues/3409 pip install \ --no-deps \ --upgrade \ git+https://github.com/dask/dask \ git+https://github.com/dask/distributed \ git+https://github.com/zarr-developers/zarr \ - git+https://github.com/Unidata/cftime + git+https://github.com/Unidata/cftime.git@refs/pull/127/merge + # git+https://github.com/Unidata/cftime # FIXME PR 127 not merged yet condition: eq(variables['UPSTREAM_DEV'], 'true') displayName: Install upstream dev dependencies diff --git a/ci/min_deps_check.py b/ci/min_deps_check.py index 3bdd48ca76d..a5ba90679b7 100755 --- a/ci/min_deps_check.py +++ b/ci/min_deps_check.py @@ -6,7 +6,7 @@ import sys from concurrent.futures import ThreadPoolExecutor from datetime import datetime, timedelta -from typing import Dict, Iterator, Tuple +from typing import Dict, Iterator, Optional, Tuple import yaml @@ -34,10 +34,14 @@ def error(msg: str) -> None: print("ERROR:", msg) -def parse_requirements(fname) -> Iterator[Tuple[str, int, int]]: +def warning(msg: str) -> None: + print("WARNING:", msg) + + +def parse_requirements(fname) -> Iterator[Tuple[str, int, int, Optional[int]]]: """Load requirements/py36-min-all-deps.yml - Yield (package name, major version, minor version) + Yield (package name, major version, minor version, [patch version]) """ global has_errors @@ -52,15 +56,18 @@ def parse_requirements(fname) -> Iterator[Tuple[str, int, int]]: if pkg.endswith("<") or pkg.endswith(">") or eq != "=": error("package should be pinned with exact version: " + row) continue + try: - major, minor = version.split(".") - except ValueError: - error("expected major.minor (without patch): " + row) - continue - try: - yield pkg, int(major), int(minor) + version_tup = tuple(int(x) for x in version.split(".")) except ValueError: - error("failed to parse version: " + row) + raise ValueError("non-numerical version: " + row) + + if len(version_tup) == 2: + yield (pkg, *version_tup, None) # type: ignore + elif len(version_tup) == 3: + yield (pkg, *version_tup) # type: ignore + else: + raise ValueError("expected major.minor or major.minor.patch: " + row) def query_conda(pkg: str) -> Dict[Tuple[int, int], datetime]: @@ -80,9 +87,9 @@ def query_conda(pkg: str) -> Dict[Tuple[int, int], datetime]: label = label.strip() if label == "file name": value = value.strip()[len(pkg) :] - major, minor = value.split("-")[1].split(".")[:2] - major = int(major) - minor = int(minor) + smajor, sminor = value.split("-")[1].split(".")[:2] + major = int(smajor) + minor = int(sminor) if label == "timestamp": assert major is not None assert minor is not None @@ -109,17 +116,15 @@ def query_conda(pkg: str) -> Dict[Tuple[int, int], datetime]: def process_pkg( - pkg: str, req_major: int, req_minor: int -) -> Tuple[str, int, int, str, int, int, str, str]: + pkg: str, req_major: int, req_minor: int, req_patch: Optional[int] +) -> Tuple[str, str, str, str, str, str]: """Compare package version from requirements file to available versions in conda. Return row to build pandas dataframe: - package name - - major version in requirements file - - minor version in requirements file + - major.minor.[patch] version in requirements file - publication date of version in requirements file (YYYY-MM-DD) - - major version suggested by policy - - minor version suggested by policy + - major.minor version suggested by policy - publication date of version suggested by policy (YYYY-MM-DD) - status ("<", "=", "> (!)") """ @@ -130,7 +135,7 @@ def process_pkg( req_published = versions[req_major, req_minor] except KeyError: error("not found in conda: " + pkg) - return pkg, req_major, req_minor, "-", 0, 0, "-", "(!)" + return pkg, fmt_version(req_major, req_minor, req_patch), "-", "-", "-", "(!)" policy_months = POLICY_MONTHS.get(pkg, POLICY_MONTHS_DEFAULT) policy_published = datetime.now() - timedelta(days=policy_months * 30) @@ -153,30 +158,39 @@ def process_pkg( else: status = "=" + if req_patch is not None: + warning("patch version should not appear in requirements file: " + pkg) + status += " (w)" + return ( pkg, - req_major, - req_minor, + fmt_version(req_major, req_minor, req_patch), req_published.strftime("%Y-%m-%d"), - policy_major, - policy_minor, + fmt_version(policy_major, policy_minor), policy_published_actual.strftime("%Y-%m-%d"), status, ) +def fmt_version(major: int, minor: int, patch: int = None) -> str: + if patch is None: + return f"{major}.{minor}" + else: + return f"{major}.{minor}.{patch}" + + def main() -> None: fname = sys.argv[1] with ThreadPoolExecutor(8) as ex: futures = [ - ex.submit(process_pkg, pkg, major, minor) - for pkg, major, minor in parse_requirements(fname) + ex.submit(process_pkg, pkg, major, minor, patch) + for pkg, major, minor, patch in parse_requirements(fname) ] rows = [f.result() for f in futures] - print("Package Required Policy Status") - print("------------- ----------------- ----------------- ------") - fmt = "{:13} {:>1d}.{:<2d} ({:10}) {:>1d}.{:<2d} ({:10}) {}" + print("Package Required Policy Status") + print("------------- -------------------- -------------------- ------") + fmt = "{:13} {:7} ({:10}) {:7} ({:10}) {}" for row in rows: print(fmt.format(*row)) diff --git a/ci/requirements/py36-min-all-deps.yml b/ci/requirements/py36-min-all-deps.yml index bbc51d09ce2..c99ae39e5d9 100644 --- a/ci/requirements/py36-min-all-deps.yml +++ b/ci/requirements/py36-min-all-deps.yml @@ -13,7 +13,7 @@ dependencies: - cartopy=0.17 - cdms2=3.1 - cfgrib=0.9 - - cftime=1.0.3 + - cftime=1.0.3 # FIXME need 1.0.5 (not released yet); 1.0.4 is broken - coveralls - dask=1.2 - distributed=1.27 diff --git a/ci/requirements/py36.yml b/ci/requirements/py36.yml index 54ab9b5be7a..6e27cea2ffe 100644 --- a/ci/requirements/py36.yml +++ b/ci/requirements/py36.yml @@ -9,7 +9,7 @@ dependencies: - cartopy - cdms2 - cfgrib - - cftime=1.0.3.4 + - cftime<1.0.4 # FIXME need 1.0.5 (not released yet); 1.0.4 is broken - coveralls - dask - distributed @@ -25,7 +25,7 @@ dependencies: - nc-time-axis - netcdf4 - numba - - numpy + - numpy<1.18 # FIXME https://github.com/pydata/xarray/issues/3409 - pandas - pint - pip diff --git a/ci/requirements/py37-windows.yml b/ci/requirements/py37-windows.yml index 3318d837257..7027fc11ab7 100644 --- a/ci/requirements/py37-windows.yml +++ b/ci/requirements/py37-windows.yml @@ -8,8 +8,8 @@ dependencies: - bottleneck - cartopy # - cdms2 # Not available on Windows - # - cfgrib>=0.9.2 # Causes Python interpreter crash on Windows - - cftime=1.0.3.4 + # - cfgrib # Causes Python interpreter crash on Windows + - cftime<1.0.4 # FIXME need 1.0.5 (not released yet); 1.0.4 is broken - coveralls - dask - distributed @@ -25,7 +25,7 @@ dependencies: - nc-time-axis - netcdf4 - numba - - numpy + - numpy<1.18 # FIXME https://github.com/pydata/xarray/issues/3409 - pandas - pint - pip diff --git a/ci/requirements/py37.yml b/ci/requirements/py37.yml index 5cdb634649c..a4c974c0176 100644 --- a/ci/requirements/py37.yml +++ b/ci/requirements/py37.yml @@ -9,7 +9,7 @@ dependencies: - cartopy - cdms2 - cfgrib - - cftime=1.0.3.4 + - cftime<1.0.4 # FIXME need 1.0.5 (not released yet); 1.0.4 is broken - coveralls - dask - distributed @@ -25,7 +25,7 @@ dependencies: - nc-time-axis - netcdf4 - numba - - numpy + - numpy<1.18 # FIXME https://github.com/pydata/xarray/issues/3409 - pandas - pint - pip diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 2fbfd58ddba..0f4d0c10f1f 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -42,7 +42,7 @@ Bug fixes but cloudpickle isn't (:issue:`3401`) by `Rhys Doyle `_ - Sync with cftime by removing `dayofwk=-1` for cftime>=1.0.4. - By `Anderson Banihirwe `_. + By `Anderson Banihirwe `_. Documentation