From 3c462b9663bfd9f609b567a7743465aa1b413b1e Mon Sep 17 00:00:00 2001 From: Maximilian Roos <5635139+max-sixty@users.noreply.github.com> Date: Sun, 20 Oct 2019 20:16:58 -0400 Subject: [PATCH] Python3.6 idioms (#3419) * pyupgrade --py36-plus * Update xarray/core/nputils.py Co-Authored-By: crusaderky * Update xarray/core/parallel.py Co-Authored-By: crusaderky * Update xarray/tests/test_cftime_offsets.py Co-Authored-By: crusaderky * Update xarray/tests/test_cftime_offsets.py Co-Authored-By: crusaderky --- doc/gallery/plot_cartopy_facetgrid.py | 1 - doc/gallery/plot_colorbar_center.py | 1 - doc/gallery/plot_control_colorbar.py | 1 - doc/gallery/plot_lines_from_2d.py | 1 - doc/gallery/plot_rasterio.py | 1 - doc/gallery/plot_rasterio_rgb.py | 1 - xarray/_version.py | 7 ++--- xarray/backends/api.py | 6 ++-- xarray/backends/file_manager.py | 4 +-- xarray/backends/netCDF4_.py | 2 +- xarray/backends/netcdf3.py | 2 +- xarray/backends/pydap_.py | 2 +- xarray/coding/cftime_offsets.py | 10 ++---- xarray/coding/cftimeindex.py | 2 +- xarray/coding/strings.py | 2 +- xarray/coding/times.py | 4 +-- xarray/coding/variables.py | 9 ++---- xarray/convert.py | 14 ++++----- xarray/core/alignment.py | 8 ++--- xarray/core/common.py | 20 ++++++------ xarray/core/computation.py | 24 +++++++-------- xarray/core/concat.py | 2 +- xarray/core/dataarray.py | 44 +++++++++++++-------------- xarray/core/dataset.py | 22 ++++++-------- xarray/core/duck_array_ops.py | 4 +-- xarray/core/formatting.py | 32 +++++++++---------- xarray/core/groupby.py | 4 +-- xarray/core/indexing.py | 22 +++++++++----- xarray/core/merge.py | 4 ++- xarray/core/nputils.py | 6 ++-- xarray/core/options.py | 2 +- xarray/core/parallel.py | 11 +++---- xarray/core/utils.py | 10 +++--- xarray/core/variable.py | 14 ++++----- xarray/plot/dataset_plot.py | 20 ++++++------ xarray/plot/plot.py | 14 ++++----- xarray/plot/utils.py | 4 +-- xarray/testing.py | 2 +- xarray/tests/__init__.py | 4 +-- xarray/tests/test_accessor_str.py | 2 +- xarray/tests/test_backends.py | 16 +++++----- xarray/tests/test_cftime_offsets.py | 4 +-- xarray/tests/test_coding_strings.py | 1 - xarray/tests/test_coding_times.py | 12 ++++---- xarray/tests/test_computation.py | 4 +-- xarray/tests/test_conventions.py | 1 - xarray/tests/test_dataarray.py | 4 +-- xarray/tests/test_dataset.py | 3 +- xarray/tests/test_duck_array_ops.py | 4 +-- xarray/tests/test_formatting.py | 1 - xarray/tests/test_plot.py | 2 +- xarray/tests/test_sparse.py | 2 +- xarray/tests/test_tutorial.py | 4 +-- xarray/tests/test_units.py | 8 ++--- xarray/tests/test_variable.py | 2 +- xarray/ufuncs.py | 2 +- xarray/util/print_versions.py | 6 ++-- 57 files changed, 200 insertions(+), 221 deletions(-) diff --git a/doc/gallery/plot_cartopy_facetgrid.py b/doc/gallery/plot_cartopy_facetgrid.py index 11db9b800b5..d8f5e73ee56 100644 --- a/doc/gallery/plot_cartopy_facetgrid.py +++ b/doc/gallery/plot_cartopy_facetgrid.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ ================================== Multiple plots and map projections diff --git a/doc/gallery/plot_colorbar_center.py b/doc/gallery/plot_colorbar_center.py index 8227dc5ba0c..42d6448adf6 100644 --- a/doc/gallery/plot_colorbar_center.py +++ b/doc/gallery/plot_colorbar_center.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ ================== Centered colormaps diff --git a/doc/gallery/plot_control_colorbar.py b/doc/gallery/plot_control_colorbar.py index bd1f2c69a44..8fb8d7f8be6 100644 --- a/doc/gallery/plot_control_colorbar.py +++ b/doc/gallery/plot_control_colorbar.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ =========================== Control the plot's colorbar diff --git a/doc/gallery/plot_lines_from_2d.py b/doc/gallery/plot_lines_from_2d.py index 2aebda2f323..1b2845cd8a9 100644 --- a/doc/gallery/plot_lines_from_2d.py +++ b/doc/gallery/plot_lines_from_2d.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ ================================== Multiple lines from a 2d DataArray diff --git a/doc/gallery/plot_rasterio.py b/doc/gallery/plot_rasterio.py index d5cbb0700cc..99eb1fd1daf 100644 --- a/doc/gallery/plot_rasterio.py +++ b/doc/gallery/plot_rasterio.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ .. _recipes.rasterio: diff --git a/doc/gallery/plot_rasterio_rgb.py b/doc/gallery/plot_rasterio_rgb.py index 4b5b30ea793..758d4cd3c37 100644 --- a/doc/gallery/plot_rasterio_rgb.py +++ b/doc/gallery/plot_rasterio_rgb.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ .. _recipes.rasterio_rgb: diff --git a/xarray/_version.py b/xarray/_version.py index 826bf470ca7..0ccb33a5e56 100644 --- a/xarray/_version.py +++ b/xarray/_version.py @@ -94,7 +94,7 @@ def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env= return None, None else: if verbose: - print("unable to find command, tried %s" % (commands,)) + print(f"unable to find command, tried {commands}") return None, None stdout = p.communicate()[0].strip() if sys.version_info[0] >= 3: @@ -302,9 +302,8 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): if verbose: fmt = "tag '%s' doesn't start with prefix '%s'" print(fmt % (full_tag, tag_prefix)) - pieces["error"] = "tag '%s' doesn't start with prefix '%s'" % ( - full_tag, - tag_prefix, + pieces["error"] = "tag '{}' doesn't start with prefix '{}'".format( + full_tag, tag_prefix ) return pieces pieces["closest-tag"] = full_tag[len(tag_prefix) :] diff --git a/xarray/backends/api.py b/xarray/backends/api.py index 8f6881b804a..199516116b0 100644 --- a/xarray/backends/api.py +++ b/xarray/backends/api.py @@ -718,7 +718,7 @@ def open_mfdataset( autoclose=None, parallel=False, join="outer", - **kwargs + **kwargs, ): """Open multiple files as a single dataset. @@ -1258,9 +1258,7 @@ def _validate_append_dim_and_encoding( return if append_dim: if append_dim not in ds.dims: - raise ValueError( - "{} not a valid dimension in the Dataset".format(append_dim) - ) + raise ValueError(f"{append_dim} not a valid dimension in the Dataset") for data_var in ds_to_append: if data_var in ds: if append_dim is None: diff --git a/xarray/backends/file_manager.py b/xarray/backends/file_manager.py index a3c1961373a..4967788a1e7 100644 --- a/xarray/backends/file_manager.py +++ b/xarray/backends/file_manager.py @@ -83,7 +83,7 @@ def __init__( kwargs=None, lock=None, cache=None, - ref_counts=None + ref_counts=None, ): """Initialize a FileManager. @@ -267,7 +267,7 @@ def __setstate__(self, state): def __repr__(self): args_string = ", ".join(map(repr, self._args)) if self._mode is not _DEFAULT_MODE: - args_string += ", mode={!r}".format(self._mode) + args_string += f", mode={self._mode!r}" return "{}({!r}, {}, kwargs={})".format( type(self).__name__, self._opener, args_string, self._kwargs ) diff --git a/xarray/backends/netCDF4_.py b/xarray/backends/netCDF4_.py index 2edcca7c617..0e454ec47de 100644 --- a/xarray/backends/netCDF4_.py +++ b/xarray/backends/netCDF4_.py @@ -137,7 +137,7 @@ def _nc4_dtype(var): elif var.dtype.kind in ["i", "u", "f", "c", "S"]: dtype = var.dtype else: - raise ValueError("unsupported dtype for netCDF4 variable: {}".format(var.dtype)) + raise ValueError(f"unsupported dtype for netCDF4 variable: {var.dtype}") return dtype diff --git a/xarray/backends/netcdf3.py b/xarray/backends/netcdf3.py index 887eafc972e..d26b6ce2ea9 100644 --- a/xarray/backends/netcdf3.py +++ b/xarray/backends/netcdf3.py @@ -50,7 +50,7 @@ def coerce_nc3_dtype(arr): cast_arr = arr.astype(new_dtype) if not (cast_arr == arr).all(): raise ValueError( - "could not safely cast array from dtype %s to %s" % (dtype, new_dtype) + f"could not safely cast array from dtype {dtype} to {new_dtype}" ) arr = cast_arr return arr diff --git a/xarray/backends/pydap_.py b/xarray/backends/pydap_.py index ca2bf73d048..7ef4ec66241 100644 --- a/xarray/backends/pydap_.py +++ b/xarray/backends/pydap_.py @@ -49,7 +49,7 @@ def _fix_attributes(attributes): # dot-separated key attributes.update( { - "{}.{}".format(k, k_child): v_child + f"{k}.{k_child}": v_child for k_child, v_child in attributes.pop(k).items() } ) diff --git a/xarray/coding/cftime_offsets.py b/xarray/coding/cftime_offsets.py index 515d309d75b..af46510f7c4 100644 --- a/xarray/coding/cftime_offsets.py +++ b/xarray/coding/cftime_offsets.py @@ -638,7 +638,7 @@ def __apply__(self, other): _FREQUENCY_CONDITION = "|".join(_FREQUENCIES.keys()) -_PATTERN = r"^((?P\d+)|())(?P({}))$".format(_FREQUENCY_CONDITION) +_PATTERN = fr"^((?P\d+)|())(?P({_FREQUENCY_CONDITION}))$" # pandas defines these offsets as "Tick" objects, which for instance have @@ -759,9 +759,7 @@ def _generate_range(start, end, periods, offset): next_date = current + offset if next_date <= current: - raise ValueError( - "Offset {offset} did not increment date".format(offset=offset) - ) + raise ValueError(f"Offset {offset} did not increment date") current = next_date else: while current >= end: @@ -769,9 +767,7 @@ def _generate_range(start, end, periods, offset): next_date = current + offset if next_date >= current: - raise ValueError( - "Offset {offset} did not decrement date".format(offset=offset) - ) + raise ValueError(f"Offset {offset} did not decrement date") current = next_date diff --git a/xarray/coding/cftimeindex.py b/xarray/coding/cftimeindex.py index 802dd94f06c..434d55d6569 100644 --- a/xarray/coding/cftimeindex.py +++ b/xarray/coding/cftimeindex.py @@ -403,7 +403,7 @@ def shift(self, n, freq): from .cftime_offsets import to_offset if not isinstance(n, int): - raise TypeError("'n' must be an int, got {}.".format(n)) + raise TypeError(f"'n' must be an int, got {n}.") if isinstance(freq, timedelta): return self + n * freq elif isinstance(freq, str): diff --git a/xarray/coding/strings.py b/xarray/coding/strings.py index 44d07929e35..6d383fcf318 100644 --- a/xarray/coding/strings.py +++ b/xarray/coding/strings.py @@ -228,7 +228,7 @@ def shape(self): return self.array.shape[:-1] def __repr__(self): - return "%s(%r)" % (type(self).__name__, self.array) + return "{}({!r})".format(type(self).__name__, self.array) def __getitem__(self, key): # require slicing the last dimension completely diff --git a/xarray/coding/times.py b/xarray/coding/times.py index ed6908117a2..0174088064b 100644 --- a/xarray/coding/times.py +++ b/xarray/coding/times.py @@ -286,7 +286,7 @@ def infer_datetime_units(dates): # NumPy casting bug: https://github.com/numpy/numpy/issues/11096 unique_timedeltas = to_timedelta_unboxed(unique_timedeltas) units = _infer_time_units_from_diff(unique_timedeltas) - return "%s since %s" % (units, reference_date) + return f"{units} since {reference_date}" def format_cftime_datetime(date): @@ -341,7 +341,7 @@ def cftime_to_nptime(times): def _cleanup_netcdf_time_units(units): delta, ref_date = _unpack_netcdf_time_units(units) try: - units = "%s since %s" % (delta, format_timestamp(ref_date)) + units = "{} since {}".format(delta, format_timestamp(ref_date)) except OutOfBoundsDatetime: # don't worry about reifying the units if they're out of bounds pass diff --git a/xarray/coding/variables.py b/xarray/coding/variables.py index f78502d81be..5f9c8932b6b 100644 --- a/xarray/coding/variables.py +++ b/xarray/coding/variables.py @@ -73,11 +73,8 @@ def __array__(self, dtype=None): return self.func(self.array) def __repr__(self): - return "%s(%r, func=%r, dtype=%r)" % ( - type(self).__name__, - self.array, - self.func, - self.dtype, + return "{}({!r}, func={!r}, dtype={!r})".format( + type(self).__name__, self.array, self.func, self.dtype ) @@ -113,7 +110,7 @@ def unpack_for_decoding(var): def safe_setitem(dest, key, value, name=None): if key in dest: - var_str = " on variable {!r}".format(name) if name else "" + var_str = f" on variable {name!r}" if name else "" raise ValueError( "failed to prevent overwriting existing key {} in attrs{}. " "This is probably an encoding field used by xarray to describe " diff --git a/xarray/convert.py b/xarray/convert.py index 15d701bce21..4974a55d8e2 100644 --- a/xarray/convert.py +++ b/xarray/convert.py @@ -229,16 +229,14 @@ def _iris_cell_methods_to_str(cell_methods_obj): """ cell_methods = [] for cell_method in cell_methods_obj: - names = "".join(["{}: ".format(n) for n in cell_method.coord_names]) + names = "".join([f"{n}: " for n in cell_method.coord_names]) intervals = " ".join( - ["interval: {}".format(interval) for interval in cell_method.intervals] - ) - comments = " ".join( - ["comment: {}".format(comment) for comment in cell_method.comments] + [f"interval: {interval}" for interval in cell_method.intervals] ) + comments = " ".join([f"comment: {comment}" for comment in cell_method.comments]) extra = " ".join([intervals, comments]).strip() if extra: - extra = " ({})".format(extra) + extra = f" ({extra})" cell_methods.append(names + cell_method.method + extra) return " ".join(cell_methods) @@ -267,11 +265,11 @@ def from_iris(cube): dim_coord = cube.coord(dim_coords=True, dimensions=(i,)) dims.append(_name(dim_coord)) except iris.exceptions.CoordinateNotFoundError: - dims.append("dim_{}".format(i)) + dims.append(f"dim_{i}") if len(set(dims)) != len(dims): duplicates = [k for k, v in Counter(dims).items() if v > 1] - raise ValueError("Duplicate coordinate name {}.".format(duplicates)) + raise ValueError(f"Duplicate coordinate name {duplicates}.") coords = {} diff --git a/xarray/core/alignment.py b/xarray/core/alignment.py index 3e53c642bb1..1a33cb955c3 100644 --- a/xarray/core/alignment.py +++ b/xarray/core/alignment.py @@ -64,7 +64,7 @@ def align( copy=True, indexes=None, exclude=frozenset(), - fill_value=dtypes.NA + fill_value=dtypes.NA, ): """ Given any number of Dataset and/or DataArray objects, returns new @@ -294,9 +294,7 @@ def align( or dim in unlabeled_dim_sizes ): if join == "exact": - raise ValueError( - "indexes along dimension {!r} are not equal".format(dim) - ) + raise ValueError(f"indexes along dimension {dim!r} are not equal") index = joiner(matching_indexes) joined_indexes[dim] = index else: @@ -402,7 +400,7 @@ def is_alignable(obj): copy=copy, indexes=indexes, exclude=exclude, - fill_value=fill_value + fill_value=fill_value, ) for position, key, aligned_obj in zip(positions, keys, aligned): diff --git a/xarray/core/common.py b/xarray/core/common.py index d23428eca62..45d860a1797 100644 --- a/xarray/core/common.py +++ b/xarray/core/common.py @@ -87,7 +87,7 @@ def wrapped_func(self, dim=None, skipna=None, **kwargs): skipna=skipna, numeric_only=numeric_only, allow_lazy=True, - **kwargs + **kwargs, ) else: @@ -167,7 +167,7 @@ def _get_axis_num(self: Any, dim: Hashable) -> int: try: return self.dims.index(dim) except ValueError: - raise ValueError("%r not found in array dimensions %r" % (dim, self.dims)) + raise ValueError(f"{dim!r} not found in array dimensions {self.dims!r}") @property def sizes(self: Any) -> Mapping[Hashable, int]: @@ -225,7 +225,7 @@ def __getattr__(self, name: str) -> Any: with suppress(KeyError): return source[name] raise AttributeError( - "%r object has no attribute %r" % (type(self).__name__, name) + "{!r} object has no attribute {!r}".format(type(self).__name__, name) ) # This complicated two-method design boosts overall performance of simple operations @@ -258,7 +258,9 @@ def __setattr__(self, name: str, value: Any) -> None: except AttributeError as e: # Don't accidentally shadow custom AttributeErrors, e.g. # DataArray.dims.setter - if str(e) != "%r object has no attribute %r" % (type(self).__name__, name): + if str(e) != "{!r} object has no attribute {!r}".format( + type(self).__name__, name + ): raise raise AttributeError( "cannot set attribute %r on a %r object. Use __setitem__ style" @@ -479,7 +481,7 @@ def pipe( self, func: Union[Callable[..., T], Tuple[Callable[..., T], str]], *args, - **kwargs + **kwargs, ) -> T: """ Apply func(self, *args, **kwargs) @@ -735,7 +737,7 @@ def rolling( dim: Mapping[Hashable, int] = None, min_periods: int = None, center: bool = False, - **window_kwargs: int + **window_kwargs: int, ): """ Rolling window object. @@ -799,7 +801,7 @@ def rolling_exp( self, window: Mapping[Hashable, int] = None, window_type: str = "span", - **window_kwargs + **window_kwargs, ): """ Exponentially-weighted moving window. @@ -840,7 +842,7 @@ def coarsen( boundary: str = "exact", side: Union[str, Mapping[Hashable, str]] = "left", coord_func: str = "mean", - **window_kwargs: int + **window_kwargs: int, ): """ Coarsen object. @@ -910,7 +912,7 @@ def resample( keep_attrs: bool = None, loffset=None, restore_coord_dims: bool = None, - **indexer_kwargs: str + **indexer_kwargs: str, ): """Returns a Resample object for performing resampling operations. diff --git a/xarray/core/computation.py b/xarray/core/computation.py index 04dcbb21ff8..1393d76f283 100644 --- a/xarray/core/computation.py +++ b/xarray/core/computation.py @@ -110,16 +110,14 @@ def __ne__(self, other): return not self == other def __repr__(self): - return "%s(%r, %r)" % ( - type(self).__name__, - list(self.input_core_dims), - list(self.output_core_dims), + return "{}({!r}, {!r})".format( + type(self).__name__, list(self.input_core_dims), list(self.output_core_dims) ) def __str__(self): lhs = ",".join("({})".format(",".join(dims)) for dims in self.input_core_dims) rhs = ",".join("({})".format(",".join(dims)) for dims in self.output_core_dims) - return "{}->{}".format(lhs, rhs) + return f"{lhs}->{rhs}" def to_gufunc_string(self): """Create an equivalent signature string for a NumPy gufunc. @@ -355,7 +353,7 @@ def apply_dataset_vfunc( dataset_join="exact", fill_value=_NO_FILL_VALUE, exclude_dims=frozenset(), - keep_attrs=False + keep_attrs=False, ): """Apply a variable level function over Dataset, dict of DataArray, DataArray, Variable and/or ndarray objects. @@ -548,7 +546,7 @@ def apply_variable_ufunc( dask="forbidden", output_dtypes=None, output_sizes=None, - keep_attrs=False + keep_attrs=False, ): """Apply a ndarray level function over Variable and/or ndarray objects. """ @@ -720,7 +718,7 @@ def _apply_blockwise( *blockwise_args, dtype=dtype, concatenate=True, - new_axes=output_sizes + new_axes=output_sizes, ) @@ -743,7 +741,7 @@ def apply_array_ufunc(func, *args, dask="forbidden"): elif dask == "allowed": pass else: - raise ValueError("unknown setting for dask array handling: {}".format(dask)) + raise ValueError(f"unknown setting for dask array handling: {dask}") return func(*args) @@ -761,7 +759,7 @@ def apply_ufunc( kwargs: Mapping = None, dask: str = "forbidden", output_dtypes: Sequence = None, - output_sizes: Mapping[Any, int] = None + output_sizes: Mapping[Any, int] = None, ) -> Any: """Apply a vectorized function for unlabeled arrays on xarray objects. @@ -1032,7 +1030,7 @@ def earth_mover_distance(first_samples, exclude_dims=exclude_dims, dataset_join=dataset_join, fill_value=dataset_fill_value, - keep_attrs=keep_attrs + keep_attrs=keep_attrs, ) elif any(isinstance(a, DataArray) for a in args): return apply_dataarray_vfunc( @@ -1041,7 +1039,7 @@ def earth_mover_distance(first_samples, signature=signature, join=join, exclude_dims=exclude_dims, - keep_attrs=keep_attrs + keep_attrs=keep_attrs, ) elif any(isinstance(a, Variable) for a in args): return variables_vfunc(*args) @@ -1175,7 +1173,7 @@ def dot(*arrays, dims=None, **kwargs): *arrays, input_core_dims=input_core_dims, output_core_dims=output_core_dims, - dask="allowed" + dask="allowed", ) return result.transpose(*[d for d in all_dims if d in result.dims]) diff --git a/xarray/core/concat.py b/xarray/core/concat.py index e98e8a72125..bcab136de8d 100644 --- a/xarray/core/concat.py +++ b/xarray/core/concat.py @@ -217,7 +217,7 @@ def process_subset_opt(opt, subset): elif opt == "minimal": pass else: - raise ValueError("unexpected value for %s: %s" % (subset, opt)) + raise ValueError(f"unexpected value for {subset}: {opt}") else: invalid_vars = [k for k in opt if k not in getattr(datasets[0], subset)] if invalid_vars: diff --git a/xarray/core/dataarray.py b/xarray/core/dataarray.py index 4a48f13b86d..5fccb9236e8 100644 --- a/xarray/core/dataarray.py +++ b/xarray/core/dataarray.py @@ -504,7 +504,7 @@ def to_dataset(self, dim: Hashable = None, *, name: Hashable = None) -> Dataset: """ if dim is not None and dim not in self.dims: raise TypeError( - "{} is not a dim. If supplying a ``name``, pass as a kwarg.".format(dim) + f"{dim} is not a dim. If supplying a ``name``, pass as a kwarg." ) if dim is not None: @@ -996,7 +996,7 @@ def isel( self, indexers: Mapping[Hashable, Any] = None, drop: bool = False, - **indexers_kwargs: Any + **indexers_kwargs: Any, ) -> "DataArray": """Return a new DataArray whose data is given by integer indexing along the specified dimension(s). @@ -1016,7 +1016,7 @@ def sel( method: str = None, tolerance=None, drop: bool = False, - **indexers_kwargs: Any + **indexers_kwargs: Any, ) -> "DataArray": """Return a new DataArray whose data is given by selecting index labels along the specified dimension(s). @@ -1044,14 +1044,14 @@ def sel( drop=drop, method=method, tolerance=tolerance, - **indexers_kwargs + **indexers_kwargs, ) return self._from_temp_dataset(ds) def head( self, indexers: Union[Mapping[Hashable, int], int] = None, - **indexers_kwargs: Any + **indexers_kwargs: Any, ) -> "DataArray": """Return a new DataArray whose data is given by the the first `n` values along the specified dimension(s). Default `n` = 5 @@ -1068,7 +1068,7 @@ def head( def tail( self, indexers: Union[Mapping[Hashable, int], int] = None, - **indexers_kwargs: Any + **indexers_kwargs: Any, ) -> "DataArray": """Return a new DataArray whose data is given by the the last `n` values along the specified dimension(s). Default `n` = 5 @@ -1085,7 +1085,7 @@ def tail( def thin( self, indexers: Union[Mapping[Hashable, int], int] = None, - **indexers_kwargs: Any + **indexers_kwargs: Any, ) -> "DataArray": """Return a new DataArray whose data is given by each `n` value along the specified dimension(s). Default `n` = 5 @@ -1230,7 +1230,7 @@ def reindex( tolerance=None, copy: bool = True, fill_value=dtypes.NA, - **indexers_kwargs: Any + **indexers_kwargs: Any, ) -> "DataArray": """Conform this object onto the indexes of another object, filling in missing values with ``fill_value``. The default fill value is NaN. @@ -1293,7 +1293,7 @@ def interp( method: str = "linear", assume_sorted: bool = False, kwargs: Mapping[str, Any] = None, - **coords_kwargs: Any + **coords_kwargs: Any, ) -> "DataArray": """ Multidimensional interpolation of variables. @@ -1348,7 +1348,7 @@ def interp( method=method, kwargs=kwargs, assume_sorted=assume_sorted, - **coords_kwargs + **coords_kwargs, ) return self._from_temp_dataset(ds) @@ -1410,7 +1410,7 @@ def interp_like( def rename( self, new_name_or_name_dict: Union[Hashable, Mapping[Hashable, Hashable]] = None, - **names: Hashable + **names: Hashable, ) -> "DataArray": """Returns a new DataArray with renamed coordinates or a new name. @@ -1491,7 +1491,7 @@ def expand_dims( self, dim: Union[None, Hashable, Sequence[Hashable], Mapping[Hashable, Any]] = None, axis=None, - **dim_kwargs: Any + **dim_kwargs: Any, ) -> "DataArray": """Return a new object with an additional axis (or axes) inserted at the corresponding position in the array shape. The new object is a @@ -1545,7 +1545,7 @@ def set_index( indexes: Mapping[Hashable, Union[Hashable, Sequence[Hashable]]] = None, append: bool = False, inplace: bool = None, - **indexes_kwargs: Union[Hashable, Sequence[Hashable]] + **indexes_kwargs: Union[Hashable, Sequence[Hashable]], ) -> Optional["DataArray"]: """Set DataArray (multi-)indexes using one or more existing coordinates. @@ -1638,7 +1638,7 @@ def reorder_levels( self, dim_order: Mapping[Hashable, Sequence[int]] = None, inplace: bool = None, - **dim_order_kwargs: Sequence[int] + **dim_order_kwargs: Sequence[int], ) -> "DataArray": """Rearrange index levels using input order. @@ -1674,7 +1674,7 @@ def reorder_levels( def stack( self, dimensions: Mapping[Hashable, Sequence[Hashable]] = None, - **dimensions_kwargs: Sequence[Hashable] + **dimensions_kwargs: Sequence[Hashable], ) -> "DataArray": """ Stack any number of existing dimensions into a single new dimension. @@ -1821,7 +1821,7 @@ def to_unstacked_dataset(self, dim, level=0): idx = self.indexes[dim] if not isinstance(idx, pd.MultiIndex): - raise ValueError("'{}' is not a stacked coordinate".format(dim)) + raise ValueError(f"'{dim}' is not a stacked coordinate") level_number = idx._get_level_number(level) variables = idx.levels[level_number] @@ -1986,7 +1986,7 @@ def interpolate_na( method: str = "linear", limit: int = None, use_coordinate: Union[bool, str] = True, - **kwargs: Any + **kwargs: Any, ) -> "DataArray": """Interpolate values according to different methods. @@ -2034,7 +2034,7 @@ def interpolate_na( method=method, limit=limit, use_coordinate=use_coordinate, - **kwargs + **kwargs, ) def ffill(self, dim: Hashable, limit: int = None) -> "DataArray": @@ -2110,7 +2110,7 @@ def reduce( axis: Union[None, int, Sequence[int]] = None, keep_attrs: bool = None, keepdims: bool = False, - **kwargs: Any + **kwargs: Any, ) -> "DataArray": """Reduce this array by applying `func` along some dimension(s). @@ -2492,7 +2492,7 @@ def _binary_op( f: Callable[..., Any], reflexive: bool = False, join: str = None, # see xarray.align - **ignored_kwargs + **ignored_kwargs, ) -> Callable[..., "DataArray"]: @functools.wraps(f) def func(self, other): @@ -2633,7 +2633,7 @@ def shift( self, shifts: Mapping[Hashable, int] = None, fill_value: Any = dtypes.NA, - **shifts_kwargs: int + **shifts_kwargs: int, ) -> "DataArray": """Shift this array by an offset along one or more dimensions. @@ -2682,7 +2682,7 @@ def roll( self, shifts: Mapping[Hashable, int] = None, roll_coords: bool = None, - **shifts_kwargs: int + **shifts_kwargs: int, ) -> "DataArray": """Roll this array by an offset along one or more dimensions. diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index 6123b42b77e..3fdde8fa4e3 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -1639,18 +1639,16 @@ def info(self, buf=None) -> None: lines.append("xarray.Dataset {") lines.append("dimensions:") for name, size in self.dims.items(): - lines.append("\t{name} = {size} ;".format(name=name, size=size)) + lines.append(f"\t{name} = {size} ;") lines.append("\nvariables:") for name, da in self.variables.items(): dims = ", ".join(da.dims) - lines.append( - "\t{type} {name}({dims}) ;".format(type=da.dtype, name=name, dims=dims) - ) + lines.append(f"\t{da.dtype} {name}({dims}) ;") for k, v in da.attrs.items(): - lines.append("\t\t{name}:{k} = {v} ;".format(name=name, k=k, v=v)) + lines.append(f"\t\t{name}:{k} = {v} ;") lines.append("\n// global attributes:") for k, v in self.attrs.items(): - lines.append("\t:{k} = {v} ;".format(k=k, v=v)) + lines.append(f"\t:{k} = {v} ;") lines.append("}") buf.write("\n".join(lines)) @@ -1732,7 +1730,7 @@ def maybe_chunk(name, var, chunks): chunks = None if var.ndim > 0: token2 = tokenize(name, token if token else var._data) - name2 = "%s%s-%s" % (name_prefix, name, token2) + name2 = f"{name_prefix}{name}-{token2}" return var.chunk(chunks, name=name2, lock=lock) else: return var @@ -2624,7 +2622,7 @@ def _rename_vars(self, name_dict, dims_dict): var.dims = tuple(dims_dict.get(dim, dim) for dim in v.dims) name = name_dict.get(k, k) if name in variables: - raise ValueError("the new name %r conflicts" % (name,)) + raise ValueError(f"the new name {name!r} conflicts") variables[name] = var if k in self._coord_names: coord_names.add(name) @@ -2932,7 +2930,7 @@ def expand_dims( raise ValueError("lengths of dim and axis should be identical.") for d in dim: if d in self.dims: - raise ValueError("Dimension {dim} already exists.".format(dim=d)) + raise ValueError(f"Dimension {d} already exists.") if d in self._variables and not utils.is_scalar(self._variables[d]): raise ValueError( "{dim} already exists as coordinate or" @@ -4722,7 +4720,7 @@ def diff(self, dim, n=1, label="upper"): if n == 0: return self if n < 0: - raise ValueError("order `n` must be non-negative but got {}".format(n)) + raise ValueError(f"order `n` must be non-negative but got {n}") # prepare slices kwargs_start = {dim: slice(None, -1)} @@ -5125,7 +5123,7 @@ def differentiate(self, coord, edge_order=1, datetime_unit=None): from .variable import Variable if coord not in self.variables and coord not in self.dims: - raise ValueError("Coordinate {} does not exist.".format(coord)) + raise ValueError(f"Coordinate {coord} does not exist.") coord_var = self[coord].variable if coord_var.ndim != 1: @@ -5191,7 +5189,7 @@ def _integrate_one(self, coord, datetime_unit=None): from .variable import Variable if coord not in self.variables and coord not in self.dims: - raise ValueError("Coordinate {} does not exist.".format(coord)) + raise ValueError(f"Coordinate {coord} does not exist.") coord_var = self[coord].variable if coord_var.ndim != 1: diff --git a/xarray/core/duck_array_ops.py b/xarray/core/duck_array_ops.py index 126168d418b..d943788c434 100644 --- a/xarray/core/duck_array_ops.py +++ b/xarray/core/duck_array_ops.py @@ -41,7 +41,7 @@ def f(*args, **kwargs): try: wrapped = getattr(dask_module, name) except AttributeError as e: - raise AttributeError("%s: requires dask >=%s" % (e, requires_dask)) + raise AttributeError(f"{e}: requires dask >={requires_dask}") else: wrapped = getattr(eager_module, name) return wrapped(*args, **kwargs) @@ -257,7 +257,7 @@ def _create_nan_agg_method(name, coerce_strings=False): def f(values, axis=None, skipna=None, **kwargs): if kwargs.pop("out", None) is not None: - raise TypeError("`out` is not valid for {}".format(name)) + raise TypeError(f"`out` is not valid for {name}") values = asarray(values) diff --git a/xarray/core/formatting.py b/xarray/core/formatting.py index 0c7f073819d..520fa9b9f1b 100644 --- a/xarray/core/formatting.py +++ b/xarray/core/formatting.py @@ -111,7 +111,7 @@ def format_timestamp(t): if time_str == "00:00:00": return date_str else: - return "{}T{}".format(date_str, time_str) + return f"{date_str}T{time_str}" def format_timedelta(t, timedelta_format=None): @@ -140,7 +140,7 @@ def format_item(x, timedelta_format=None, quote_strings=True): elif isinstance(x, (str, bytes)): return repr(x) if quote_strings else x elif isinstance(x, (float, np.float)): - return "{:.4}".format(x) + return f"{x:.4}" else: return str(x) @@ -228,11 +228,11 @@ def inline_dask_repr(array): meta_repr = _KNOWN_TYPE_REPRS[type(meta)] else: meta_repr = type(meta).__name__ - meta_string = ", meta={}".format(meta_repr) + meta_string = f", meta={meta_repr}" else: meta_string = "" - return "dask.array".format(chunksize, meta_string) + return f"dask.array" def inline_sparse_repr(array): @@ -262,12 +262,12 @@ def summarize_variable(name, var, col_width, marker=" ", max_width=None): """Summarize a variable in one line, e.g., for the Dataset.__repr__.""" if max_width is None: max_width = OPTIONS["display_width"] - first_col = pretty_print(" {} {} ".format(marker, name), col_width) + first_col = pretty_print(f" {marker} {name} ", col_width) if var.dims: dims_str = "({}) ".format(", ".join(map(str, var.dims))) else: dims_str = "" - front_str = "{}{}{} ".format(first_col, dims_str, var.dtype) + front_str = f"{first_col}{dims_str}{var.dtype} " values_width = max_width - len(front_str) values_str = inline_variable_array_repr(var, values_width) @@ -276,7 +276,7 @@ def summarize_variable(name, var, col_width, marker=" ", max_width=None): def _summarize_coord_multiindex(coord, col_width, marker): - first_col = pretty_print(" {} {} ".format(marker, coord.name), col_width) + first_col = pretty_print(f" {marker} {coord.name} ", col_width) return "{}({}) MultiIndex".format(first_col, str(coord.dims[0])) @@ -313,13 +313,13 @@ def summarize_coord(name, var, col_width): def summarize_attr(key, value, col_width=None): """Summary for __repr__ - use ``X.attrs[key]`` for full value.""" # Indent key and add ':', then right-pad if col_width is not None - k_str = " {}:".format(key) + k_str = f" {key}:" if col_width is not None: k_str = pretty_print(k_str, col_width) # Replace tabs and newlines, so we print on one line in known width v_str = str(value).replace("\t", "\\t").replace("\n", "\\n") # Finally, truncate to the desired display width - return maybe_truncate("{} {}".format(k_str, v_str), OPTIONS["display_width"]) + return maybe_truncate(f"{k_str} {v_str}", OPTIONS["display_width"]) EMPTY_REPR = " *empty*" @@ -351,7 +351,7 @@ def _calculate_col_width(col_items): def _mapping_repr(mapping, title, summarizer, col_width=None): if col_width is None: col_width = _calculate_col_width(mapping) - summary = ["{}:".format(title)] + summary = [f"{title}:"] if mapping: summary += [summarizer(k, v, col_width) for k, v in mapping.items()] else: @@ -380,19 +380,19 @@ def coords_repr(coords, col_width=None): def indexes_repr(indexes): summary = [] for k, v in indexes.items(): - summary.append(wrap_indent(repr(v), "{}: ".format(k))) + summary.append(wrap_indent(repr(v), f"{k}: ")) return "\n".join(summary) def dim_summary(obj): - elements = ["{}: {}".format(k, v) for k, v in obj.sizes.items()] + elements = [f"{k}: {v}" for k, v in obj.sizes.items()] return ", ".join(elements) def unindexed_dims_repr(dims, coords): unindexed_dims = [d for d in dims if d not in coords] if unindexed_dims: - dims_str = ", ".join("{}".format(d) for d in unindexed_dims) + dims_str = ", ".join(f"{d}" for d in unindexed_dims) return "Dimensions without coordinates: " + dims_str else: return None @@ -438,13 +438,13 @@ def short_data_repr(array): return short_numpy_repr(array) else: # internal xarray array type - return "[{} values with dtype={}]".format(array.size, array.dtype) + return f"[{array.size} values with dtype={array.dtype}]" def array_repr(arr): # used for DataArray, Variable and IndexVariable if hasattr(arr, "name") and arr.name is not None: - name_str = "{!r} ".format(arr.name) + name_str = f"{arr.name!r} " else: name_str = "" @@ -503,7 +503,7 @@ def _diff_mapping_repr(a_mapping, b_mapping, compat, title, summarizer, col_widt 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) + header = f"{title} only on the {ab_side} object:" return [header] + extra_repr else: return [] diff --git a/xarray/core/groupby.py b/xarray/core/groupby.py index 43724e3c644..52eb17df18d 100644 --- a/xarray/core/groupby.py +++ b/xarray/core/groupby.py @@ -298,7 +298,7 @@ def __init__( ) group = obj[group] if len(group) == 0: - raise ValueError("{} must not be empty".format(group.name)) + raise ValueError(f"{group.name} must not be empty") if group.name not in obj.coords and group.name in obj.dims: # DummyGroups should not appear on groupby results @@ -417,7 +417,7 @@ def __iter__(self): return zip(self._unique_coord.values, self._iter_grouped()) def __repr__(self): - return "%s, grouped over %r \n%r groups with labels %s." % ( + return "{}, grouped over {!r} \n{!r} groups with labels {}.".format( self.__class__.__name__, self._unique_coord.name, self._unique_coord.size, diff --git a/xarray/core/indexing.py b/xarray/core/indexing.py index 010c4818ca5..3d2e634eaa8 100644 --- a/xarray/core/indexing.py +++ b/xarray/core/indexing.py @@ -156,7 +156,7 @@ def convert_label_indexer(index, label, index_name="", method=None, tolerance=No # GH2619. Raise a KeyError if nothing is chosen if indexer.dtype.kind == "b" and indexer.sum() == 0: - raise KeyError("{} not found".format(label)) + raise KeyError(f"{label} not found") elif isinstance(label, tuple) and isinstance(index, pd.MultiIndex): if _is_nested_tuple(label): @@ -352,7 +352,7 @@ class BasicIndexer(ExplicitIndexer): def __init__(self, key): if not isinstance(key, tuple): - raise TypeError("key must be a tuple: {!r}".format(key)) + raise TypeError(f"key must be a tuple: {key!r}") new_key = [] for k in key: @@ -384,7 +384,7 @@ class OuterIndexer(ExplicitIndexer): def __init__(self, key): if not isinstance(key, tuple): - raise TypeError("key must be a tuple: {!r}".format(key)) + raise TypeError(f"key must be a tuple: {key!r}") new_key = [] for k in key: @@ -429,7 +429,7 @@ class VectorizedIndexer(ExplicitIndexer): def __init__(self, key): if not isinstance(key, tuple): - raise TypeError("key must be a tuple: {!r}".format(key)) + raise TypeError(f"key must be a tuple: {key!r}") new_key = [] ndim = None @@ -574,7 +574,9 @@ def __setitem__(self, key, value): self.array[full_key] = value def __repr__(self): - return "%s(array=%r, key=%r)" % (type(self).__name__, self.array, self.key) + return "{}(array={!r}, key={!r})".format( + type(self).__name__, self.array, self.key + ) class LazilyVectorizedIndexedArray(ExplicitlyIndexedNDArrayMixin): @@ -625,7 +627,9 @@ def __setitem__(self, key, value): ) def __repr__(self): - return "%s(array=%r, key=%r)" % (type(self).__name__, self.array, self.key) + return "{}(array={!r}, key={!r})".format( + type(self).__name__, self.array, self.key + ) def _wrap_numpy_scalars(array): @@ -847,7 +851,7 @@ def decompose_indexer( return _decompose_vectorized_indexer(indexer, shape, indexing_support) if isinstance(indexer, (BasicIndexer, OuterIndexer)): return _decompose_outer_indexer(indexer, shape, indexing_support) - raise TypeError("unexpected key type: {}".format(indexer)) + raise TypeError(f"unexpected key type: {indexer}") def _decompose_slice(key, size): @@ -1413,7 +1417,9 @@ def transpose(self, order) -> pd.Index: return self.array # self.array should be always one-dimensional def __repr__(self) -> str: - return "%s(array=%r, dtype=%r)" % (type(self).__name__, self.array, self.dtype) + return "{}(array={!r}, dtype={!r})".format( + type(self).__name__, self.array, self.dtype + ) def copy(self, deep: bool = True) -> "PandasIndexAdapter": # Not the same as just writing `self.array.copy(deep=deep)`, as diff --git a/xarray/core/merge.py b/xarray/core/merge.py index 012898ac18b..db5ef9531df 100644 --- a/xarray/core/merge.py +++ b/xarray/core/merge.py @@ -144,7 +144,9 @@ def unique_variable( def _assert_compat_valid(compat): if compat not in _VALID_COMPAT: - raise ValueError("compat=%r invalid: must be %s" % (compat, set(_VALID_COMPAT))) + raise ValueError( + "compat={!r} invalid: must be {}".format(compat, set(_VALID_COMPAT)) + ) MergeElement = Tuple[Variable, Optional[pd.Index]] diff --git a/xarray/core/nputils.py b/xarray/core/nputils.py index df36c98f94c..3fe2c254b0f 100644 --- a/xarray/core/nputils.py +++ b/xarray/core/nputils.py @@ -16,7 +16,7 @@ def _validate_axis(data, axis): ndim = data.ndim if not -ndim <= axis < ndim: - raise IndexError("axis %r out of bounds [-%r, %r)" % (axis, ndim, ndim)) + raise IndexError(f"axis {axis!r} out of bounds [-{ndim}, {ndim})") if axis < 0: axis += ndim return axis @@ -190,9 +190,9 @@ def _rolling_window(a, window, axis=-1): a = np.swapaxes(a, axis, -1) if window < 1: - raise ValueError("`window` must be at least 1. Given : {}".format(window)) + raise ValueError(f"`window` must be at least 1. Given : {window}") if window > a.shape[-1]: - raise ValueError("`window` is too long. Given : {}".format(window)) + raise ValueError(f"`window` is too long. Given : {window}") shape = a.shape[:-1] + (a.shape[-1] - window + 1, window) strides = a.strides + (a.strides[-1],) diff --git a/xarray/core/options.py b/xarray/core/options.py index c5086268f48..2f464a33fb1 100644 --- a/xarray/core/options.py +++ b/xarray/core/options.py @@ -125,7 +125,7 @@ def __init__(self, **kwargs): % (k, set(OPTIONS)) ) if k in _VALIDATORS and not _VALIDATORS[k](v): - raise ValueError("option %r given an invalid value: %r" % (k, v)) + raise ValueError(f"option {k!r} given an invalid value: {v!r}") self.old[k] = OPTIONS[k] self._apply_update(kwargs) diff --git a/xarray/core/parallel.py b/xarray/core/parallel.py index 48bb9ccfc3d..fbb5ef94ca2 100644 --- a/xarray/core/parallel.py +++ b/xarray/core/parallel.py @@ -222,9 +222,8 @@ def _wrapper(func, obj, to_array, args, kwargs): indexes.update({k: template.indexes[k] for k in new_indexes}) graph: Dict[Any, Any] = {} - gname = "%s-%s" % ( - dask.utils.funcname(func), - dask.base.tokenize(dataset, args, kwargs), + gname = "{}-{}".format( + dask.utils.funcname(func), dask.base.tokenize(dataset, args, kwargs) ) # map dims to list of chunk indexes @@ -253,7 +252,7 @@ def _wrapper(func, obj, to_array, args, kwargs): for dim in variable.dims: chunk = chunk[chunk_index_dict[dim]] - chunk_variable_task = ("%s-%s" % (gname, chunk[0]),) + v + chunk_variable_task = (f"{gname}-{chunk[0]}",) + v graph[chunk_variable_task] = ( tuple, [variable.dims, chunk, variable.attrs], @@ -272,7 +271,7 @@ def _wrapper(func, obj, to_array, args, kwargs): subset = variable.isel(subsetter) chunk_variable_task = ( - "%s-%s" % (gname, dask.base.tokenize(subset)), + "{}-{}".format(gname, dask.base.tokenize(subset)), ) + v graph[chunk_variable_task] = ( tuple, @@ -300,7 +299,7 @@ def _wrapper(func, obj, to_array, args, kwargs): for name, variable in template.variables.items(): if name in indexes: continue - gname_l = "%s-%s" % (gname, name) + gname_l = f"{gname}-{name}" var_key_map[name] = gname_l key: Tuple[Any, ...] = (gname_l,) diff --git a/xarray/core/utils.py b/xarray/core/utils.py index c9c5866654d..6befe0b5efc 100644 --- a/xarray/core/utils.py +++ b/xarray/core/utils.py @@ -42,7 +42,7 @@ def _check_inplace(inplace: Optional[bool]) -> None: def alias_message(old_name: str, new_name: str) -> str: - return "%s has been deprecated. Use %s instead." % (old_name, new_name) + return f"{old_name} has been deprecated. Use {new_name} instead." def alias_warning(old_name: str, new_name: str, stacklevel: int = 3) -> None: @@ -393,7 +393,7 @@ def __contains__(self, key: object) -> bool: return key in self.mapping def __repr__(self) -> str: - return "%s(%r)" % (type(self).__name__, self.mapping) + return "{}({!r})".format(type(self).__name__, self.mapping) def FrozenDict(*args, **kwargs) -> Frozen: @@ -430,7 +430,7 @@ def __contains__(self, key: object) -> bool: return key in self.mapping def __repr__(self) -> str: - return "%s(%r)" % (type(self).__name__, self.mapping) + return "{}({!r})".format(type(self).__name__, self.mapping) class OrderedSet(MutableSet[T]): @@ -476,7 +476,7 @@ def update(self, values: AbstractSet[T]) -> None: self |= values # type: ignore def __repr__(self) -> str: - return "%s(%r)" % (type(self).__name__, list(self)) + return "{}({!r})".format(type(self).__name__, list(self)) class NdimSizeLenMixin: @@ -524,7 +524,7 @@ def __getitem__(self: Any, key): return self.array[key] def __repr__(self: Any) -> str: - return "%s(array=%r)" % (type(self).__name__, self.array) + return "{}(array={!r})".format(type(self).__name__, self.array) class ReprObject: diff --git a/xarray/core/variable.py b/xarray/core/variable.py index b17597df580..37672cd82d9 100644 --- a/xarray/core/variable.py +++ b/xarray/core/variable.py @@ -113,7 +113,7 @@ def as_variable(obj, name=None) -> "Union[Variable, IndexVariable]": elif isinstance(obj, (pd.Index, IndexVariable)) and obj.name is not None: obj = Variable(obj.name, obj) elif isinstance(obj, (set, dict)): - raise TypeError("variable %r has invalid type %r" % (name, type(obj))) + raise TypeError("variable {!r} has invalid type {!r}".format(name, type(obj))) elif name is not None: data = as_compatible_data(obj) if data.ndim != 1: @@ -658,7 +658,7 @@ def _broadcast_indexes_vectorized(self, key): try: variables = _broadcast_compat_variables(*variables) except ValueError: - raise IndexError("Dimensions of indexers mismatch: {}".format(key)) + raise IndexError(f"Dimensions of indexers mismatch: {key}") out_key = [variable.data for variable in variables] out_dims = tuple(out_dims_set) @@ -972,7 +972,7 @@ def chunk(self, chunks=None, name=None, lock=False): def isel( self: VariableType, indexers: Mapping[Hashable, Any] = None, - **indexers_kwargs: Any + **indexers_kwargs: Any, ) -> VariableType: """Return a new array indexed along the specified dimension(s). @@ -1417,7 +1417,7 @@ def reduce( keep_attrs=None, keepdims=False, allow_lazy=False, - **kwargs + **kwargs, ): """Reduce this array by applying `func` along some dimension(s). @@ -1803,7 +1803,7 @@ def coarsen(self, windows, func, boundary="exact", side="left"): name = func func = getattr(duck_array_ops, name, None) if func is None: - raise NameError("{} is not a valid method.".format(name)) + raise NameError(f"{name} is not a valid method.") return type(self)(self.dims, func(reshaped, axis=axes), self._attrs) def _coarsen_reshape(self, windows, boundary, side): @@ -1822,7 +1822,7 @@ def _coarsen_reshape(self, windows, boundary, side): for d, window in windows.items(): if window <= 0: - raise ValueError("window must be > 0. Given {}".format(window)) + raise ValueError(f"window must be > 0. Given {window}") variable = self for d, window in windows.items(): @@ -2246,7 +2246,7 @@ def assert_unique_multiindex_level_names(variables): idx_level_names = var.to_index_variable().level_names if idx_level_names is not None: for n in idx_level_names: - level_names[n].append("%r (%s)" % (n, var_name)) + level_names[n].append(f"{n!r} ({var_name})") if idx_level_names: all_level_names.update(idx_level_names) diff --git a/xarray/plot/dataset_plot.py b/xarray/plot/dataset_plot.py index 176f0c504f6..ea037c1a2c2 100644 --- a/xarray/plot/dataset_plot.py +++ b/xarray/plot/dataset_plot.py @@ -19,7 +19,7 @@ def _infer_meta_data(ds, x, y, hue, hue_style, add_guide): dvars = set(ds.variables.keys()) - error_msg = " must be one of ({0:s})".format(", ".join(dvars)) + error_msg = " must be one of ({:s})".format(", ".join(dvars)) if x not in dvars: raise ValueError("x" + error_msg) @@ -148,7 +148,7 @@ def _parse_size(data, norm): return pd.Series(sizes) -class _Dataset_PlotMethods(object): +class _Dataset_PlotMethods: """ Enables use of xarray.plot functions as attributes on a Dataset. For example, Dataset.plot.scatter @@ -243,7 +243,7 @@ def _dsplot(plotfunc): """ # Build on the original docstring - plotfunc.__doc__ = "%s\n%s" % (plotfunc.__doc__, commondoc) + plotfunc.__doc__ = f"{plotfunc.__doc__}\n{commondoc}" @functools.wraps(plotfunc) def newplotfunc( @@ -275,7 +275,7 @@ def newplotfunc( colors=None, extend=None, cmap=None, - **kwargs + **kwargs, ): _is_facetgrid = kwargs.pop("_is_facetgrid", False) @@ -310,9 +310,9 @@ def newplotfunc( ) # subset that can be passed to scatter, hist2d - cmap_params_subset = dict( - (vv, cmap_params[vv]) for vv in ["vmin", "vmax", "norm", "cmap"] - ) + cmap_params_subset = { + vv: cmap_params[vv] for vv in ["vmin", "vmax", "norm", "cmap"] + } else: cmap_params_subset = {} @@ -325,7 +325,7 @@ def newplotfunc( hue_style=hue_style, ax=ax, cmap_params=cmap_params_subset, - **kwargs + **kwargs, ) if _is_facetgrid: # if this was called from Facetgrid.map_dataset, @@ -380,7 +380,7 @@ def plotmethod( colors=None, extend=None, cmap=None, - **kwargs + **kwargs, ): """ The method should have the same signature as the function. @@ -436,7 +436,7 @@ def scatter(ds, x, y, ax, **kwargs): data["x"].where(mask, drop=True).values.flatten(), data["y"].where(mask, drop=True).values.flatten(), label=label, - **kwargs + **kwargs, ) ) diff --git a/xarray/plot/plot.py b/xarray/plot/plot.py index 7938f9b027b..a288f195e32 100644 --- a/xarray/plot/plot.py +++ b/xarray/plot/plot.py @@ -124,7 +124,7 @@ def plot( hue=None, rtol=0.01, subplot_kws=None, - **kwargs + **kwargs, ): """ Default plot of DataArray using matplotlib.pyplot. @@ -226,7 +226,7 @@ def line( ylim=None, add_legend=True, _labels=True, - **kwargs + **kwargs, ): """ Line plot of DataArray index against values @@ -404,7 +404,7 @@ def hist( yticks=None, xlim=None, ylim=None, - **kwargs + **kwargs, ): """ Histogram of DataArray @@ -584,7 +584,7 @@ def _plot2d(plotfunc): """ # Build on the original docstring - plotfunc.__doc__ = "%s\n%s" % (plotfunc.__doc__, commondoc) + plotfunc.__doc__ = f"{plotfunc.__doc__}\n{commondoc}" @functools.wraps(plotfunc) def newplotfunc( @@ -621,7 +621,7 @@ def newplotfunc( xlim=None, ylim=None, norm=None, - **kwargs + **kwargs, ): # All 2d plots in xarray share this function signature. # Method signature below should be consistent. @@ -734,7 +734,7 @@ def newplotfunc( vmin=cmap_params["vmin"], vmax=cmap_params["vmax"], norm=cmap_params["norm"], - **kwargs + **kwargs, ) # Label the plot with metadata @@ -808,7 +808,7 @@ def plotmethod( xlim=None, ylim=None, norm=None, - **kwargs + **kwargs, ): """ The method should have the same signature as the function. diff --git a/xarray/plot/utils.py b/xarray/plot/utils.py index e070ea16855..3b739197fea 100644 --- a/xarray/plot/utils.py +++ b/xarray/plot/utils.py @@ -302,7 +302,7 @@ def _infer_xy_labels_3d(darray, x, y, rgb): ) for label in not_none: if label not in darray.dims: - raise ValueError("%r is not a dimension" % (label,)) + raise ValueError(f"{label!r} is not a dimension") # Then calculate rgb dimension if certain and check validity could_be_color = [ @@ -693,7 +693,7 @@ def _process_cmap_cbar_kwargs( colors=None, cbar_kwargs: Union[Iterable[Tuple[str, Any]], Mapping[str, Any]] = None, levels=None, - **kwargs + **kwargs, ): """ Parameters diff --git a/xarray/testing.py b/xarray/testing.py index eeff4d932b4..5c3ca8a3cca 100644 --- a/xarray/testing.py +++ b/xarray/testing.py @@ -120,7 +120,7 @@ def assert_allclose(a, b, rtol=1e-05, atol=1e-08, decode_bytes=True): if isinstance(a, Variable): assert a.dims == b.dims allclose = _data_allclose_or_equiv(a.values, b.values, **kwargs) - assert allclose, "{}\n{}".format(a.values, b.values) + assert allclose, f"{a.values}\n{b.values}" elif isinstance(a, DataArray): assert_allclose(a.variable, b.variable, **kwargs) assert set(a.coords) == set(b.coords) diff --git a/xarray/tests/__init__.py b/xarray/tests/__init__.py index acf8b67effa..88476e5e730 100644 --- a/xarray/tests/__init__.py +++ b/xarray/tests/__init__.py @@ -44,7 +44,7 @@ def _importorskip(modname, minversion=None): raise ImportError("Minimum version not satisfied") except ImportError: has = False - func = pytest.mark.skipif(not has, reason="requires {}".format(modname)) + func = pytest.mark.skipif(not has, reason=f"requires {modname}") return has, func @@ -109,7 +109,7 @@ def raises_regex(error, pattern): message = str(excinfo.value) if not re.search(pattern, message): raise AssertionError( - "exception %r did not match pattern %r" % (excinfo.value, pattern) + f"exception {excinfo.value!r} did not match pattern {pattern!r}" ) diff --git a/xarray/tests/test_accessor_str.py b/xarray/tests/test_accessor_str.py index 5cd815eebf0..a987d302202 100644 --- a/xarray/tests/test_accessor_str.py +++ b/xarray/tests/test_accessor_str.py @@ -503,7 +503,7 @@ def test_slice(dtype): expected = xr.DataArray([s[start:stop:step] for s in arr.values]) assert_equal(result, expected.astype(dtype)) except IndexError: - print("failed on %s:%s:%s" % (start, stop, step)) + print(f"failed on {start}:{stop}:{step}") raise diff --git a/xarray/tests/test_backends.py b/xarray/tests/test_backends.py index b5421a6bc9f..4bdebe73050 100644 --- a/xarray/tests/test_backends.py +++ b/xarray/tests/test_backends.py @@ -92,7 +92,7 @@ def open_example_mfdataset(names, *args, **kwargs): return open_mfdataset( [os.path.join(os.path.dirname(__file__), "data", name) for name in names], *args, - **kwargs + **kwargs, ) @@ -986,7 +986,7 @@ def test_multiindex_not_implemented(self): @contextlib.contextmanager def create_tmp_file(suffix=".nc", allow_cleanup_failure=False): temp_dir = tempfile.mkdtemp() - path = os.path.join(temp_dir, "temp-%s%s" % (next(_counter), suffix)) + path = os.path.join(temp_dir, "temp-{}{}".format(next(_counter), suffix)) try: yield path finally: @@ -2490,7 +2490,7 @@ def test_open_mfdataset_list_attr(): f.createDimension("x", 3) vlvar = f.createVariable("test_var", np.int32, ("x")) # here create an attribute as a list - vlvar.test_attr = ["string a {}".format(i), "string b {}".format(i)] + vlvar.test_attr = [f"string a {i}", f"string b {i}"] vlvar[:] = np.arange(3) f.close() ds1 = open_dataset(nfiles[0]) @@ -3534,7 +3534,7 @@ def create_tmp_geotiff( crs=crs, transform=transform, dtype=rasterio.float32, - **open_kwargs + **open_kwargs, ) as s: for attr, val in additional_attrs.items(): setattr(s, attr, val) @@ -4276,7 +4276,7 @@ def test_use_cftime_standard_calendar_default_out_of_range(calendar, units_year) x = [0, 1] time = [0, 720] - units = "days since {}-01-01".format(units_year) + units = f"days since {units_year}-01-01" original = DataArray(x, [("time", time)], name="x") original = original.to_dataset() for v in ["x", "time"]: @@ -4307,7 +4307,7 @@ def test_use_cftime_true(calendar, units_year): x = [0, 1] time = [0, 720] - units = "days since {}-01-01".format(units_year) + units = f"days since {units_year}-01-01" original = DataArray(x, [("time", time)], name="x") original = original.to_dataset() for v in ["x", "time"]: @@ -4365,7 +4365,7 @@ def test_use_cftime_false_standard_calendar_in_range(calendar): def test_use_cftime_false_standard_calendar_out_of_range(calendar, units_year): x = [0, 1] time = [0, 720] - units = "days since {}-01-01".format(units_year) + units = f"days since {units_year}-01-01" original = DataArray(x, [("time", time)], name="x") original = original.to_dataset() for v in ["x", "time"]: @@ -4384,7 +4384,7 @@ def test_use_cftime_false_standard_calendar_out_of_range(calendar, units_year): def test_use_cftime_false_nonstandard_calendar(calendar, units_year): x = [0, 1] time = [0, 720] - units = "days since {}".format(units_year) + units = f"days since {units_year}" original = DataArray(x, [("time", time)], name="x") original = original.to_dataset() for v in ["x", "time"]: diff --git a/xarray/tests/test_cftime_offsets.py b/xarray/tests/test_cftime_offsets.py index 3be46b68fc4..142769dbbe7 100644 --- a/xarray/tests/test_cftime_offsets.py +++ b/xarray/tests/test_cftime_offsets.py @@ -202,7 +202,7 @@ def test_to_offset_annual(month_label, month_int, multiple, offset_str): if month_label: freq = "-".join([freq, month_label]) if multiple: - freq = "{}".format(multiple) + freq + freq = f"{multiple}{freq}" result = to_offset(freq) if multiple and month_int: @@ -230,7 +230,7 @@ def test_to_offset_quarter(month_label, month_int, multiple, offset_str): if month_label: freq = "-".join([freq, month_label]) if multiple: - freq = "{}".format(multiple) + freq + freq = f"{multiple}{freq}" result = to_offset(freq) if multiple and month_int: diff --git a/xarray/tests/test_coding_strings.py b/xarray/tests/test_coding_strings.py index 10cdd03459c..c9d10ba4eb0 100644 --- a/xarray/tests/test_coding_strings.py +++ b/xarray/tests/test_coding_strings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from contextlib import suppress import numpy as np diff --git a/xarray/tests/test_coding_times.py b/xarray/tests/test_coding_times.py index 45f2ea6e28a..021d76e2b11 100644 --- a/xarray/tests/test_coding_times.py +++ b/xarray/tests/test_coding_times.py @@ -455,7 +455,7 @@ def test_decode_360_day_calendar(): calendar = "360_day" # ensure leap year doesn't matter for year in [2010, 2011, 2012, 2013, 2014]: - units = "days since {}-01-01".format(year) + units = f"days since {year}-01-01" num_times = np.arange(100) if cftime.__name__ == "cftime": @@ -884,7 +884,7 @@ def test_use_cftime_default_standard_calendar_out_of_range(calendar, units_year) from cftime import num2date numerical_dates = [0, 1] - units = "days since {}-01-01".format(units_year) + units = f"days since {units_year}-01-01" expected = num2date( numerical_dates, units, calendar, only_use_cftime_datetimes=True ) @@ -901,7 +901,7 @@ def test_use_cftime_default_non_standard_calendar(calendar, units_year): from cftime import num2date numerical_dates = [0, 1] - units = "days since {}-01-01".format(units_year) + units = f"days since {units_year}-01-01" expected = num2date( numerical_dates, units, calendar, only_use_cftime_datetimes=True ) @@ -919,7 +919,7 @@ def test_use_cftime_true(calendar, units_year): from cftime import num2date numerical_dates = [0, 1] - units = "days since {}-01-01".format(units_year) + units = f"days since {units_year}-01-01" expected = num2date( numerical_dates, units, calendar, only_use_cftime_datetimes=True ) @@ -946,7 +946,7 @@ def test_use_cftime_false_standard_calendar_in_range(calendar): @pytest.mark.parametrize("units_year", [1500, 2500]) def test_use_cftime_false_standard_calendar_out_of_range(calendar, units_year): numerical_dates = [0, 1] - units = "days since {}-01-01".format(units_year) + units = f"days since {units_year}-01-01" with pytest.raises(OutOfBoundsDatetime): decode_cf_datetime(numerical_dates, units, calendar, use_cftime=False) @@ -955,6 +955,6 @@ def test_use_cftime_false_standard_calendar_out_of_range(calendar, units_year): @pytest.mark.parametrize("units_year", [1500, 2000, 2500]) def test_use_cftime_false_non_standard_calendar(calendar, units_year): numerical_dates = [0, 1] - units = "days since {}-01-01".format(units_year) + units = f"days since {units_year}-01-01" with pytest.raises(OutOfBoundsDatetime): decode_cf_datetime(numerical_dates, units, calendar, use_cftime=False) diff --git a/xarray/tests/test_computation.py b/xarray/tests/test_computation.py index e0058f4001d..383427b479b 100644 --- a/xarray/tests/test_computation.py +++ b/xarray/tests/test_computation.py @@ -25,7 +25,7 @@ def assert_identical(a, b): if hasattr(a, "identical"): - msg = "not identical:\n%r\n%r" % (a, b) + msg = f"not identical:\n{a!r}\n{b!r}" assert a.identical(b), msg else: assert_array_equal(a, b) @@ -376,7 +376,7 @@ def func(*x): *objects, input_core_dims=[[dim]] * len(objects), output_core_dims=[[dim]], - exclude_dims={dim} + exclude_dims={dim}, ) if isinstance(result, (xr.Dataset, xr.DataArray)): # note: this will fail if dim is not a coordinate on any input diff --git a/xarray/tests/test_conventions.py b/xarray/tests/test_conventions.py index 5d80abb4661..42b2a679347 100644 --- a/xarray/tests/test_conventions.py +++ b/xarray/tests/test_conventions.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import contextlib import warnings diff --git a/xarray/tests/test_dataarray.py b/xarray/tests/test_dataarray.py index 1398e936f37..d05a02ae705 100644 --- a/xarray/tests/test_dataarray.py +++ b/xarray/tests/test_dataarray.py @@ -2516,7 +2516,7 @@ def test_groupby_reduce_attrs(self): for shortcut in [True, False]: for keep_attrs in [True, False]: - print("shortcut=%s, keep_attrs=%s" % (shortcut, keep_attrs)) + print(f"shortcut={shortcut}, keep_attrs={keep_attrs}") actual = array.groupby("abc").reduce( np.mean, keep_attrs=keep_attrs, shortcut=shortcut ) @@ -4160,7 +4160,7 @@ def test_rolling_wrapped_bottleneck(da, name, center, min_periods): # Test all bottleneck functions rolling_obj = da.rolling(time=7, min_periods=min_periods) - func_name = "move_{}".format(name) + func_name = f"move_{name}" actual = getattr(rolling_obj, name)() expected = getattr(bn, func_name)( da.values, window=7, axis=1, min_count=min_periods diff --git a/xarray/tests/test_dataset.py b/xarray/tests/test_dataset.py index a5c9920f1d9..dce417f27f9 100644 --- a/xarray/tests/test_dataset.py +++ b/xarray/tests/test_dataset.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pickle import sys import warnings @@ -5391,7 +5390,7 @@ def test_rolling_wrapped_bottleneck(ds, name, center, min_periods, key): # Test all bottleneck functions rolling_obj = ds.rolling(time=7, min_periods=min_periods) - func_name = "move_{}".format(name) + func_name = f"move_{name}" actual = getattr(rolling_obj, name)() if key == "z1": # z1 does not depend on 'Time' axis. Stored as it is. expected = ds[key] diff --git a/xarray/tests/test_duck_array_ops.py b/xarray/tests/test_duck_array_ops.py index 62ea19be97b..eb073a14aae 100644 --- a/xarray/tests/test_duck_array_ops.py +++ b/xarray/tests/test_duck_array_ops.py @@ -355,7 +355,7 @@ def test_reduce(dim_num, dtype, dask, func, skipna, aggdim): # Numpy < 1.13 does not handle object-type array. try: if skipna: - expected = getattr(np, "nan{}".format(func))(da.values, axis=axis) + expected = getattr(np, f"nan{func}")(da.values, axis=axis) else: expected = getattr(np, func)(da.values, axis=axis) @@ -400,7 +400,7 @@ def test_reduce(dim_num, dtype, dask, func, skipna, aggdim): actual = getattr(da, func)(skipna=skipna) if dask: assert isinstance(da.data, dask_array_type) - expected = getattr(np, "nan{}".format(func))(da.values) + expected = getattr(np, f"nan{func}")(da.values) if actual.dtype == object: assert actual.values == np.array(expected) else: diff --git a/xarray/tests/test_formatting.py b/xarray/tests/test_formatting.py index c518f528537..9a1f0bbd975 100644 --- a/xarray/tests/test_formatting.py +++ b/xarray/tests/test_formatting.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import sys from textwrap import dedent diff --git a/xarray/tests/test_plot.py b/xarray/tests/test_plot.py index e3b29b86e4d..3ac45a9720f 100644 --- a/xarray/tests/test_plot.py +++ b/xarray/tests/test_plot.py @@ -1544,7 +1544,7 @@ def test_names_appear_somewhere(self): self.darray.name = "testvar" self.g.map_dataarray(xplt.contourf, "x", "y") for k, ax in zip("abc", self.g.axes.flat): - assert "z = {}".format(k) == ax.get_title() + assert f"z = {k}" == ax.get_title() alltxt = text_in_fig() assert self.darray.name in alltxt diff --git a/xarray/tests/test_sparse.py b/xarray/tests/test_sparse.py index 4a0c6c58619..bd26b96f6d4 100644 --- a/xarray/tests/test_sparse.py +++ b/xarray/tests/test_sparse.py @@ -65,7 +65,7 @@ def __call__(self, obj): return getattr(obj, self.meth)(*self.args, **self.kwargs) def __repr__(self): - return "obj.{}(*{}, **{})".format(self.meth, self.args, self.kwargs) + return f"obj.{self.meth}(*{self.args}, **{self.kwargs})" @pytest.mark.parametrize( diff --git a/xarray/tests/test_tutorial.py b/xarray/tests/test_tutorial.py index 9bf84c9edb0..a2eb159f624 100644 --- a/xarray/tests/test_tutorial.py +++ b/xarray/tests/test_tutorial.py @@ -17,9 +17,9 @@ def setUp(self): os.sep.join(("~", ".xarray_tutorial_data", self.testfile)) ) with suppress(OSError): - os.remove("{}.nc".format(self.testfilepath)) + os.remove(f"{self.testfilepath}.nc") with suppress(OSError): - os.remove("{}.md5".format(self.testfilepath)) + os.remove(f"{self.testfilepath}.md5") def test_download_from_github(self): ds = tutorial.open_dataset(self.testfile).load() diff --git a/xarray/tests/test_units.py b/xarray/tests/test_units.py index 15bb40ce4b2..9d14104bb50 100644 --- a/xarray/tests/test_units.py +++ b/xarray/tests/test_units.py @@ -257,14 +257,12 @@ def __call__(self, obj, *args, **kwargs): if key not in exclude_kwargs } else: - raise AttributeError( - "{obj} has no method named '{self.name}'".format(obj=obj, self=self) - ) + raise AttributeError(f"{obj} has no method named '{self.name}'") return func(*all_args, **all_kwargs) def __repr__(self): - return "method_{self.name}".format(self=self) + return f"method_{self.name}" class function: @@ -276,7 +274,7 @@ def __call__(self, *args, **kwargs): return self.func(*args, **kwargs) def __repr__(self): - return "function_{self.name}".format(self=self) + return f"function_{self.name}" @pytest.mark.parametrize("func", (xr.zeros_like, xr.ones_like)) diff --git a/xarray/tests/test_variable.py b/xarray/tests/test_variable.py index eb6101fe37d..78723eda013 100644 --- a/xarray/tests/test_variable.py +++ b/xarray/tests/test_variable.py @@ -215,7 +215,7 @@ def __hash__(self): return hash(self.item) def __repr__(self): - return "%s(item=%r)" % (type(self).__name__, self.item) + return "{}(item={!r})".format(type(self).__name__, self.item) item = HashableItemWrapper((1, 2, 3)) x = self.cls("x", [item]) diff --git a/xarray/ufuncs.py b/xarray/ufuncs.py index 7b9ca1878f7..0f6fc3b1334 100644 --- a/xarray/ufuncs.py +++ b/xarray/ufuncs.py @@ -55,7 +55,7 @@ def __call__(self, *args, **kwargs): f = _dask_or_eager_func(self._name, array_args=slice(len(args))) if len(args) > 2 or len(args) == 0: raise TypeError( - "cannot handle %s arguments for %r" % (len(args), self._name) + "cannot handle {} arguments for {!r}".format(len(args), self._name) ) elif len(args) == 1: if isinstance(args[0], _xarray_types): diff --git a/xarray/util/print_versions.py b/xarray/util/print_versions.py index 4ba327913bc..0d6d147f0bb 100755 --- a/xarray/util/print_versions.py +++ b/xarray/util/print_versions.py @@ -83,7 +83,7 @@ def show_versions(file=sys.stdout): try: sys_info.extend(netcdf_and_hdf5_versions()) except Exception as e: - print("Error collecting netcdf / hdf5 version: {}".format(e)) + print(f"Error collecting netcdf / hdf5 version: {e}") deps = [ # (MODULE_NAME, f(mod) -> mod version) @@ -141,11 +141,11 @@ def show_versions(file=sys.stdout): print("------------------", file=file) for k, stat in sys_info: - print("%s: %s" % (k, stat), file=file) + print(f"{k}: {stat}", file=file) print("", file=file) for k, stat in deps_blob: - print("%s: %s" % (k, stat), file=file) + print(f"{k}: {stat}", file=file) if __name__ == "__main__":