Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions changelog/14808.deprecation.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
In ini mode (``.ini`` files and ``[tool.pytest.ini_options]`` in ``pyproject.toml``),
reading a non-string value for a :confval:`string`-typed ini option (including
options registered without an explicit type, which default to ``"string"``) is now
deprecated and will raise a ``TypeError`` in pytest 10.
10 changes: 10 additions & 0 deletions src/_pytest/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
from _pytest.pathlib import safe_exists
from _pytest.stash import Stash
from _pytest.warning_types import PytestConfigWarning
from _pytest.warning_types import PytestDeprecationWarning
from _pytest.warning_types import warn_explicit_for


Expand Down Expand Up @@ -1949,6 +1950,15 @@ def _getini_ini(
elif type == "bool":
return _strtobool(str(value).strip())
elif type == "string":
if not isinstance(value, str):
warnings.warn(
PytestDeprecationWarning(
f"{self.inipath}: config option '{name}' expects a string value, "
f"got {builtins.type(value).__name__}: {value!r}. This will raise "
"a TypeError in pytest 10."
),
stacklevel=2,
)
return value
elif type == "int":
if not isinstance(value, str):
Expand Down
27 changes: 27 additions & 0 deletions testing/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -949,6 +949,33 @@ def pytest_addoption(parser):
with pytest.raises(ValueError):
config.getini("other")

def test_addini_string_type_toml_list_deprecated(self, pytester: Pytester) -> None:
# https://github.com/pytest-dev/pytest/issues/14808
pytester.makeconftest(
"""
def pytest_addoption(parser):
parser.addini("mystr", "a string option", type="string")
parser.addini("myuntyped", "an untyped option")
"""
)
pytester.makepyprojecttoml(
"""
[tool.pytest.ini_options]
mystr = ["a", "b"]
myuntyped = ["c", "d"]
"""
)
config = pytester.parseconfig()
with pytest.warns(
pytest.PytestDeprecationWarning, match="expects a string value"
):
assert config.getini("mystr") == ["a", "b"]
# Options registered without an explicit type default to "string".
with pytest.warns(
pytest.PytestDeprecationWarning, match="expects a string value"
):
assert config.getini("myuntyped") == ["c", "d"]

@pytest.mark.parametrize("config_type", ["ini", "pyproject"])
def test_addini_paths(self, pytester: Pytester, config_type: str) -> None:
pytester.makeconftest(
Expand Down