Fix required_plugins with prereleases (#8469)

* Fix required_plugins with prereleases

Fixes #8456

* Fix existing tests

* Update changelog/8456.bugfix.rst

Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>

Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
This commit is contained in:
Florian Bruhin 2021-03-21 22:51:12 +01:00 committed by GitHub
parent 35df3e68d5
commit bc055e8e69
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 9 deletions

View File

@ -0,0 +1 @@
The :confval:`required_plugins` config option now works correctly when pre-releases of plugins are installed, rather than falsely claiming that those plugins aren't installed at all.

View File

@ -1270,14 +1270,16 @@ class Config:
missing_plugins = [] missing_plugins = []
for required_plugin in required_plugins: for required_plugin in required_plugins:
try: try:
spec = Requirement(required_plugin) req = Requirement(required_plugin)
except InvalidRequirement: except InvalidRequirement:
missing_plugins.append(required_plugin) missing_plugins.append(required_plugin)
continue continue
if spec.name not in plugin_dist_info: if req.name not in plugin_dist_info:
missing_plugins.append(required_plugin) missing_plugins.append(required_plugin)
elif Version(plugin_dist_info[spec.name]) not in spec.specifier: elif not req.specifier.contains(
Version(plugin_dist_info[req.name]), prereleases=True
):
missing_plugins.append(required_plugin) missing_plugins.append(required_plugin)
if missing_plugins: if missing_plugins:

View File

@ -309,13 +309,14 @@ class TestParseIni:
result.stdout.no_fnmatch_line("*PytestConfigWarning*") result.stdout.no_fnmatch_line("*PytestConfigWarning*")
@pytest.mark.parametrize( @pytest.mark.parametrize(
"ini_file_text, exception_text", "ini_file_text, plugin_version, exception_text",
[ [
pytest.param( pytest.param(
""" """
[pytest] [pytest]
required_plugins = a z required_plugins = a z
""", """,
"1.5",
"Missing required plugins: a, z", "Missing required plugins: a, z",
id="2-missing", id="2-missing",
), ),
@ -324,6 +325,7 @@ class TestParseIni:
[pytest] [pytest]
required_plugins = a z myplugin required_plugins = a z myplugin
""", """,
"1.5",
"Missing required plugins: a, z", "Missing required plugins: a, z",
id="2-missing-1-ok", id="2-missing-1-ok",
), ),
@ -332,6 +334,7 @@ class TestParseIni:
[pytest] [pytest]
required_plugins = myplugin required_plugins = myplugin
""", """,
"1.5",
None, None,
id="1-ok", id="1-ok",
), ),
@ -340,6 +343,7 @@ class TestParseIni:
[pytest] [pytest]
required_plugins = myplugin==1.5 required_plugins = myplugin==1.5
""", """,
"1.5",
None, None,
id="1-ok-pin-exact", id="1-ok-pin-exact",
), ),
@ -348,23 +352,35 @@ class TestParseIni:
[pytest] [pytest]
required_plugins = myplugin>1.0,<2.0 required_plugins = myplugin>1.0,<2.0
""", """,
"1.5",
None, None,
id="1-ok-pin-loose", id="1-ok-pin-loose",
), ),
pytest.param( pytest.param(
""" """
[pytest] [pytest]
required_plugins = pyplugin==1.6 required_plugins = myplugin
""", """,
"Missing required plugins: pyplugin==1.6", "1.5a1",
None,
id="1-ok-prerelease",
),
pytest.param(
"""
[pytest]
required_plugins = myplugin==1.6
""",
"1.5",
"Missing required plugins: myplugin==1.6",
id="missing-version", id="missing-version",
), ),
pytest.param( pytest.param(
""" """
[pytest] [pytest]
required_plugins = pyplugin==1.6 other==1.0 required_plugins = myplugin==1.6 other==1.0
""", """,
"Missing required plugins: other==1.0, pyplugin==1.6", "1.5",
"Missing required plugins: myplugin==1.6, other==1.0",
id="missing-versions", id="missing-versions",
), ),
pytest.param( pytest.param(
@ -373,6 +389,7 @@ class TestParseIni:
required_plugins = wont be triggered required_plugins = wont be triggered
[pytest] [pytest]
""", """,
"1.5",
None, None,
id="invalid-header", id="invalid-header",
), ),
@ -383,6 +400,7 @@ class TestParseIni:
pytester: Pytester, pytester: Pytester,
monkeypatch: MonkeyPatch, monkeypatch: MonkeyPatch,
ini_file_text: str, ini_file_text: str,
plugin_version: str,
exception_text: str, exception_text: str,
) -> None: ) -> None:
"""Check 'required_plugins' option with various settings. """Check 'required_plugins' option with various settings.
@ -408,7 +426,7 @@ class TestParseIni:
class DummyDist: class DummyDist:
entry_points = attr.ib() entry_points = attr.ib()
files = () files = ()
version = "1.5" version = plugin_version
@property @property
def metadata(self): def metadata(self):