-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: support keyword arguments in marker expressions #12500
feat: support keyword arguments in marker expressions #12500
Conversation
9451472
to
ac18898
Compare
@lovetheguitar could you rebase the PR, fill out the PR description/commits, and compose a change note? |
e49f06a
to
c672f9f
Compare
c672f9f
to
7d4f437
Compare
@RonnyPfannschmidt Could you please have a look? :) |
3e0ebe6
to
edbbbaf
Compare
@webknjaz https://readthedocs.org/projects/pytest/builds/24773128/ does the preview fail to link that or did I reference it wrongly? Edit: The solution was to define a "title" when referencing since at the anchor there was no explicit headline.
Thanks for the tip @webknjaz. |
edbbbaf
to
11c9435
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mostly reviewed this promptly. The walrus thing seems to be the most important blocker.
11c9435
to
2b960c3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be good to go @RonnyPfannschmidt. 🚀 🤞
2b960c3
to
ae6c7d4
Compare
ae6c7d4
to
b1255a9
Compare
src/_pytest/mark/__init__.py
Outdated
if not (matches := self.own_mark_name_mapping.get(name, [])): | ||
return False | ||
|
||
if not kwargs: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This case cannot happen, I'll fix it when I get back to the computer, but feel free to beat me to it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was an early return to keep the logic for "non-keyword" markers fast/similar to before.
The case happens every time a "non-keyword" marker is looked up
pytest/src/_pytest/mark/expression.py
Lines 271 to 272 in f75e3fe
def __bool__(self) -> bool: | |
return self.matcher(self.name) |
awesome - @lovetheguitar thanks for seeing this tough and @webknjaz thanks for sorting out the last details to land this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is amazing work, and it's great how many tests there are and corner cases there are handled!
I'm really unhappy how this was merged in a seemingly unfinished state (TODO comments in various places), while we were eating dinner together, 2 hours after the final version was pushed. I found a couple of pretty obvious things from a cursory review, and now I'll either need to do a follow-up PR to pick up the lose ends, or someone else needs to go back to opening a new PR and all that additional work.
Also, @bluetech wrote the parser in the first place if memory serves me right, so I feel like it'd be appropriate to give him a chance to look at this, no?
|
||
.. code-block:: pytest | ||
|
||
$ pytest -v -m 'device(serial="123")' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Single quotes won't work on Windows, which is why we use double quotes above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In poweshell they do, but good to know they don’t in cmd.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ Changed to "
.
|
||
.. code-block:: bash | ||
|
||
pytest -m slow(phase=1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs quotes to work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ Added "
around the marker expression.
@@ -233,6 +233,54 @@ def test_two(): | |||
assert passed_str == expected_passed | |||
|
|||
|
|||
@pytest.mark.parametrize( | |||
("expr", "expected_passed"), | |||
[ # TODO: improve/sort out |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leftover TODO?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those were the first tests added, any feedback greatly appreciated. Otherwise I can just drop the todo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Preliminarily dropped.
("mark(empty_list=[])", r'unexpected character/s "\[\]"'), | ||
), | ||
) | ||
def test_invalid_kwarg_name_or_value( # TODO: move to `test_syntax_errors` ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leftover TODO?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, sorry, forgot to remove that one, talked about it with Ronny to keep it separate as is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ Removed.
("builtin_matchers_mark(z=1)", False), | ||
), | ||
) | ||
def test_builtin_matchers_keyword_expressions( # TODO: naming when decided |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leftover TODO?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same for that one. 🙃
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ Removed.
@The-Compiler Sure thing, I was also thinking about mentioning @bluetech, since, yes he wrote that part and he commented also in the issue. Feel free to be nitpicky, I'm motivated to learn the customs properly and do the right thing (TM). 😄 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice work, I wouldn't have done it better myself :)
I left some comments.
|
||
Now tests can be selected by marker keyword arguments. | ||
Supported values are :class:`int`, (unescaped) :class:`str`, :class:`bool` & :data:`None`. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to add an example here, for people skimming the changelog without clicking through to the link.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had one in there in the beginning. 😅 I think @RonnyPfannschmidt suggested to remove it and link to the docs.
Do I add it back here or leave as is?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lovetheguitar I think, it's nice to have examples in such places, but perhaps only small ones. I like Ran's idea. If you make a PR for that, we could discuss something more concrete there, with dedicated review and polishing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bluetech I believe the previous comment of @lovetheguitar was addressed to you, eh?
@@ -5,7 +5,8 @@ | |||
expression: expr? EOF | |||
expr: and_expr ('or' and_expr)* | |||
and_expr: not_expr ('and' not_expr)* | |||
not_expr: 'not' not_expr | '(' expr ')' | ident | |||
not_expr: 'not' not_expr | '(' expr ')' | ident ( '(' name '=' value ( ', ' name '=' value )* ')')* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Would remove the space after
ident (
for consistency. - The
*
(zero-or-more) at the end of this line should be?
(zero-or-one), I think. - The definitions of the
name
andvalue
productions are missing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- removed the space
- true, changed to
?
- added a definition, not sure about the semantics though 😅
@@ -5,7 +5,8 @@ | |||
expression: expr? EOF | |||
expr: and_expr ('or' and_expr)* | |||
and_expr: not_expr ('and' not_expr)* | |||
not_expr: 'not' not_expr | '(' expr ')' | ident | |||
not_expr: 'not' not_expr | '(' expr ')' | ident ( '(' name '=' value ( ', ' name '=' value )* ')')* | |||
|
|||
ident: (\w|:|\+|-|\.|\[|\]|\\|/)+ | |||
|
|||
The semantics are: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's describe here the semantics of ident(...)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added, tried to adhere to the previous style. LMKWYT.
@@ -43,6 +47,9 @@ class TokenType(enum.Enum): | |||
NOT = "not" | |||
IDENT = "identifier" | |||
EOF = "end of input" | |||
EQUAL = "=" | |||
STRING = "str" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"str" might be confusing, I suggest "string literal"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ I agree, changed accordingly and added test case.
Too bad that it got auto-merged earlier, than intended. I knew that Ronny didn't want to make the process too difficult for a first-time contributor so I fixed a few concerns myself and hit @lovetheguitar since you stated you wanted to do better, here are some action items that you could perform (with an attempt to explain why they are important):
That point (3) is something that happened here — I suggested a few correct fixes and extra explanations in some places. It was possible to click one button on the GH UI and get them in. However, they ended up being dismissed for a mysterious reason that I still have no idea of. There was a comment about choosing to use an alternative (worse) syntax option but the motivation was never stated. So I still had to just add those things manually which prolonged the PR cycle — because of lack of communication. To summarize, the PR was good in general, but a few things were missed during the review and the transparency could be better (not just on the PR author's side, though). |
Improve documentation & other kinks of marker keyword expression PR #12500
Fixes #12281
With this change you can restrict a test run to only run tests matching one or multiple marker
keyword arguments
Only keyword argument matching is supported in marker expressions.
Only
int
,str
,bool
&None
values are supported in marker expressions.