Skip to content

Commit 9486d95

Browse files
committed
Improve check for satisfied dependencies
1 parent ded23d2 commit 9486d95

File tree

4 files changed

+31
-8
lines changed

4 files changed

+31
-8
lines changed

backend/hatchling/dep/core.py

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import re
22
import sys
33

4+
from packaging.markers import default_environment
45
from packaging.requirements import Requirement
56

67
try:
@@ -10,8 +11,8 @@
1011

1112

1213
class DistributionCache:
13-
def __init__(self, sys_path=None):
14-
self._resolver = Distribution.discover(context=DistributionFinder.Context(path=sys_path or sys.path))
14+
def __init__(self, sys_path):
15+
self._resolver = Distribution.discover(context=DistributionFinder.Context(path=sys_path))
1516
self._distributions = {}
1617
self._search_exhausted = False
1718
self._canonical_regex = re.compile(r'[-_.]+')
@@ -35,7 +36,10 @@ def __getitem__(self, item):
3536
self._search_exhausted = True
3637

3738

38-
def dependency_in_sync(requirement, installed_distributions):
39+
def dependency_in_sync(requirement, environment, installed_distributions):
40+
if requirement.marker and not requirement.marker.evaluate(environment):
41+
return True
42+
3943
distribution = installed_distributions[requirement.name]
4044
if distribution is None:
4145
return False
@@ -58,10 +62,10 @@ def dependency_in_sync(requirement, installed_distributions):
5862
# extra and it's just a user error/typo. See: https://github.com/pypa/pip/issues/7122
5963
if extra not in available_extras:
6064
return False
61-
elif not transitive_requirement.marker.evaluate({'extra': extra}):
62-
continue
6365

64-
if not dependency_in_sync(transitive_requirement, installed_distributions):
66+
extra_environment = dict(environment)
67+
extra_environment['extra'] = extra
68+
if not dependency_in_sync(transitive_requirement, extra_environment, installed_distributions):
6569
return False
6670

6771
if requirement.specifier and not requirement.specifier.contains(distribution.version):
@@ -93,6 +97,11 @@ def dependency_in_sync(requirement, installed_distributions):
9397
return True
9498

9599

96-
def dependencies_in_sync(requirements, sys_path=None):
100+
def dependencies_in_sync(requirements, sys_path=None, environment=None):
101+
if sys_path is None:
102+
sys_path = sys.path
103+
if environment is None:
104+
environment = default_environment()
105+
97106
installed_distributions = DistributionCache(sys_path)
98-
return all(dependency_in_sync(requirement, installed_distributions) for requirement in requirements)
107+
return all(dependency_in_sync(requirement, environment, installed_distributions) for requirement in requirements)

docs/meta/history.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ This is the first release candidate for Hatch v1, a complete rewrite.
7777

7878
- Build hooks now have access to project metadata
7979

80+
***Fixed:***
81+
82+
- Improve check for satisfied dependencies
83+
8084
### [0.8.2](https://github.com/ofek/hatch/releases/tag/hatchling-v0.8.2) - 2022-01-16 ### {: #hatchling-v0.8.2 }
8185

8286
***Fixed:***
File renamed without changes.

tests/dep/test_core.py renamed to tests/backend/dep/test_core.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@ def test_version_unmet(platform):
2828
assert not dependencies_in_sync([Requirement('binary>9000')], venv.sys_path)
2929

3030

31+
def test_marker_met(platform):
32+
with TempVirtualEnv(sys.executable, platform) as venv:
33+
assert dependencies_in_sync([Requirement('binary; python_version < "1"')], venv.sys_path)
34+
35+
36+
def test_marker_unmet(platform):
37+
with TempVirtualEnv(sys.executable, platform) as venv:
38+
assert not dependencies_in_sync([Requirement('binary; python_version > "1"')], venv.sys_path)
39+
40+
3141
def test_extra_no_dependencies(platform):
3242
with TempVirtualEnv(sys.executable, platform) as venv:
3343
platform.run_command(['pip', 'install', 'binary'], check=True, capture_output=True)

0 commit comments

Comments
 (0)