Merge pull request #7286 from gnikonorov/issue_6856

Output a warning to stderr when an invalid key is read from an INI config file
This commit is contained in:
Ronny Pfannschmidt 2020-06-02 15:47:02 +02:00 committed by GitHub
commit 8faf1e8eca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 85 additions and 0 deletions

View File

@ -109,6 +109,7 @@ Gabriel Reis
Gene Wood Gene Wood
George Kussumoto George Kussumoto
Georgy Dyuldin Georgy Dyuldin
Gleb Nikonorov
Graham Horler Graham Horler
Greg Price Greg Price
Gregory Lee Gregory Lee

View File

@ -0,0 +1,3 @@
A warning is now shown when an unknown key is read from a config INI file.
The `--strict-config` flag has been added to treat these warnings as errors.

View File

@ -1030,6 +1030,7 @@ class Config:
self.known_args_namespace = ns = self._parser.parse_known_args( self.known_args_namespace = ns = self._parser.parse_known_args(
args, namespace=copy.copy(self.option) args, namespace=copy.copy(self.option)
) )
self._validatekeys()
if self.known_args_namespace.confcutdir is None and self.inifile: if self.known_args_namespace.confcutdir is None and self.inifile:
confcutdir = py.path.local(self.inifile).dirname confcutdir = py.path.local(self.inifile).dirname
self.known_args_namespace.confcutdir = confcutdir self.known_args_namespace.confcutdir = confcutdir
@ -1072,6 +1073,17 @@ class Config:
) )
) )
def _validatekeys(self):
for key in self._get_unknown_ini_keys():
message = "Unknown config ini key: {}\n".format(key)
if self.known_args_namespace.strict_config:
fail(message, pytrace=False)
sys.stderr.write("WARNING: {}".format(message))
def _get_unknown_ini_keys(self) -> List[str]:
parser_inicfg = self._parser._inidict
return [name for name in self.inicfg if name not in parser_inicfg]
def parse(self, args: List[str], addopts: bool = True) -> None: def parse(self, args: List[str], addopts: bool = True) -> None:
# parse given cmdline arguments into this config object. # parse given cmdline arguments into this config object.
assert not hasattr( assert not hasattr(

View File

@ -70,6 +70,11 @@ def pytest_addoption(parser):
default=0, default=0,
help="exit after first num failures or errors.", help="exit after first num failures or errors.",
) )
group._addoption(
"--strict-config",
action="store_true",
help="invalid ini keys for the `pytest` section of the configuration file raise errors.",
)
group._addoption( group._addoption(
"--strict-markers", "--strict-markers",
"--strict", "--strict",

View File

@ -147,6 +147,70 @@ class TestParseIni:
result = testdir.inline_run("--confcutdir=.") result = testdir.inline_run("--confcutdir=.")
assert result.ret == 0 assert result.ret == 0
@pytest.mark.parametrize(
"ini_file_text, invalid_keys, stderr_output, exception_text",
[
(
"""
[pytest]
unknown_ini = value1
another_unknown_ini = value2
""",
["unknown_ini", "another_unknown_ini"],
[
"WARNING: Unknown config ini key: unknown_ini",
"WARNING: Unknown config ini key: another_unknown_ini",
],
"Unknown config ini key: unknown_ini",
),
(
"""
[pytest]
unknown_ini = value1
minversion = 5.0.0
""",
["unknown_ini"],
["WARNING: Unknown config ini key: unknown_ini"],
"Unknown config ini key: unknown_ini",
),
(
"""
[some_other_header]
unknown_ini = value1
[pytest]
minversion = 5.0.0
""",
[],
[],
"",
),
(
"""
[pytest]
minversion = 5.0.0
""",
[],
[],
"",
),
],
)
def test_invalid_ini_keys(
self, testdir, ini_file_text, invalid_keys, stderr_output, exception_text
):
testdir.tmpdir.join("pytest.ini").write(textwrap.dedent(ini_file_text))
config = testdir.parseconfig()
assert config._get_unknown_ini_keys() == invalid_keys, str(
config._get_unknown_ini_keys()
)
result = testdir.runpytest()
result.stderr.fnmatch_lines(stderr_output)
if stderr_output:
with pytest.raises(pytest.fail.Exception, match=exception_text):
testdir.runpytest("--strict-config")
class TestConfigCmdlineParsing: class TestConfigCmdlineParsing:
def test_parsing_again_fails(self, testdir): def test_parsing_again_fails(self, testdir):