MNT/TST: generalize check_figures_equal to work with pytest.marks#15199
Conversation
Generalize (at the cost of reaching a little bit into pytest internals) the check_figures_equal decorator so it works as expected with `pytest.mark.paramatarize`
lib/matplotlib/testing/decorators.py
Outdated
|
|
||
| wrapper.pytestmark = get_unpacked_marks( | ||
| wrapper | ||
| ) + get_unpacked_marks(func) |
There was a problem hiding this comment.
Is this not something you can add together from wrapper.pytestmark and func.pytestmark?
There was a problem hiding this comment.
Is that actually part of the public API?
Internally, pytest uses these three functions to do the mark manipulation:
def get_unpacked_marks(obj):
"""
obtain the unpacked marks that are stored on an object
"""
mark_list = getattr(obj, "pytestmark", [])
if not isinstance(mark_list, list):
mark_list = [mark_list]
return normalize_mark_list(mark_list)
def normalize_mark_list(mark_list):
"""
normalizes marker decorating helpers to mark objects
:type mark_list: List[Union[Mark, Markdecorator]]
:rtype: List[Mark]
"""
extracted = [
getattr(mark, "mark", mark) for mark in mark_list
] # unpack MarkDecorator
for mark in extracted:
if not isinstance(mark, Mark):
raise TypeError("got {!r} instead of Mark".format(mark))
return [x for x in extracted if isinstance(x, Mark)]
def store_mark(obj, mark):
"""store a Mark on an object
this is used to implement the Mark declarations/decorators correctly
"""
assert isinstance(mark, Mark), mark
# always reassign name to avoid updating pytestmark
# in a reference that was only borrowed
obj.pytestmark = get_unpacked_marks(obj) + [mark]I was between just vendoring them all, doing the semi-private import, or adding the obj.pytestmark list together. I took the middle route, I'll change it to just adding the pytestmark lists together.
lib/matplotlib/testing/decorators.py
Outdated
| sig = inspect.signature(func) | ||
| new_sig = sig.replace( | ||
| parameters=( | ||
| [ |
There was a problem hiding this comment.
As a side note, I find your code formatting style extremely hard to read.
There was a problem hiding this comment.
I agree this just looks like the worst of black, things like
wrapper.pytestmark = get_unpacked_marks(
wrapper
) + get_unpacked_marks(func)
just completely obfuscate the structure of the code -- compare with
wrapper.pytestmark = (get_unpacked_marks(wrapper)
+ get_unpacked_marks(func))
(or with an additional newline after the opening parenthesis).
There was a problem hiding this comment.
This is indeed black's doing.
Ironically, the biggest selling point of black for me is avoiding exactly these conversations.
There was a problem hiding this comment.
The fact that it's automated doesn't absolve it from completely violating basic esthetics.
There was a problem hiding this comment.
fwiw @NelleV and I have been trying to come up with a better automated scheme and it's certainly not trivial... Nevertheless, since afaict matplotlib hasn't added black as a dependency, it's a bit weird to add badly black-formatted code...
There was a problem hiding this comment.
(And @tacaswell it looks like you've set it to 71c wide? Which is unconventional to say the least...)
There was a problem hiding this comment.
(I personally just don't buy into the idea that code can be properly formatted without understanding the underlying semantics.)
There was a problem hiding this comment.
(Juan is considering doing constrained reinforcement learning to learn the rules…)
There was a problem hiding this comment.
I thought I set it to 80c (to keep our pyflakes happy). Black does a slightly better job if you give it a bit more width to work with.
|
I'm having a hard time understanding whether this is worth it. There's a chance this gets broken without warning between two pytests version. |
|
I compressed the code a bit. I'm not convinced it is actually more readable..... |
|
@meeseeksdev backport to v3.2.x |
… to work with pytest.marks
…199-on-v3.2.x Backport PR #15199 on branch v3.2.x (MNT/TST: generalize check_figures_equal to work with pytest.marks)
PR Summary
Generalize (at the cost of reaching a little bit into pytest
internals) the check_figures_equal decorator so it works as
expected with
pytest.mark.paramatarizePR Checklist