summaryrefslogtreecommitdiff
path: root/src/tox/tox_env
diff options
context:
space:
mode:
authorBernát Gábor <gaborjbernat@gmail.com>2022-12-06 17:14:44 -0800
committerGitHub <noreply@github.com>2022-12-06 17:14:44 -0800
commit51accd3dea9f9ae5f9dd184d18e55386cdfde641 (patch)
tree1ae5c5580d3bc93025f7f7ea115b57f18f8ce74b /src/tox/tox_env
parent529c2a1d8ee6acdb7ca39d20810227b5ee2d0238 (diff)
downloadtox-git-51accd3dea9f9ae5f9dd184d18e55386cdfde641.tar.gz
Do not conflate extra markers and extra dependencies (#2605)
Resolves https://github.com/tox-dev/tox/issues/2603
Diffstat (limited to 'src/tox/tox_env')
-rw-r--r--src/tox/tox_env/python/virtual_env/package/util.py17
1 files changed, 8 insertions, 9 deletions
diff --git a/src/tox/tox_env/python/virtual_env/package/util.py b/src/tox/tox_env/python/virtual_env/package/util.py
index b84f687a..9936c7f2 100644
--- a/src/tox/tox_env/python/virtual_env/package/util.py
+++ b/src/tox/tox_env/python/virtual_env/package/util.py
@@ -7,20 +7,18 @@ from packaging.requirements import Requirement
def dependencies_with_extras(deps: list[Requirement], extras: set[str], package_name: str) -> list[Requirement]:
- deps = _normalize_req(deps)
+ deps_with_markers = extract_extra_markers(deps)
result: list[Requirement] = []
found: set[str] = set()
todo: set[str | None] = extras | {None}
visited: set[str | None] = set()
while todo:
new_extras: set[str | None] = set()
- for req in deps:
- if todo & (req.extras or {None}): # type: ignore[arg-type]
+ for req, extra_markers in deps_with_markers:
+ if todo & extra_markers:
if req.name == package_name: # support for recursive extras
new_extras.update(req.extras or set())
else:
- req = deepcopy(req)
- req.extras.clear() # strip the extra part as the installation will invoke it without
req_str = str(req)
if req_str not in found:
found.add(req_str)
@@ -30,20 +28,21 @@ def dependencies_with_extras(deps: list[Requirement], extras: set[str], package_
return result
-def _normalize_req(deps: list[Requirement]) -> list[Requirement]:
+def extract_extra_markers(deps: list[Requirement]) -> list[tuple[Requirement, set[str | None]]]:
# extras might show up as markers, move them into extras property
- result: list[Requirement] = []
+ result: list[tuple[Requirement, set[str | None]]] = []
for req in deps:
req = deepcopy(req)
markers: list[str | tuple[Variable, Variable, Variable]] = getattr(req.marker, "_markers", []) or []
_at: int | None = None
+ extra_markers = set()
for _at, (marker_key, op, marker_value) in (
(_at_marker, marker)
for _at_marker, marker in enumerate(markers)
if isinstance(marker, tuple) and len(marker) == 3
):
if marker_key.value == "extra" and op.value == "==": # pragma: no branch
- req.extras.add(marker_value.value)
+ extra_markers.add(marker_value.value)
del markers[_at]
_at -= 1
if _at > 0 and (isinstance(markers[_at], str) and markers[_at] in ("and", "or")):
@@ -51,5 +50,5 @@ def _normalize_req(deps: list[Requirement]) -> list[Requirement]:
if len(markers) == 0:
req.marker = None
break
- result.append(req)
+ result.append((req, extra_markers or {None}))
return result