Skip to content

Commit d79af50

Browse files
committed
Add strict ini option to enable all other strictness options
The `--strict` option is undeprecated and enables `strict`. Fix #13823.
1 parent 95204ed commit d79af50

File tree

13 files changed

+107
-35
lines changed

13 files changed

+107
-35
lines changed

changelog/13823.feature.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Added a :confval:`strict` configuration option to enable all strictness-related options.
2+
3+
When set to ``True``, the :confval:`strict` option currently enables :confval:`strict_config`,
4+
:confval:`strict_markers`, :confval:`strict_xfail`, and :confval:`strict_parametrization_ids`.
5+
6+
The individual strictness options can be explicitly set to override the global :confval:`strict` setting.
7+
8+
If new strictness options are added in the future, they will also be automatically enabled by :confval:`strict`.
9+
Therefore, we only recommend setting ``strict=True`` if you're using a locked version of pytest,
10+
or if you want to proactively adopt new strictness options as they are added.

doc/en/deprecations.rst

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -589,18 +589,20 @@ removed in pytest 8 (deprecated since pytest 2.4.0):
589589
- ``parser.addoption(..., type="int/string/float/complex")`` - use ``type=int`` etc. instead.
590590

591591

592-
The ``--strict`` command-line option
593-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
592+
The ``--strict`` command-line option (reintroduced)
593+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
594594

595595
.. deprecated:: 6.2
596-
.. versionremoved:: 8.0
596+
.. versionchanged:: 9.0
597597

598-
The ``--strict`` command-line option has been deprecated in favor of ``--strict-markers``, which
598+
The ``--strict`` command-line option had been deprecated in favor of ``--strict-markers``, which
599599
better conveys what the option does.
600600

601-
We have plans to maybe in the future to reintroduce ``--strict`` and make it an encompassing
602-
flag for all strictness related options (``--strict-markers`` and ``--strict-config``
603-
at the moment, more might be introduced in the future).
601+
In version 8.1, we accidentally un-deprecated ``--strict``.
602+
603+
In version 9.0, we changed ``--strict`` to make it set the new :confval:`strict`
604+
configuration option. It now enables all strictness related options (including
605+
:confval:`strict_markers`).
604606

605607

606608
.. _cmdline-preparse-deprecated:

doc/en/reference/reference.rst

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2066,6 +2066,32 @@ passed multiple times. The expected format is ``name=value``. For example::
20662066
"auto" can be used to explicitly use the global verbosity level.
20672067

20682068

2069+
.. confval:: strict
2070+
2071+
If set to ``True``, enables all strictness options:
2072+
2073+
* :confval:`strict_config`
2074+
* :confval:`strict_markers`
2075+
* :confval:`strict_xfail`
2076+
* :confval:`strict_parametrization_ids`
2077+
2078+
Plugins may also enable their own strictness options.
2079+
2080+
If you explicitly set an individual strictness option, it takes precedence over ``strict``.
2081+
2082+
.. note::
2083+
If new strictness options are added to pytest in the future, they will also be enabled by ``strict``.
2084+
We therefore only recommend using this option when using a locked version of pytest,
2085+
or if you want to proactively adopt new strictness options as they are added.
2086+
2087+
.. code-block:: ini
2088+
2089+
[pytest]
2090+
strict = True
2091+
2092+
.. versionadded:: 9.0
2093+
2094+
20692095
.. confval:: strict_xfail
20702096

20712097
If set to ``True``, tests marked with ``@pytest.mark.xfail`` that actually succeed will by default fail the
@@ -2078,6 +2104,8 @@ passed multiple times. The expected format is ``name=value``. For example::
20782104
[pytest]
20792105
strict_xfail = True
20802106
2107+
You can also enable this option via the :confval:`strict` option.
2108+
20812109
.. versionchanged:: 9.0
20822110
Renamed from ``xfail_strict`` to ``strict_xfail``.
20832111
``xfail_strict`` is accepted as an alias for ``strict_xfail``.
@@ -2092,6 +2120,8 @@ passed multiple times. The expected format is ``name=value``. For example::
20922120
[pytest]
20932121
strict_config = True
20942122
2123+
You can also enable this option via the :confval:`strict` option.
2124+
20952125

20962126
.. confval:: strict_markers
20972127

@@ -2102,6 +2132,8 @@ passed multiple times. The expected format is ``name=value``. For example::
21022132
[pytest]
21032133
strict_markers = True
21042134
2135+
You can also enable this option via the :confval:`strict` option.
2136+
21052137

21062138
.. confval:: strict_parametrization_ids
21072139

@@ -2115,6 +2147,8 @@ passed multiple times. The expected format is ``name=value``. For example::
21152147
[pytest]
21162148
strict_parametrization_ids = True
21172149
2150+
You can also enable this option via the :confval:`strict` option.
2151+
21182152
For example,
21192153

21202154
.. code-block:: python

pyproject.toml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -378,10 +378,7 @@ norecursedirs = [
378378
"build",
379379
"dist",
380380
]
381-
strict_xfail = true
382-
strict_parametrization_ids = true
383-
strict_markers = true
384-
strict_config = true
381+
strict = true
385382
filterwarnings = [
386383
"error",
387384
"default:Using or importing the ABCs:DeprecationWarning:unittest2.*",

src/_pytest/config/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1516,6 +1516,8 @@ def _validate_plugins(self) -> None:
15161516

15171517
def _warn_or_fail_if_strict(self, message: str) -> None:
15181518
strict_config = self.getini("strict_config")
1519+
if strict_config is None:
1520+
strict_config = self.getini("strict")
15191521
if strict_config:
15201522
raise UsageError(message)
15211523

src/_pytest/main.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,21 +90,32 @@ def pytest_addoption(parser: Parser) -> None:
9090
)
9191
group.addoption(
9292
"--strict",
93-
action="store_true",
94-
help="(Deprecated) alias to --strict-markers",
93+
action=OverrideIniAction,
94+
ini_option="strict",
95+
ini_value="true",
96+
help="Enables the strict option",
9597
)
9698
parser.addini(
9799
"strict_config",
98100
"Any warnings encountered while parsing the `pytest` section of the "
99101
"configuration file raise errors",
100102
type="bool",
101-
default=False,
103+
# None => fallback to `strict`.
104+
default=None,
102105
)
103106
parser.addini(
104107
"strict_markers",
105108
"Markers not registered in the `markers` section of the configuration "
106109
"file raise errors",
107110
type="bool",
111+
# None => fallback to `strict`.
112+
default=None,
113+
)
114+
parser.addini(
115+
"strict",
116+
"Enables all strictness options, currently: "
117+
"strict_config, strict_markers, strict_xfail, strict_parametrization_ids",
118+
type="bool",
108119
default=False,
109120
)
110121

src/_pytest/mark/structures.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -585,9 +585,9 @@ def __getattr__(self, name: str) -> MarkDecorator:
585585
__tracebackhide__ = True
586586
fail(f"Unknown '{name}' mark, did you mean 'parametrize'?")
587587

588-
strict_markers = (
589-
self._config.getini("strict_markers") or self._config.option.strict
590-
)
588+
strict_markers = self._config.getini("strict_markers")
589+
if strict_markers is None:
590+
strict_markers = self._config.getini("strict")
591591
if strict_markers:
592592
fail(
593593
f"{name!r} not found in `markers` configuration option",

src/_pytest/python.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import textwrap
2525
import types
2626
from typing import Any
27+
from typing import cast
2728
from typing import final
2829
from typing import Literal
2930
from typing import NoReturn
@@ -111,7 +112,8 @@ def pytest_addoption(parser: Parser) -> None:
111112
parser.addini(
112113
"strict_parametrization_ids",
113114
type="bool",
114-
default=False,
115+
# None => fallback to `strict`.
116+
default=None,
115117
help="Emit an error if non-unique parameter set IDs are detected",
116118
)
117119

@@ -963,9 +965,12 @@ def make_unique_parameterset_ids(self) -> list[str | _HiddenParam]:
963965
return resolved_ids
964966

965967
def _strict_parametrization_ids_enabled(self) -> bool:
966-
if self.config:
967-
return bool(self.config.getini("strict_parametrization_ids"))
968-
return False
968+
if self.config is None:
969+
return False
970+
strict_parametrization_ids = self.config.getini("strict_parametrization_ids")
971+
if strict_parametrization_ids is None:
972+
strict_parametrization_ids = self.config.getini("strict")
973+
return cast(bool, strict_parametrization_ids)
969974

970975
def _resolve_ids(self) -> Iterable[str | _HiddenParam]:
971976
"""Resolve IDs for all ParameterSets (may contain duplicates)."""

src/_pytest/skipping.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ def pytest_addoption(parser: Parser) -> None:
4040
"strict_xfail",
4141
"Default for the strict parameter of xfail "
4242
"markers when not given explicitly (default: False) (alias: xfail_strict)",
43-
default=False,
4443
type="bool",
44+
# None => fallback to `strict`.
45+
default=None,
4546
aliases=["xfail_strict"],
4647
)
4748

@@ -214,7 +215,11 @@ def evaluate_xfail_marks(item: Item) -> Xfail | None:
214215
"""Evaluate xfail marks on item, returning Xfail if triggered."""
215216
for mark in item.iter_markers(name="xfail"):
216217
run = mark.kwargs.get("run", True)
217-
strict = mark.kwargs.get("strict", item.config.getini("strict_xfail"))
218+
strict = mark.kwargs.get("strict")
219+
if strict is None:
220+
strict = item.config.getini("strict_xfail")
221+
if strict is None:
222+
strict = item.config.getini("strict")
218223
raises = mark.kwargs.get("raises", None)
219224
if "condition" not in mark.kwargs:
220225
conditions = mark.args

testing/test_collection.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2726,15 +2726,17 @@ def test_1(): pass
27262726
),
27272727
],
27282728
)
2729+
@pytest.mark.parametrize("option_name", ["strict_parametrization_ids", "strict"])
27292730
def test_strict_parametrization_ids(
27302731
pytester: Pytester,
27312732
x_y: Sequence[tuple[int, int]],
27322733
expected_duplicates: Sequence[str],
2734+
option_name: str,
27332735
) -> None:
27342736
pytester.makeini(
2735-
"""
2737+
f"""
27362738
[pytest]
2737-
strict_parametrization_ids = true
2739+
{option_name} = true
27382740
"""
27392741
)
27402742
pytester.makepyfile(

0 commit comments

Comments
 (0)