Skip to content

Commit

Permalink
Merge pull request #101 from khaeru/fix/1.18
Browse files Browse the repository at this point in the history
Fixes for 1.18.0
  • Loading branch information
khaeru committed Aug 31, 2023
2 parents 08b7eff + 3a8d1e6 commit 47438fc
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 25 deletions.
12 changes: 10 additions & 2 deletions doc/whatsnew.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
What's new
**********

.. Next release
.. ============
Next release
============

- Show the caller's context in :class:`DeprecationWarning` from :class:`.Computer` methods that were
- deprecated in :pull:`98` (:pull:`101`).
- Bugfix: restore behaviour of genno ≤ 1.17.2 in :func:`.config.aggregate` (:pull:`101`).
Specifically: when there are multiple ``_quantities:`` to be aggregated, a failure to match any one key results in the whole item failing and being re-appended to the queue to be retried after other configuration items.
Giving ``_fail: warning`` (or anything less than "error") causes the behaviour to be permissive: missing keys are logged but tolerated.
This functionality was broken in 1.18.0.
- Allow for zero positional/only keyword arguments when formatting a :class:`DeprecationWarning` from :meth:`.Computer.convert_pyam` (:pull:`101`).

v1.18.0 (2023-08-31)
====================
Expand Down
41 changes: 27 additions & 14 deletions genno/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,27 +159,40 @@ def aggregate(c: Computer, info):
# Copy for destructive .pop()
info = copy(info)

# Unpack `info`
quantities = c.infer_keys(info.pop("_quantities"))
tag = info.pop("_tag")
fail = info.pop("_fail", None)
groups = {info.pop("_dim"): info}
# Keyword arguments for add()
kw = dict(
fail=info.pop("_fail", None),
groups={info.pop("_dim"): info},
strict=True,
sums=True,
)

def _log_or_raise(exc: Exception, default_level: str, message: str):
"""Either raise `exc` if ``kw["fail"]`` > `default_level`, or log `message`."""
fail_level = getattr(logging, (kw["fail"] or default_level).upper())
if fail_level >= logging.ERROR:
raise exc
else:
log.log(fail_level, message)

try:
quantities = c.check_keys(*quantities)
except MissingKeyError as e:
# Default to fail="error" here: stricter
_log_or_raise(e, "error", f"No key(s) {e.args!r} to aggregate")

# Iterate over quantities to be aggregated
for qty in map(Key, quantities):
try:
result = c.add(
qty.add_tag(tag),
"aggregate",
qty,
groups=groups,
strict=True,
sums=True,
fail=fail,
)
result = c.add(qty.add_tag(tag), "aggregate", qty, **kw)
except KeyExistsError:
pass
except MissingKeyError:
if fail == "error":
raise
except MissingKeyError as e:
# Default to fail="warning": more permissive
_log_or_raise(e, "warning", repr(e))
else:
if keys := list(iter_keys(result)):
log.info(f"Add {repr(keys[0])} + {len(keys)-1} partial sums")
Expand Down
13 changes: 7 additions & 6 deletions genno/core/computer.py
Original file line number Diff line number Diff line change
Expand Up @@ -797,7 +797,7 @@ def add_file(self, *args, **kwargs):
f"Computer.add_file(…). Use: Computer.add({kwargs.get('key', arg)!r}, "
'"load_file", …)',
DeprecationWarning,
stacklevel=-1,
stacklevel=2,
)
return computations.load_file.add_tasks(self, *args, **kwargs)

Expand All @@ -814,7 +814,7 @@ def add_product(self, *args, **kwargs):
warn(
f'Computer.add_product(…). Use: Computer.add({args[0]!r}, "mul", …)',
DeprecationWarning,
stacklevel=-1,
stacklevel=2,
)
return computations.mul.add_tasks(self, *args, **kwargs)

Expand Down Expand Up @@ -901,7 +901,7 @@ def aggregate(
f"dimensions=dims_or_groups, strict=True, ...)"
)

warn(f"Computer.aggregate(…, {msg}", DeprecationWarning, stacklevel=-1)
warn(f"Computer.aggregate(…, {msg}", DeprecationWarning, stacklevel=2)

return self.add(key, *args, **kwargs, strict=True, sums=sums, fail=fail)

Expand All @@ -919,12 +919,13 @@ def convert_pyam(self, *args, **kwargs):
c.require_compat("pyam")
c.add(..., "as_pyam", ...)
"""
arg0 = (repr(args[0]) + ", ") if len(args) else ""
warn(
f"""Computer.convert_pyam(…). Use:
Computer.require_compat("pyam")
Computer.add({args[0]!r}, "as_pyam", …)""",
Computer.add({arg0}"as_pyam", …)""",
DeprecationWarning,
stacklevel=-1,
stacklevel=2,
)
self.require_compat("pyam")
return self.get_comp("as_pyam").add_tasks(self, *args, **kwargs)
Expand Down Expand Up @@ -965,6 +966,6 @@ def disaggregate(self, qty, new_dim, method="shares", args=[]):
else:
raise ValueError(method) if isinstance(method, str) else TypeError(method)

warn(f"Computer.disaggregate(…, {msg}", DeprecationWarning, stacklevel=-1)
warn(f"Computer.disaggregate(…, {msg}", DeprecationWarning, stacklevel=2)

return self.add(key, method, qty, *args, sums=False, strict=True)
3 changes: 2 additions & 1 deletion genno/core/key.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ def from_str_or_key(
warn(
"Calling Key.from_str_or_key(value) with no other arguments is no "
"longer necessary; simply use Key(value)",
UserWarning,
FutureWarning,
stacklevel=2,
)
return base

Expand Down
2 changes: 1 addition & 1 deletion genno/tests/core/test_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def test_init1(self, args, expected):

@pytest.mark.parametrize("value, expected", CASES)
def test_from_str_or_key0(self, value, expected):
with pytest.warns(UserWarning, match="no longer necessary"):
with pytest.warns(FutureWarning, match="no longer necessary"):
assert expected == Key.from_str_or_key(value)

@pytest.mark.parametrize(
Expand Down
13 changes: 12 additions & 1 deletion genno/tests/data/config-aggregate0.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
aggregate:
- _quantities: [ "X::", "Y::", "Z::" ]
# Z:: fails because no existing key
- _quantities: [ "X::", "Z::" ]
_tag: agg
_dim: a
_fail: warning

baz123: [baz1, baz2, baz3]
baz13: [baz1, baz3]

# X:: is skipped silently because
# already created above
- _quantities: [ "X::", "Y::" ]
_tag: agg
_dim: a
_fail: warning
Expand Down

0 comments on commit 47438fc

Please sign in to comment.