fix: validate marker names in -m expression with --strict-markers - #14127
Conversation
There was a problem hiding this comment.
Pull request overview
This pull request implements validation of marker names in -m (marker expression) arguments when --strict-markers is enabled, addressing issue #2781. Previously, --strict-markers only validated markers used in test decorations (e.g., @pytest.mark.foo), but not markers referenced in command-line -m expressions.
Changes:
- Added tracking of identifier names during expression parsing to capture marker names used in expressions
- Implemented validation of marker names in
-mexpressions against registered markers when strict mode is enabled - Added comprehensive test coverage for the new validation behavior
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/_pytest/mark/expression.py | Modified Scanner, expression parser, and Expression class to track and expose identifier names used in expressions |
| src/_pytest/mark/init.py | Added _validate_marker_names() function to validate markers in expressions when strict_markers is enabled |
| testing/test_mark_expression.py | Added unit tests for the new Expression.idents() method |
| testing/test_mark.py | Added integration test verifying that unregistered markers in -m expressions trigger errors with --strict-markers |
| changelog/2781.feature.rst | Documented the new feature |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| pytester.makeini( | ||
| """ | ||
| [pytest] | ||
| markers = registered: a registered marker | ||
| """ | ||
| ) |
There was a problem hiding this comment.
The makeini call here is redundant because it's immediately overwritten by another makeini call on lines 239-245 when option_name is "strict_markers" or "strict". This first ini file is never used. Consider removing these lines or restructuring the test to avoid creating the ini file twice.
ec4ad16 to
20e1063
Compare
bluetech
left a comment
There was a problem hiding this comment.
I debated with myself whether this is a good feature. It can help with bad typos, but maybe there's a use case for trying non-registered markers? But I couldn't think of any such use cases. So LGTM. Let's see if anyone complains...
Consider also mentioning this briefly in the strict_markers documentation.
56688fb to
2192ac2
Compare
9964bfb to
c1a9d4e
Compare
d65846e to
c8e1948
Compare
Extract marker line parsing into a single _iter_registered_markers() method on Config class, replacing duplicate parsing logic in three locations: - MarkGenerator._markers cache population - _validate_marker_names() for strict marker checking - pytest_cmdline_main() for --markers display Introduces RegisteredMarker NamedTuple with name, signature, and description fields for cleaner API. Co-authored-by: Cursor AI <ai@cursor.sh> Co-authored-by: Anthropic Claude Opus 4.5 <claude@anthropic.com>
Closes pytest-dev#2781 Co-authored-by: Cursor AI <ai@cursor.sh> Co-authored-by: Anthropic Claude Opus 4.5 <claude@anthropic.com>
c8e1948 to
a8cc3f1
Compare
_validate_marker_names re-implemented the "markers" ini parsing inline, duplicating the split logic and its comment verbatim from Config._iter_registered_markers. Use the helper instead, matching the other two call sites in mark/__init__.py and mark/structures.py. This also exercises FakeConfig._iter_registered_markers in the tests, which was previously dead code and the sole patch-coverage miss. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Fixes #2781
When
--strict-markersis enabled, marker names used in-mexpressions are now validated against registered markers.