Skip to content

Commit e4ef7ca

Browse files
authored
Merge pull request #694 from dhellmann/clarify-dependency-adding
fix: fix install dependency tracking
2 parents 57b0fb7 + a92e6c8 commit e4ef7ca

File tree

3 files changed

+64
-15
lines changed

3 files changed

+64
-15
lines changed

src/fromager/bootstrapper.py

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,34 @@ def resolve_version(
9292
)
9393
return source_url, resolved_version
9494

95+
def _processing_build_requirement(self, current_req_type: RequirementType) -> bool:
96+
"""Are we currently processing a build requirement?
97+
98+
We determine that a package is a build dependency if its requirement
99+
type is build_system, build_backend, or build_sdist OR if it is an
100+
installation requirement of something that is a build dependency. We
101+
use a verbose loop to determine the status so we can log the reason
102+
something is treated as a build dependency.
103+
"""
104+
if current_req_type.is_build_requirement:
105+
logger.debug(f"is itself a build requirement: {current_req_type}")
106+
return True
107+
if not current_req_type.is_install_requirement:
108+
logger.debug(
109+
"is not an install requirement, not checking dependency chain for a build requirement"
110+
)
111+
return False
112+
for req_type, req, resolved_version in reversed(self.why):
113+
if req_type.is_build_requirement:
114+
logger.debug(
115+
f"is a build requirement because {req_type} dependency {req} ({resolved_version}) depends on it"
116+
)
117+
return True
118+
logger.debug("is not a build requirement")
119+
return False
120+
95121
def bootstrap(self, req: Requirement, req_type: RequirementType) -> Version:
122+
logger.info(f"bootstrapping {req} as {req_type} dependency of {self.why[-1:]}")
96123
constraint = self.ctx.constraints.get_constraint(req.name)
97124
if constraint:
98125
logger.info(
@@ -108,14 +135,18 @@ def bootstrap(self, req: Requirement, req_type: RequirementType) -> Version:
108135
self._add_to_graph(req, req_type, resolved_version, source_url)
109136

110137
# Is bootstrap going to create a wheel or just an sdist?
138+
#
111139
# Use fast sdist-only if flag is set and requirement is not a build
112140
# requirement.
113-
# An install requirement on a pre-built wheel treats the
114-
# wheel as sdist-only in order to build its installation requirements
115-
# sdist-only. When bootstrap encounters another package with a
116-
# *build* requirement on a pre-built wheel, its installation
117-
# dependencies are materialized.
118-
build_sdist_only = self.sdist_only and req_type.is_install_requirement
141+
#
142+
# An install requirement on a pre-built wheel treats the wheel as
143+
# sdist-only in order to build its installation requirements sdist-only.
144+
#
145+
# When bootstrap encounters another package with a *build* requirement
146+
# on a pre-built wheel, its installation dependencies are materialized.
147+
build_sdist_only = self.sdist_only and not self._processing_build_requirement(
148+
req_type
149+
)
119150

120151
# Avoid cyclic dependencies and redundant processing.
121152
if self._has_been_seen(req, resolved_version, build_sdist_only):
@@ -303,19 +334,12 @@ def bootstrap(self, req: Requirement, req_type: RequirementType) -> Version:
303334
prebuilt=pbi.pre_built,
304335
constraint=constraint,
305336
)
306-
if req_type.is_build_requirement:
307-
# install dependencies of build requirements are also build
308-
# system requirements.
309-
child_req_type = RequirementType.BUILD_SYSTEM
310-
else:
311-
# top-level and install requirements
312-
child_req_type = RequirementType.INSTALL
313337

314338
self.progressbar.update_total(len(install_dependencies))
315339
for dep in self._sort_requirements(install_dependencies):
316340
with req_ctxvar_context(dep):
317341
try:
318-
self.bootstrap(req=dep, req_type=child_req_type)
342+
self.bootstrap(req=dep, req_type=RequirementType.INSTALL)
319343
except Exception as err:
320344
raise ValueError(f"could not handle {self._explain}") from err
321345
self.progressbar.update()

src/fromager/dependency_graph.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ def add_dependency(
215215
pre_built: bool = False,
216216
) -> None:
217217
logger.debug(
218-
"recording %s %s dependency %s -> %s %s",
218+
"recording %s dependency %s%s -> %s==%s",
219219
req_type,
220220
parent_name if parent_name else f"({RequirementType.TOP_LEVEL})",
221221
f"=={parent_version}" if parent_version else "",

tests/test_bootstrapper.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,3 +403,28 @@ def test_explain(tmp_context: WorkContext):
403403
bt._explain
404404
== f"{RequirementType.BUILD_SYSTEM} dependency bar==4.0.0 (4.0.0) for {RequirementType.TOP_LEVEL} dependency foo (1.0.0)"
405405
)
406+
407+
408+
def test_is_build_requirement(tmp_context: WorkContext):
409+
bt = bootstrapper.Bootstrapper(tmp_context, None, old_graph)
410+
bt.why = []
411+
assert not bt._processing_build_requirement(RequirementType.TOP_LEVEL)
412+
assert bt._processing_build_requirement(RequirementType.BUILD_SYSTEM)
413+
assert bt._processing_build_requirement(RequirementType.BUILD_BACKEND)
414+
assert bt._processing_build_requirement(RequirementType.BUILD_SDIST)
415+
assert not bt._processing_build_requirement(RequirementType.INSTALL)
416+
417+
bt.why = [(RequirementType.TOP_LEVEL, Requirement("foo"), Version("1.0.0"))]
418+
assert not bt._processing_build_requirement(RequirementType.INSTALL)
419+
assert bt._processing_build_requirement(RequirementType.BUILD_SYSTEM)
420+
assert bt._processing_build_requirement(RequirementType.BUILD_BACKEND)
421+
assert bt._processing_build_requirement(RequirementType.BUILD_SDIST)
422+
423+
bt.why = [
424+
(RequirementType.TOP_LEVEL, Requirement("foo"), Version("1.0.0")),
425+
(RequirementType.BUILD_SYSTEM, Requirement("bar==4.0.0"), Version("4.0.0")),
426+
]
427+
assert bt._processing_build_requirement(RequirementType.INSTALL)
428+
assert bt._processing_build_requirement(RequirementType.BUILD_SYSTEM)
429+
assert bt._processing_build_requirement(RequirementType.BUILD_BACKEND)
430+
assert bt._processing_build_requirement(RequirementType.BUILD_SDIST)

0 commit comments

Comments
 (0)