Skip to content

Commit d933a54

Browse files
committed
Fix hbutils snippet for transitive non-extra deps
1 parent 6d0535d commit d933a54

File tree

1 file changed

+15
-10
lines changed

1 file changed

+15
-10
lines changed

source/guides/handling-missing-extras-at-runtime.rst

+15-10
Original file line numberDiff line numberDiff line change
@@ -56,22 +56,25 @@ recursively and check whether all are installed in the current environment
5656

5757
.. code-block:: python
5858
59-
# TODO Unless we get special permission, this snippet is Apache-2-licensed:
59+
# Adapted from (see there for copyright & license):
6060
# https://github.com/HansBug/hbutils/blob/927b0757449a781ce8e30132f26b06089a24cd71/LICENSE
61+
# SPDX-License-Identifier: Apache-2.0
6162
6263
from collections.abc import Iterable
6364
from importlib.metadata import PackageNotFoundError, distribution, metadata
6465
65-
from packaging.metadata import Metadata
66+
from packaging.metadata import Metadata, RawMetadata
6667
from packaging.requirements import Requirement
6768
69+
6870
def check_reqs(req_strs: Iterable[str]) -> bool:
6971
return all(
7072
_check_req_recursive(req)
7173
for req_str in req_strs
7274
if not (req := Requirement(req_str)).marker or req.marker.evaluate()
7375
)
7476
77+
7578
def _check_req_recursive(req: Requirement) -> bool:
7679
try:
7780
version = distribution(req.name).version
@@ -83,21 +86,23 @@ recursively and check whether all are installed in the current environment
8386
8487
req_metadata = Metadata.from_raw(metadata(req.name).json, validate=False)
8588
for child_req in req_metadata.requires_dist or []:
86-
for extra in req.extras:
87-
if child_req.marker and child_req.marker.evaluate({"extra": extra}):
88-
if not _check_req_recursive(child_req):
89-
return False
90-
break
89+
# A dependency is only required to be present if ...
90+
if (
91+
not child_req.marker # ... it doesn't have a marker
92+
or child_req.marker.evaluate() # ... its marker matches our env
93+
or any( # ... its marker matches our env given one of our extras
94+
child_req.marker.evaluate({"extra": extra}) for extra in req.extras
95+
)
96+
):
97+
if not _check_req_recursive(child_req):
98+
return False
9199
92100
return True
93101
94102
95103
# Perform check, e.g.:
96104
extra_installed = check_reqs(["your-package[your-extra]"])
97105
98-
TODO Either point out that this snippet doesn't actually check everything
99-
(https://github.com/HansBug/hbutils/issues/109) or fix it.
100-
101106
The possibility of offering a helper function similar to ``check_reqs`` in
102107
``importlib.metadata`` or ``packaging`` themselves is still being discussed
103108
(`packaging-problems #317 <packaging-problems-317_>`_).

0 commit comments

Comments
 (0)