Merge pull request #7366 from gnikonorov/issue_7346

Allow users to provide version information to the required_plugins INI key
This commit is contained in:
Ronny Pfannschmidt 2020-06-15 20:19:05 +02:00 committed by GitHub
commit 4e5a7b7d2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 78 additions and 5 deletions

View File

@ -0,0 +1 @@
Version information as defined by `PEP 440 <https://www.python.org/dev/peps/pep-0440/#version-specifiers>`_ may now be included when providing plugins to the ``required_plugins`` configuration option.

View File

@ -1562,12 +1562,14 @@ passed multiple times. The expected format is ``name=value``. For example::
.. confval:: required_plugins
A space separated list of plugins that must be present for pytest to run.
Plugins can be listed with or without version specifiers directly following
their name. Whitespace between different version specifiers is not allowed.
If any one of the plugins is not found, emit an error.
.. code-block:: ini
[pytest]
required_plugins = pytest-html pytest-xdist
required_plugins = pytest-django>=3.0.0,<4.0.0 pytest-html pytest-xdist>=1.0.0
.. confval:: testpaths

View File

@ -1106,13 +1106,26 @@ class Config:
if not required_plugins:
return
# Imported lazily to improve start-up time.
from packaging.version import Version
from packaging.requirements import InvalidRequirement, Requirement
plugin_info = self.pluginmanager.list_plugin_distinfo()
plugin_dist_names = [dist.project_name for _, dist in plugin_info]
plugin_dist_info = {dist.project_name: dist.version for _, dist in plugin_info}
missing_plugins = []
for plugin in required_plugins:
if plugin not in plugin_dist_names:
missing_plugins.append(plugin)
for required_plugin in required_plugins:
spec = None
try:
spec = Requirement(required_plugin)
except InvalidRequirement:
missing_plugins.append(required_plugin)
continue
if spec.name not in plugin_dist_info:
missing_plugins.append(required_plugin)
elif Version(plugin_dist_info[spec.name]) not in spec.specifier:
missing_plugins.append(required_plugin)
if missing_plugins:
fail(

View File

@ -250,6 +250,63 @@ class TestParseIni:
),
(
"""
[pytest]
required_plugins = pytest-xdist
""",
"",
),
(
"""
[pytest]
required_plugins = pytest-xdist==1.32.0
""",
"",
),
(
"""
[pytest]
required_plugins = pytest-xdist>1.0.0,<2.0.0
""",
"",
),
(
"""
[pytest]
required_plugins = pytest-xdist~=1.32.0 pytest-xdist==1.32.0 pytest-xdist!=0.0.1 pytest-xdist<=99.99.0
pytest-xdist>=1.32.0 pytest-xdist<9.9.9 pytest-xdist>1.30.0 pytest-xdist===1.32.0
""",
"",
),
(
"""
[pytest]
required_plugins = pytest-xdist>9.9.9 pytest-xdist==1.32.0 pytest-xdist==8.8.8
""",
"Missing required plugins: pytest-xdist==8.8.8, pytest-xdist>9.9.9",
),
(
"""
[pytest]
required_plugins = pytest-xdist==aegsrgrsgs pytest-xdist==-1 pytest-xdist>2.1.1,>3.0.0
""",
"Missing required plugins: pytest-xdist==-1, pytest-xdist==aegsrgrsgs, pytest-xdist>2.1.1,>3.0.0",
),
(
"""
[pytest]
required_plugins = pytest-xdist== pytest-xdist<=
""",
"Missing required plugins: pytest-xdist<=, pytest-xdist==",
),
(
"""
[pytest]
required_plugins = pytest-xdist= pytest-xdist<
""",
"Missing required plugins: pytest-xdist<, pytest-xdist=",
),
(
"""
[some_other_header]
required_plugins = wont be triggered
[pytest]