From f13536c965d02bb2845da31e909899a90754b375 Mon Sep 17 00:00:00 2001 From: Stephan Hoyer Date: Tue, 15 Jan 2019 13:19:58 +0200 Subject: [PATCH 01/11] Fix test failures with numpy=1.16 (#2675) Fixes https://github.com/pydata/xarray/issues/2673 Note that these were only test failures, not a real bug. --- xarray/tests/test_variable.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xarray/tests/test_variable.py b/xarray/tests/test_variable.py index 6dd50e11fd3..fdcc184eec4 100644 --- a/xarray/tests/test_variable.py +++ b/xarray/tests/test_variable.py @@ -140,8 +140,8 @@ def _assertIndexedLikeNDArray(self, variable, expected_value0, # check value is equal for both ndarray and Variable with warnings.catch_warnings(): warnings.filterwarnings('ignore', "In the future, 'NAT == x'") - assert variable.values[0] == expected_value0 - assert variable[0].values == expected_value0 + np.testing.assert_equal(variable.values[0], expected_value0) + np.testing.assert_equal(variable[0].values, expected_value0) # check type or dtype is consistent for both ndarray and Variable if expected_dtype is None: # check output type instead of array dtype From 5a96460dcba1bdfcedb3f2950628edca8a939e87 Mon Sep 17 00:00:00 2001 From: Maximilian Roos <5635139+max-sixty@users.noreply.github.com> Date: Wed, 16 Jan 2019 10:35:51 +0100 Subject: [PATCH 02/11] Update README.rst (#2682) --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index f30d9dde8bb..f69f7d95c31 100644 --- a/README.rst +++ b/README.rst @@ -114,7 +114,7 @@ __ http://climate.com/ License ------- -Copyright 2014-2018, xarray Developers +Copyright 2014-2019, xarray Developers Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From dc87dea52351835af472d131f70a7f7603b3100e Mon Sep 17 00:00:00 2001 From: Tom Nicholas <35968931+TomNicholas@users.noreply.github.com> Date: Thu, 17 Jan 2019 13:05:42 +0000 Subject: [PATCH 03/11] Hotfix for #2662 (#2678) * Hotfix for #2662 * Separate keyfunc * Added a test, and made others slightly stricter * Comment explaining test better --- xarray/core/combine.py | 9 +++++++-- xarray/tests/test_combine.py | 16 ++++++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/xarray/core/combine.py b/xarray/core/combine.py index e552d8d900c..0327a65ab1b 100644 --- a/xarray/core/combine.py +++ b/xarray/core/combine.py @@ -493,16 +493,21 @@ def _auto_combine_all_along_first_dim(combined_ids, dim, data_vars, return new_combined_ids +def vars_as_keys(ds): + return tuple(sorted(ds)) + + def _auto_combine_1d(datasets, concat_dim=_CONCAT_DIM_DEFAULT, compat='no_conflicts', data_vars='all', coords='different'): # This is just the old auto_combine function (which only worked along 1D) if concat_dim is not None: dim = None if concat_dim is _CONCAT_DIM_DEFAULT else concat_dim - grouped = itertools.groupby(datasets, key=lambda ds: tuple(sorted(ds))) + sorted_datasets = sorted(datasets, key=vars_as_keys) + grouped_by_vars = itertools.groupby(sorted_datasets, key=vars_as_keys) concatenated = [_auto_concat(list(ds_group), dim=dim, data_vars=data_vars, coords=coords) - for id, ds_group in grouped] + for id, ds_group in grouped_by_vars] else: concatenated = datasets merged = merge(concatenated, compat=compat) diff --git a/xarray/tests/test_combine.py b/xarray/tests/test_combine.py index 9ea38e7d5f2..e978350d322 100644 --- a/xarray/tests/test_combine.py +++ b/xarray/tests/test_combine.py @@ -650,7 +650,7 @@ def test_merge_one_dim_concat_another(self): expected = Dataset({'foo': ('x', [0, 1, 2, 3]), 'bar': ('x', [10, 20, 30, 40])}) - actual = auto_combine(objs, concat_dim=['x', None]) + actual = auto_combine(objs, concat_dim=['x', None], compat='equals') assert_identical(expected, actual) actual = auto_combine(objs) @@ -661,7 +661,19 @@ def test_merge_one_dim_concat_another(self): Dataset({'foo': ('x', [2, 3])})], [Dataset({'bar': ('x', [10, 20])}), Dataset({'bar': ('x', [30, 40])})]] - actual = auto_combine(objs, concat_dim=[None, 'x']) + actual = auto_combine(objs, concat_dim=[None, 'x'], compat='equals') + assert_identical(expected, actual) + + def test_internal_ordering(self): + # This gives a MergeError if _auto_combine_1d is not sorting by + # data_vars correctly, see GH #2662 + objs = [Dataset({'foo': ('x', [0, 1])}), + Dataset({'bar': ('x', [10, 20])}), + Dataset({'foo': ('x', [2, 3])}), + Dataset({'bar': ('x', [30, 40])})] + actual = auto_combine(objs, concat_dim='x', compat='equals') + expected = Dataset({'foo': ('x', [0, 1, 2, 3]), + 'bar': ('x', [10, 20, 30, 40])}) assert_identical(expected, actual) def test_combine_concat_over_redundant_nesting(self): From 1d0a2bc4970d9e7337fe307f4519bd936f7d7d89 Mon Sep 17 00:00:00 2001 From: Benoit Bovy Date: Fri, 18 Jan 2019 10:16:30 +0100 Subject: [PATCH 04/11] Detailed report for testing.assert_equal and testing.assert_identical (#1507) * more detailed AssertionError message for assert_identical * print differing dimensions/data/variables/attributes * minor tweaks * add what's new entry * add tests for diff_array_repr and diff_dataset_repr * pep8 * add differing dimensions in diff_array_repr * fix tests (explicit numpy dtypes) * fix tests (dtype shown / not shown in array repr) * minor tweaks --- doc/whats-new.rst | 5 ++ xarray/core/formatting.py | 146 ++++++++++++++++++++++++++++++-- xarray/testing.py | 15 ++-- xarray/tests/test_formatting.py | 117 +++++++++++++++++++++++++ 4 files changed, 272 insertions(+), 11 deletions(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index b50df2af10e..4a351716fab 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -36,6 +36,11 @@ Enhancements - Upsampling an array via interpolation with resample is now dask-compatible, as long as the array is not chunked along the resampling dimension. By `Spencer Clark `_. +- :py:func:`xarray.testing.assert_equal` and + :py:func:`xarray.testing.assert_identical` now provide a more detailed + report showing what exactly differs between the two objects (dimensions / + coordinates / variables / attributes) (:issue:`1507`). + By `Benoit Bovy `_. Bug fixes ~~~~~~~~~ diff --git a/xarray/core/formatting.py b/xarray/core/formatting.py index 5dd3cf06025..50fa64c9987 100644 --- a/xarray/core/formatting.py +++ b/xarray/core/formatting.py @@ -13,6 +13,7 @@ import numpy as np import pandas as pd +from .duck_array_ops import array_equiv from .options import OPTIONS from .pycompat import ( PY2, bytes_type, dask_array_type, unicode_type, zip_longest) @@ -411,6 +412,15 @@ def short_dask_repr(array, show_dtype=True): return 'dask.array' % (array.shape, chunksize) +def short_data_repr(array): + if isinstance(getattr(array, 'variable', array)._data, dask_array_type): + return short_dask_repr(array) + elif array._in_memory or array.size < 1e5: + return short_array_repr(array.values) + else: + return u'[%s values with dtype=%s]' % (array.size, array.dtype) + + def array_repr(arr): # used for DataArray, Variable and IndexVariable if hasattr(arr, 'name') and arr.name is not None: @@ -421,12 +431,7 @@ def array_repr(arr): summary = [u'' % (type(arr).__name__, name_str, dim_summary(arr))] - if isinstance(getattr(arr, 'variable', arr)._data, dask_array_type): - summary.append(short_dask_repr(arr)) - elif arr._in_memory or arr.size < 1e5: - summary.append(short_array_repr(arr.values)) - else: - summary.append(u'[%s values with dtype=%s]' % (arr.size, arr.dtype)) + summary.append(short_data_repr(arr)) if hasattr(arr, 'coords'): if arr.coords: @@ -463,3 +468,132 @@ def dataset_repr(ds): summary.append(attrs_repr(ds.attrs)) return u'\n'.join(summary) + + +def diff_dim_summary(a, b): + if a.dims != b.dims: + return "Differing dimensions:\n ({}) != ({})".format( + dim_summary(a), dim_summary(b)) + else: + return "" + + +def _diff_mapping_repr(a_mapping, b_mapping, compat, + title, summarizer, col_width=None): + + def extra_items_repr(extra_keys, mapping, ab_side): + extra_repr = [summarizer(k, mapping[k], col_width) for k in extra_keys] + if extra_repr: + header = "{} only on the {} object:".format(title, ab_side) + return [header] + extra_repr + else: + return [] + + a_keys = set(a_mapping) + b_keys = set(b_mapping) + + summary = [] + + diff_items = [] + + for k in a_keys & b_keys: + try: + # compare xarray variable + compatible = getattr(a_mapping[k], compat)(b_mapping[k]) + is_variable = True + except AttributeError: + # compare attribute value + compatible = a_mapping[k] == b_mapping[k] + is_variable = False + + if not compatible: + temp = [summarizer(k, vars[k], col_width) + for vars in (a_mapping, b_mapping)] + + if compat == 'identical' and is_variable: + attrs_summary = [] + + for m in (a_mapping, b_mapping): + attr_s = "\n".join([summarize_attr(ak, av) + for ak, av in m[k].attrs.items()]) + attrs_summary.append(attr_s) + + temp = ["\n".join([var_s, attr_s]) if attr_s else var_s + for var_s, attr_s in zip(temp, attrs_summary)] + + diff_items += [ab_side + s[1:] + for ab_side, s in zip(('L', 'R'), temp)] + + if diff_items: + summary += ["Differing {}:".format(title.lower())] + diff_items + + summary += extra_items_repr(a_keys - b_keys, a_mapping, "left") + summary += extra_items_repr(b_keys - a_keys, b_mapping, "right") + + return "\n".join(summary) + + +diff_coords_repr = functools.partial(_diff_mapping_repr, + title="Coordinates", + summarizer=summarize_coord) + + +diff_data_vars_repr = functools.partial(_diff_mapping_repr, + title="Data variables", + summarizer=summarize_datavar) + + +diff_attrs_repr = functools.partial(_diff_mapping_repr, + title="Attributes", + summarizer=summarize_attr) + + +def _compat_to_str(compat): + if compat == "equals": + return "equal" + else: + return compat + + +def diff_array_repr(a, b, compat): + # used for DataArray, Variable and IndexVariable + summary = ["Left and right {} objects are not {}" + .format(type(a).__name__, _compat_to_str(compat))] + + summary.append(diff_dim_summary(a, b)) + + if not array_equiv(a.data, b.data): + temp = [wrap_indent(short_array_repr(obj), start=' ') + for obj in (a, b)] + diff_data_repr = [ab_side + "\n" + ab_data_repr + for ab_side, ab_data_repr in zip(('L', 'R'), temp)] + summary += ["Differing values:"] + diff_data_repr + + if hasattr(a, 'coords'): + col_width = _calculate_col_width(set(a.coords) | set(b.coords)) + summary.append(diff_coords_repr(a.coords, b.coords, compat, + col_width=col_width)) + + if compat == 'identical': + summary.append(diff_attrs_repr(a.attrs, b.attrs, compat)) + + return "\n".join(summary) + + +def diff_dataset_repr(a, b, compat): + summary = ["Left and right {} objects are not {}" + .format(type(a).__name__, _compat_to_str(compat))] + + col_width = _calculate_col_width( + set(_get_col_items(a.variables) + _get_col_items(b.variables))) + + summary.append(diff_dim_summary(a, b)) + summary.append(diff_coords_repr(a.coords, b.coords, compat, + col_width=col_width)) + summary.append(diff_data_vars_repr(a.data_vars, b.data_vars, compat, + col_width=col_width)) + + if compat == 'identical': + summary.append(diff_attrs_repr(a.attrs, b.attrs, compat)) + + return "\n".join(summary) diff --git a/xarray/testing.py b/xarray/testing.py index c2bb5044ef4..418f1a08668 100644 --- a/xarray/testing.py +++ b/xarray/testing.py @@ -4,6 +4,7 @@ import numpy as np from xarray.core import duck_array_ops +from xarray.core import formatting def _decode_string_data(data): @@ -49,8 +50,10 @@ def assert_equal(a, b): import xarray as xr __tracebackhide__ = True # noqa: F841 assert type(a) == type(b) # noqa - if isinstance(a, (xr.Variable, xr.DataArray, xr.Dataset)): - assert a.equals(b), '{}\n{}'.format(a, b) + if isinstance(a, (xr.Variable, xr.DataArray)): + assert a.equals(b), formatting.diff_array_repr(a, b, 'equals') + elif isinstance(a, xr.Dataset): + assert a.equals(b), formatting.diff_dataset_repr(a, b, 'equals') else: raise TypeError('{} not supported by assertion comparison' .format(type(a))) @@ -76,11 +79,13 @@ def assert_identical(a, b): import xarray as xr __tracebackhide__ = True # noqa: F841 assert type(a) == type(b) # noqa - if isinstance(a, xr.DataArray): + if isinstance(a, xr.Variable): + assert a.identical(b), formatting.diff_array_repr(a, b, 'identical') + elif isinstance(a, xr.DataArray): assert a.name == b.name - assert_identical(a._to_temp_dataset(), b._to_temp_dataset()) + assert a.identical(b), formatting.diff_array_repr(a, b, 'identical') elif isinstance(a, (xr.Dataset, xr.Variable)): - assert a.identical(b), '{}\n{}'.format(a, b) + assert a.identical(b), formatting.diff_dataset_repr(a, b, 'identical') else: raise TypeError('{} not supported by assertion comparison' .format(type(a))) diff --git a/xarray/tests/test_formatting.py b/xarray/tests/test_formatting.py index 024c669bed9..6ca5e6f5363 100644 --- a/xarray/tests/test_formatting.py +++ b/xarray/tests/test_formatting.py @@ -1,9 +1,12 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, division, print_function +from textwrap import dedent + import numpy as np import pandas as pd +import xarray as xr from xarray.core import formatting from xarray.core.pycompat import PY3 @@ -190,6 +193,120 @@ def test_attribute_repr(self): assert u'\n' not in newlines assert u'\t' not in tabs + def test_diff_array_repr(self): + da_a = xr.DataArray( + np.array([[1, 2, 3], [4, 5, 6]], dtype='int64'), + dims=('x', 'y'), + coords={'x': np.array(['a', 'b'], dtype='U1'), + 'y': np.array([1, 2, 3], dtype='int64')}, + attrs={'units': 'm', 'description': 'desc'}) + + da_b = xr.DataArray( + np.array([1, 2], dtype='int64'), + dims='x', + coords={'x': np.array(['a', 'c'], dtype='U1'), + 'label': ('x', np.array([1, 2], dtype='int64'))}, + attrs={'units': 'kg'}) + + expected = dedent("""\ + Left and right DataArray objects are not identical + Differing dimensions: + (x: 2, y: 3) != (x: 2) + Differing values: + L + array([[1, 2, 3], + [4, 5, 6]], dtype=int64) + R + array([1, 2], dtype=int64) + Differing coordinates: + L * x (x) Date: Fri, 18 Jan 2019 13:47:43 -0800 Subject: [PATCH 05/11] try no rasterio in py36 env (#2691) * try no rasterio in py36 env * no pynio or iris either * pin min gdal version in doc build --- .travis.yml | 2 +- ci/requirements-py36.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8e1866de8d4..a21d4d94413 100644 --- a/.travis.yml +++ b/.travis.yml @@ -60,7 +60,7 @@ script: - python --version - python -OO -c "import xarray" - if [[ "$CONDA_ENV" == "docs" ]]; then - conda install -c conda-forge sphinx sphinx_rtd_theme sphinx-gallery numpydoc; + conda install -c conda-forge --override-channels sphinx sphinx_rtd_theme sphinx-gallery numpydoc "gdal>2.2.4"; sphinx-build -n -j auto -b html -d _build/doctrees doc _build/html; elif [[ "$CONDA_ENV" == "lint" ]]; then pycodestyle xarray ; diff --git a/ci/requirements-py36.yml b/ci/requirements-py36.yml index 311e4a275a8..0ed6dd78c3a 100644 --- a/ci/requirements-py36.yml +++ b/ci/requirements-py36.yml @@ -20,14 +20,14 @@ dependencies: - scipy - seaborn - toolz - - rasterio + # - rasterio # xref #2683 - bottleneck - zarr - pseudonetcdf>=3.0.1 - eccodes - cdms2 - - pynio - - iris>=1.10 + # - pynio # xref #2683 + # - iris>=1.10 # xref #2683 - pydap - lxml - pip: From ec255eba7cce749c25e1d7b6f0a7fc537ff61841 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Sat, 19 Jan 2019 11:45:19 -0600 Subject: [PATCH 06/11] Update asv.conf.json (#2693) --- asv_bench/asv.conf.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asv_bench/asv.conf.json b/asv_bench/asv.conf.json index e3933b400e6..11a779ae376 100644 --- a/asv_bench/asv.conf.json +++ b/asv_bench/asv.conf.json @@ -40,7 +40,7 @@ // The Pythons you'd like to test against. If not provided, defaults // to the current version of Python used to run `asv`. - "pythons": ["2.7", "3.6"], + "pythons": ["3.6"], // The matrix of dependencies to test. Each key is the name of a // package (in PyPI) and the values are version numbers. An empty From a7d55b9bcd0cc19330b5784842d51af5309d07ee Mon Sep 17 00:00:00 2001 From: Ryan Abernathey Date: Tue, 22 Jan 2019 00:25:55 +0100 Subject: [PATCH 07/11] to_dict without data (#2659) * add data=False to to_dict methods * doc and whats-new * fix pep8 errors * small tweaks * added shape and dtype --- doc/io.rst | 12 +++++++++++- doc/whats-new.rst | 2 ++ xarray/core/dataarray.py | 22 ++++++++++------------ xarray/core/dataset.py | 21 +++++++++------------ xarray/core/variable.py | 13 ++++++++++++- xarray/tests/test_dataarray.py | 9 +++++++++ xarray/tests/test_dataset.py | 20 +++++++++++++++++--- 7 files changed, 70 insertions(+), 29 deletions(-) diff --git a/doc/io.rst b/doc/io.rst index 151f5eb740f..0dc5181f9b8 100644 --- a/doc/io.rst +++ b/doc/io.rst @@ -81,6 +81,16 @@ require external libraries and dicts can easily be pickled, or converted to json, or geojson. All the values are converted to lists, so dicts might be quite large. +To export just the dataset schema, without the data itself, use the +``data=False`` option: + +.. ipython:: python + + ds.to_dict(data=False) + +This can be useful for generating indices of dataset contents to expose to +search indices or other automated data discovery tools. + .. _io.netcdf: netCDF @@ -665,7 +675,7 @@ To read a consolidated store, pass the ``consolidated=True`` option to :py:func:`~xarray.open_zarr`:: ds = xr.open_zarr('foo.zarr', consolidated=True) - + Xarray can't perform consolidation on pre-existing zarr datasets. This should be done directly from zarr, as described in the `zarr docs `_. diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 4a351716fab..c408306ffdb 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -28,6 +28,8 @@ Breaking changes Enhancements ~~~~~~~~~~~~ +- Add ``data=False`` option to ``to_dict()`` methods. (:issue:`2656`) + By `Ryan Abernathey `_ - :py:meth:`~xarray.DataArray.coarsen` and :py:meth:`~xarray.Dataset.coarsen` are newly added. See :ref:`comput.coarsen` for details. diff --git a/xarray/core/dataarray.py b/xarray/core/dataarray.py index f27958b1c77..aa6c35394fb 100644 --- a/xarray/core/dataarray.py +++ b/xarray/core/dataarray.py @@ -1760,7 +1760,7 @@ def to_netcdf(self, *args, **kwargs): return dataset.to_netcdf(*args, **kwargs) - def to_dict(self): + def to_dict(self, data=True): """ Convert this xarray.DataArray into a dictionary following xarray naming conventions. @@ -1769,22 +1769,20 @@ def to_dict(self): Useful for coverting to json. To avoid datetime incompatibility use decode_times=False kwarg in xarrray.open_dataset. + Parameters + ---------- + data : bool, optional + Whether to include the actual data in the dictionary. When set to + False, returns just the schema. + See also -------- DataArray.from_dict """ - d = {'coords': {}, 'attrs': decode_numpy_dict_values(self.attrs), - 'dims': self.dims} - + d = self.variable.to_dict(data=data) + d.update({'coords': {}, 'name': self.name}) for k in self.coords: - data = ensure_us_time_resolution(self[k].values).tolist() - d['coords'].update({ - k: {'data': data, - 'dims': self[k].dims, - 'attrs': decode_numpy_dict_values(self[k].attrs)}}) - - d.update({'data': ensure_us_time_resolution(self.values).tolist(), - 'name': self.name}) + d['coords'][k] = self.coords[k].variable.to_dict(data=data) return d @classmethod diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index 2caf45ce954..3f1c038fc11 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -3221,7 +3221,7 @@ def to_dask_dataframe(self, dim_order=None, set_index=False): return df - def to_dict(self): + def to_dict(self, data=True): """ Convert this dataset to a dictionary following xarray naming conventions. @@ -3230,25 +3230,22 @@ def to_dict(self): Useful for coverting to json. To avoid datetime incompatibility use decode_times=False kwarg in xarrray.open_dataset. + Parameters + ---------- + data : bool, optional + Whether to include the actual data in the dictionary. When set to + False, returns just the schema. + See also -------- Dataset.from_dict """ d = {'coords': {}, 'attrs': decode_numpy_dict_values(self.attrs), 'dims': dict(self.dims), 'data_vars': {}} - for k in self.coords: - data = ensure_us_time_resolution(self[k].values).tolist() - d['coords'].update({ - k: {'data': data, - 'dims': self[k].dims, - 'attrs': decode_numpy_dict_values(self[k].attrs)}}) + d['coords'].update({k: self[k].variable.to_dict(data=data)}) for k in self.data_vars: - data = ensure_us_time_resolution(self[k].values).tolist() - d['data_vars'].update({ - k: {'data': data, - 'dims': self[k].dims, - 'attrs': decode_numpy_dict_values(self[k].attrs)}}) + d['data_vars'].update({k: self[k].variable.to_dict(data=data)}) return d @classmethod diff --git a/xarray/core/variable.py b/xarray/core/variable.py index 8bd7225efc3..a71b148baf3 100644 --- a/xarray/core/variable.py +++ b/xarray/core/variable.py @@ -19,7 +19,8 @@ from .options import _get_keep_attrs from .pycompat import ( OrderedDict, basestring, dask_array_type, integer_types, zip) -from .utils import OrderedSet, either_dict_or_kwargs +from .utils import (OrderedSet, either_dict_or_kwargs, + decode_numpy_dict_values, ensure_us_time_resolution) try: import dask.array as da @@ -410,6 +411,16 @@ def to_index(self): """Convert this variable to a pandas.Index""" return self.to_index_variable().to_index() + def to_dict(self, data=True): + """Dictionary representation of variable.""" + item = {'dims': self.dims, + 'attrs': decode_numpy_dict_values(self.attrs)} + if data: + item['data'] = ensure_us_time_resolution(self.values).tolist() + else: + item.update({'dtype': str(self.dtype), 'shape': self.shape}) + return item + @property def dims(self): """Tuple of dimension names with which this variable is associated. diff --git a/xarray/tests/test_dataarray.py b/xarray/tests/test_dataarray.py index aa02e802fc5..8995fca2f95 100644 --- a/xarray/tests/test_dataarray.py +++ b/xarray/tests/test_dataarray.py @@ -2909,6 +2909,15 @@ def test_to_and_from_dict(self): ValueError, "cannot convert dict without the key 'data'"): DataArray.from_dict(d) + # check the data=False option + expected_no_data = expected.copy() + del expected_no_data['data'] + del expected_no_data['coords']['x']['data'] + expected_no_data['coords']['x'].update({'dtype': ' Date: Tue, 22 Jan 2019 21:49:59 -0500 Subject: [PATCH 08/11] Config for closing stale issues (#2684) * stale settings * one month before close * exempt assignees --- .github/stale.yml | 58 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 .github/stale.yml diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 00000000000..b969da0c6b4 --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,58 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 700 # start with a large number and reduce shortly + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - pinned + - security + - "[Status] Maybe Later" + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: true + +# Label to use when marking as stale +staleLabel: closed_as_stale + +# Comment to post when marking as stale. Set to `false` to disable +markComment: > + In order to maintain a list of currently relevant issues, we mark issues as stale after a period of inactivity + If this issue remains relevant, please comment here; otherwise it will be marked as closed automatically + +# Comment to post when removing the stale label. +# unmarkComment: > +# Your comment here. + +# Comment to post when closing a stale Issue or Pull Request. +# closeComment: > +# Your comment here. + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 1 # start with a small number + + +# Limit to only `issues` or `pulls` +# only: issues + +# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls': +# pulls: +# daysUntilStale: 30 +# markComment: > +# This pull request has been automatically marked as stale because it has not had +# recent activity. It will be closed if no further activity occurs. Thank you +# for your contributions. + +# issues: +# exemptLabels: +# - confirmed \ No newline at end of file From e53f21ce6c9ad8c74b1f6cc9dd00d374688ca0fe Mon Sep 17 00:00:00 2001 From: Maximilian Roos <5635139+max-sixty@users.noreply.github.com> Date: Wed, 23 Jan 2019 11:17:35 -0500 Subject: [PATCH 09/11] add line break to message posted (#2698) --- .github/stale.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/stale.yml b/.github/stale.yml index b969da0c6b4..099645333ec 100644 --- a/.github/stale.yml +++ b/.github/stale.yml @@ -23,10 +23,10 @@ exemptMilestones: false exemptAssignees: true # Label to use when marking as stale -staleLabel: closed_as_stale +staleLabel: # Comment to post when marking as stale. Set to `false` to disable -markComment: > +markComment: | In order to maintain a list of currently relevant issues, we mark issues as stale after a period of inactivity If this issue remains relevant, please comment here; otherwise it will be marked as closed automatically From ddacf405fb256714ce01e1c4c464f829e1cc5058 Mon Sep 17 00:00:00 2001 From: waderoberts123 <32141163+waderoberts123@users.noreply.github.com> Date: Wed, 23 Jan 2019 14:09:41 -0700 Subject: [PATCH 10/11] Update indexing.rst (#2700) Grammar error --- doc/indexing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/indexing.rst b/doc/indexing.rst index 3878d983cf6..77ec7428991 100644 --- a/doc/indexing.rst +++ b/doc/indexing.rst @@ -371,7 +371,7 @@ Vectorized indexing also works with ``isel``, ``loc``, and ``sel``: ind = xr.DataArray([['a', 'b'], ['b', 'a']], dims=['a', 'b']) da.loc[:, ind] # same as da.sel(y=ind) -These methods may and also be applied to ``Dataset`` objects +These methods may also be applied to ``Dataset`` objects .. ipython:: python From 79fa060dd6b567e8aa3606b8b8cc0c54d1b14acb Mon Sep 17 00:00:00 2001 From: Maximilian Roos <5635139+max-sixty@users.noreply.github.com> Date: Wed, 23 Jan 2019 20:08:46 -0500 Subject: [PATCH 11/11] stale requires a label (#2701) --- .github/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/stale.yml b/.github/stale.yml index 099645333ec..5a8f6596d69 100644 --- a/.github/stale.yml +++ b/.github/stale.yml @@ -23,7 +23,7 @@ exemptMilestones: false exemptAssignees: true # Label to use when marking as stale -staleLabel: +staleLabel: stale # Comment to post when marking as stale. Set to `false` to disable markComment: |