From 2803c1f929624626bae0918e6e01078d5fe6d51b Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 27 Sep 2024 11:36:10 -0600 Subject: [PATCH 1/4] use absolute imports --- src/landlab/field/graph_field.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/landlab/field/graph_field.py b/src/landlab/field/graph_field.py index 8e2c4b56ae..14cea30c83 100644 --- a/src/landlab/field/graph_field.py +++ b/src/landlab/field/graph_field.py @@ -5,8 +5,8 @@ import numpy as np import xarray as xr -from .errors import FieldError -from .errors import GroupError +from landlab.field.errors import FieldError +from landlab.field.errors import GroupError def reshape_for_storage(array, field_size=None): From c0b53271ad95ecd21af7ec1031868f3329bc231f Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 27 Sep 2024 11:55:31 -0600 Subject: [PATCH 2/4] add _parse_args_and_location to parse old-style args --- src/landlab/field/graph_field.py | 40 ++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/landlab/field/graph_field.py b/src/landlab/field/graph_field.py index 14cea30c83..8c7a3a0866 100644 --- a/src/landlab/field/graph_field.py +++ b/src/landlab/field/graph_field.py @@ -1408,3 +1408,43 @@ def add_full(self, *args, **kwds): data = self.add_empty(name, at=at, **kwds) data.fill(fill_value) return data + + +def _parse_args_and_location(n_args: int, *args, **kwds) -> tuple[str, str]: + """Parse arguments for backward compatibility. + + Parameters + ---------- + n_args : int + The new number of expected arguments. + *args : tuple + The passed arguments. + **kwds : dict + The passed keyword arguments. + + Returns + ------- + tuple of tuple, str + The arguments as expect with the new signature followed by + the location string. + + Examples + -------- + >>> from landlab.field.graph_field import _parse_args_and_location + >>> _parse_args_and_location(0, "node") + ((), 'node') + >>> _parse_args_and_location(1, "node", "z") + (('z',), 'node') + >>> _parse_args_and_location(2, "cell", "z", [1, 2, 3]) + (('z', [1, 2, 3]), 'cell') + >>> _parse_args_and_location(2, "cell", "z", [1, 2, 3], at="node") + (('z', [1, 2, 3]), 'cell') + >>> _parse_args_and_location(2, "z", [1, 2, 3], at="node") + (('z', [1, 2, 3]), 'node') + """ + if len(args) == n_args: + return args, kwds.get("at", None) + elif len(args) == n_args + 1: + return args[1:], args[0] + else: + raise ValueError(f"number of arguments must be {n_args} or {n_args + 1}") From 74daf25fce891bd01fc123fd0771379f6dd49cf7 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 27 Sep 2024 12:28:01 -0600 Subject: [PATCH 3/4] warn with a FutureWarning if old-style is used --- src/landlab/field/graph_field.py | 102 ++++++++++++++----------------- 1 file changed, 46 insertions(+), 56 deletions(-) diff --git a/src/landlab/field/graph_field.py b/src/landlab/field/graph_field.py index 8c7a3a0866..7992946e6b 100644 --- a/src/landlab/field/graph_field.py +++ b/src/landlab/field/graph_field.py @@ -2,6 +2,9 @@ :class:`~landlab.graph.graph.Graph`. """ +import inspect +import warnings + import numpy as np import xarray as xr @@ -658,14 +661,9 @@ def has_field(self, *args, **kwds): :meta landlab: info-field """ - if len(args) == 2: - group, field = args - elif len(args) == 1: - group, field = kwds.pop("at", self.default_group), args[0] - else: - raise ValueError("number of arguments must be 1 or 2") - if group is None: - raise ValueError("no group provided") + kwds.setdefault("at", self.default_group) + args, group = _parse_args_and_location(1, *args, **kwds) + field = args[0] try: return field in self[group] @@ -784,14 +782,9 @@ def field_values(self, *args, **kwds): :meta landlab: field-io """ - if len(args) == 2: - group, field = args - elif len(args) == 1: - group, field = kwds.pop("at", self.default_group), args[0] - else: - raise ValueError("number of arguments must be 1 or 2") - if group is None: - raise ValueError("no group provided") + kwds.setdefault("at", self.default_group) + args, group = _parse_args_and_location(1, *args, **kwds) + field = args[0] try: fields = self[group] @@ -883,17 +876,12 @@ def return_array_or_field_values(self, *args, **kwds): :meta landlab: field-io """ - if len(args) == 2: - group, field = args - elif len(args) == 1: - group, field = kwds.pop("at", self.default_group), args[0] - else: - raise ValueError("number of arguments must be 1 or 2") - if group is None: - raise ValueError("no group provided") + kwds.setdefault("at", self.default_group) + args, group = _parse_args_and_location(1, *args, **kwds) + field = args[0] if isinstance(field, str): - vals = self.field_values(group, field) + vals = self.field_values(field, at=group) else: vals = np.asarray(field) if vals.size != self[group].size: @@ -932,14 +920,9 @@ def field_units(self, *args, **kwds): :meta landlab: info-field """ - if len(args) == 2: - group, field = args - elif len(args) == 1: - group, field = kwds.pop("at", self.default_group), args[0] - else: - raise ValueError("number of arguments must be 1 or 2") - if group is None: - raise ValueError("no group provided") + kwds.setdefault("at", self.default_group) + args, group = _parse_args_and_location(1, *args, **kwds) + field = args[0] return self[group]._ds[field].attrs["units"] @@ -977,10 +960,9 @@ def empty(self, *args, **kwds): :meta landlab: field-add """ - if len(args) == 0: - group = kwds.pop("at", kwds.pop("centering", "node")) - else: - group = args[0] + kwds.setdefault("at", kwds.pop("centering", "node")) + args, group = _parse_args_and_location(0, *args, **kwds) + kwds.pop("at") if group == "grid": raise ValueError( @@ -1148,12 +1130,10 @@ def add_field(self, *args, **kwds): :meta landlab: field-add """ - if len(args) == 3: - at, name, value_array = args - elif len(args) == 2: - at, name, value_array = (kwds.pop("at", None), args[0], args[1]) - else: - raise ValueError("number of arguments must be 2 or 3") + kwds.setdefault("at", "node") + args, at = _parse_args_and_location(2, *args, **kwds) + name, value_array = args + kwds.pop("at") units = kwds.get("units", "?") copy = kwds.get("copy", False) @@ -1250,12 +1230,11 @@ def add_empty(self, *args, **kwds): :meta landlab: field-add """ - if len(args) == 2: - loc, name = args - elif len(args) == 1: - loc, name = kwds.pop("at"), args[0] - else: - raise ValueError("number of arguments must be 1 or 2") + kwds.setdefault("at", "node") + args, loc = _parse_args_and_location(1, *args, **kwds) + name = args[0] + kwds.pop("at") + units = kwds.pop("units", "?") copy = kwds.pop("copy", False) clobber = kwds.pop("clobber", False) @@ -1397,13 +1376,10 @@ def add_full(self, *args, **kwds): :meta landlab: field-add """ - if len(args) == 3: - at, name, fill_value = args - elif len(args) == 2: - at = kwds.pop("at", "node") - name, fill_value = args - else: - raise ValueError("number of arguments must be 2 or 3") + kwds.setdefault("at", "node") + args, at = _parse_args_and_location(2, *args, **kwds) + name, fill_value = args + kwds.pop("at") data = self.add_empty(name, at=at, **kwds) data.fill(fill_value) @@ -1445,6 +1421,20 @@ def _parse_args_and_location(n_args: int, *args, **kwds) -> tuple[str, str]: if len(args) == n_args: return args, kwds.get("at", None) elif len(args) == n_args + 1: + caller_name = inspect.stack()[1].function + sig = f"at={args[0]!r}" + if n_args > 0: + sig = ", ".join([f"arg{n}" for n in range(n_args)] + [sig]) + + warnings.warn( + f"Calling `{caller_name}` with the field location as the first argument" + " is deprecated and will be removed in future versions. Instead, please use" + " the `at` keyword to specify the location:" + f" {caller_name}({sig}).", + FutureWarning, + stacklevel=3, + ) + return args[1:], args[0] else: raise ValueError(f"number of arguments must be {n_args} or {n_args + 1}") From bff229b8e33c4b516f49604a03b0f28f96ee2fe9 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Thu, 17 Oct 2024 23:09:38 -0600 Subject: [PATCH 4/4] add news fragment [skip ci] --- news/1999.misc | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 news/1999.misc diff --git a/news/1999.misc b/news/1999.misc new file mode 100644 index 0000000000..51a5a037ba --- /dev/null +++ b/news/1999.misc @@ -0,0 +1,3 @@ + +Deprecated passing the `at` keyword as the first argument to +functions like, for example, :meth:`~.GraphFields.add_ones`.