diff --git a/docs/changelog/1380.bugfix.rst b/docs/changelog/1380.bugfix.rst new file mode 100644 index 000000000..c7fdadf16 --- /dev/null +++ b/docs/changelog/1380.bugfix.rst @@ -0,0 +1 @@ +Honor environment markers in ``requires`` list - by :user:`asottile` diff --git a/src/tox/config/__init__.py b/src/tox/config/__init__.py index b5df35833..1d66ed7ae 100644 --- a/src/tox/config/__init__.py +++ b/src/tox/config/__init__.py @@ -1165,6 +1165,9 @@ def ensure_requires_satisfied(config, requires, min_version): # noinspection PyBroadException try: package = requirements.Requirement(require) + # check if the package even applies + if package.marker and not package.marker.evaluate({"extra": ""}): + continue package_name = canonicalize_name(package.name) if package_name not in exists: deps.append(DepConfig(require, None)) diff --git a/tests/integration/test_provision_int.py b/tests/integration/test_provision_int.py index 01f3cfec8..b002f0ee7 100644 --- a/tests/integration/test_provision_int.py +++ b/tests/integration/test_provision_int.py @@ -23,7 +23,8 @@ def test_provision_missing(initproj, cmd): minversion = 3.7.0 requires = setuptools == 40.6.3 - pyparsing!=2.4.1,!=2.4.1.1;python_version=="3.4" + # remove when 2.4.2 is released or python3.4 is dropped + pyparsing!=2.4.1,!=2.4.1.1 [testenv] commands=python -c "import sys; print(sys.executable); raise SystemExit(1)" """ diff --git a/tests/unit/session/test_provision.py b/tests/unit/session/test_provision.py index e8f7abc23..c2840197c 100644 --- a/tests/unit/session/test_provision.py +++ b/tests/unit/session/test_provision.py @@ -24,10 +24,10 @@ def test_provision_min_version_is_requires(newconfig, next_tox_major): with pytest.raises(MissingRequirement) as context: newconfig( [], - """ + """\ [tox] minversion = {} - """.format( + """.format( next_tox_major ), ) @@ -45,10 +45,10 @@ def test_provision_min_version_is_requires(newconfig, next_tox_major): def test_provision_tox_change_name(newconfig): config = newconfig( [], - """ + """\ [tox] provision_tox_env = magic - """, + """, ) assert config.provision_tox_env == "magic" @@ -58,12 +58,12 @@ def test_provision_basepython_global_only(newconfig, next_tox_major): with pytest.raises(MissingRequirement) as context: newconfig( [], - """ + """\ [tox] minversion = {} [testenv] basepython = what - """.format( + """.format( next_tox_major ), ) @@ -77,12 +77,12 @@ def test_provision_basepython_local(newconfig, next_tox_major): with pytest.raises(MissingRequirement) as context: newconfig( [], - """ + """\ [tox] minversion = {} [testenv:.tox] basepython = what - """.format( + """.format( next_tox_major ), ) @@ -95,10 +95,10 @@ def test_provision_bad_requires(newconfig, capsys, monkeypatch): with pytest.raises(BadRequirement): newconfig( [], - """ + """\ [tox] requires = sad >sds d ok - """, + """, ) out, err = capsys.readouterr() assert "ERROR: failed to parse InvalidRequirement" in out @@ -208,7 +208,7 @@ def test_provision_non_canonical_dep( initproj( "w-0.1", { - "tox.ini": """ + "tox.ini": """\ [tox] envlist = py requires = @@ -231,6 +231,21 @@ def test_provision_non_canonical_dep( result.assert_success(is_run_test_env=False) +def test_provision_requirement_with_environment_marker(cmd, initproj): + initproj( + "proj", + { + "tox.ini": """\ + [tox] + requires = + package-that-does-not-exist;python_version=="1.0" + """ + }, + ) + result = cmd("-e", "py", "-vv") + result.assert_success(is_run_test_env=False) + + def space_path2url(path): at_path = str(path) if " " not in at_path: