Repository navigation
DEPR: deprecate astropy.utils.check_broadcast - #16346
Conversation
|
Thank you for your contribution to Astropy! 🌌 This checklist is meant to remind the package maintainers who will review this pull request of some common things to look for.
|
|
👋 Thank you for your draft pull request! Do you know that you can use |
a99383f to
8692aa8
Compare
| r"arg (?P<argno_b>\d+) with shape (?P<shape_b>\((\d+(, ?)?)+\))\." | ||
| ) | ||
| if (match := broadcast_shapes_error_re.fullmatch(str(exc))) is None: | ||
| warnings.warn( |
There was a problem hiding this comment.
Since parsing the error message emitted by numpy is intrinsically fragile (but probably our least-bad option), I spent extra effort on making this logic as robust as possible: failing to parse an error message should be recoverable.
9c86bcc to
ef1d30e
Compare
4f0a0a5 to
45aac14
Compare
| def _add_note_to_exception(exc: Exception, note: str) -> Exception: | ||
| import sys | ||
|
|
||
| if sys.version_info >= (3, 11): | ||
| exc.add_note(note) | ||
| return exc | ||
| else: | ||
| # mimic Python 3.11 behavior: | ||
| # preserve error message and traceback | ||
| return type(exc)(f"{exc!s}\n{note}").with_traceback(exc.__traceback__) |
There was a problem hiding this comment.
This is a side improvement but isn't strictly needed here, I just applied an existing snippet of mine here. Let me know if I should revert it or move it to a separate PR.
There was a problem hiding this comment.
I sligtly like preserving the same instance. In other code, I've done the equivalent of exc.args += ("\n" + note,). Would that work here?
There was a problem hiding this comment.
Hum, I didn't think about that. I guess replacing a tuple attribute is objectively less evil than returning an entirely new instance in a context where we accept mutations anyway. Thanks !
astropy.utils.check_broadcast
83e4540 to
fd5c4c0
Compare
mhvk
left a comment
There was a problem hiding this comment.
Thanks, this looks mostly excellent. But I really would prefer no code changes/comments just for test behaviour - hence the query whether that could be dealt with in the tests themselves. The rest is mostly small stuff.
| try: | ||
| broadcast_shape = check_broadcast(*broadcasted_shapes[0]) | ||
| except (IndexError, TypeError): | ||
| # always promote deprecation warnings to exceptions |
There was a problem hiding this comment.
Is this really necessary? I feel the real code should not have to worry about this. Is it not possible to adjust a test?
p.s. Wish I could trust that except Exception was not covered by the tests...
There was a problem hiding this comment.
Is this really necessary?
For reference, the one test that failed before I applied this change was modeling/tests/test_core.py::test_inputless_model; It failed only in the context of wheel testing where the relevant difference with regular CI is that warnings are not elevated to errors.
See example logs
I haven't found a way to adjust the test itself yet, but I agree that this patch leaves a bad taste. I'll circle back to this.
p.s. Wish I could trust that except Exception was not covered by the tests...
From my experience running this is CI, it is covered, or I wouldn't have needed the aforementioned patch.
There was a problem hiding this comment.
note to self: I think Model._prepare_inputs_single_model underwent an implicit change of behavior and needs adjusting.
There was a problem hiding this comment.
I just pushed what I think is a more maintainable solution, together with a companion comment explaining my findings.
| r" 'p1' of shape .*" | ||
| ) | ||
| with pytest.raises(ValueError, match=MESSAGE): | ||
| with pytest.raises(ValueError): |
There was a problem hiding this comment.
I never liked full matching of error messages, but ValueError is very broad, so maybe keep a simple match="broadcast"? (here and elsewhere in file)
| with pytest.raises( | ||
| ValueError, match="All inputs must have identical shapes or must be scalars" | ||
| ): | ||
| with pytest.raises(ValueError): |
There was a problem hiding this comment.
Maybe again a match="broadcast"
| def _add_note_to_exception(exc: Exception, note: str) -> Exception: | ||
| import sys | ||
|
|
||
| if sys.version_info >= (3, 11): | ||
| exc.add_note(note) | ||
| return exc | ||
| else: | ||
| # mimic Python 3.11 behavior: | ||
| # preserve error message and traceback | ||
| return type(exc)(f"{exc!s}\n{note}").with_traceback(exc.__traceback__) |
There was a problem hiding this comment.
I sligtly like preserving the same instance. In other code, I've done the equivalent of exc.args += ("\n" + note,). Would that work here?
|
@mhvk thanks for your review. I think I addressed all your minor comments. I'll circle back to the more important one on Monday ! |
mhvk
left a comment
There was a problem hiding this comment.
Looks good!
Final question: did you try ignoring all warnings in test_check_broadcast? If that also doesn't work, then let's get things in as they are. Thanks!
ad37735 to
7ae188f
Compare
|
Thanks for reminding me. I updated the test with your suggestion then squashed all commits together. |
Co-authored-by: Felipe Gameleira <[email protected]>
7ae188f to
796c9c2
Compare
Description
Fixes #15211 and replaces #15499 (I marked @felipekhouri as a co-author here)
I note that this implies
IncompatibleShapeErroris now unused (outsidecheck_broadcast. Since users might be importing it to constructtry/exceptblocks aroundcheck_broadcast, it should probably be deprecated too. Let me know if this should be done in the same PR or as a follow up.