Skip to content

Commit 1109dac

Browse files
authored
Merge pull request #1047 from LalatenduMohanty/add_docstrings_non_trivial_code
docs: add docstrings and comments to complex functions
2 parents 297ed76 + 3c2c629 commit 1109dac

11 files changed

Lines changed: 103 additions & 5 deletions

src/fromager/bootstrapper.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1078,6 +1078,9 @@ def _look_for_existing_wheel(
10781078
if not wheel_filename:
10791079
return None, None
10801080

1081+
# Re-validate build tag from the actual wheel metadata because
1082+
# finders.find_wheel matches by filename prefix, which may not
1083+
# enforce an exact build tag match.
10811084
_, _, build_tag, _ = wheels.extract_info_from_wheel_file(req, wheel_filename)
10821085
if expected_build_tag and expected_build_tag != build_tag:
10831086
logger.info(
@@ -1185,7 +1188,12 @@ def _unpack_metadata_from_wheel(
11851188
return None
11861189

11871190
def _resolve_version_from_git_url(self, req: Requirement) -> tuple[str, Version]:
1188-
"Return path to the cloned git repository and the package version."
1191+
"""Resolve source path and version from a ``git+`` URL.
1192+
1193+
Parses the URL for an ``@ref`` version hint. If the ref is a valid
1194+
version, reuses an existing clone when possible. Otherwise, clones
1195+
the repo and extracts the version from package metadata.
1196+
"""
11891197

11901198
if not req.url:
11911199
raise ValueError(f"unable to resolve from URL with no URL in {req}")

src/fromager/dependencies.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ def _filter_requirements(
8181
for r in requirements:
8282
if not isinstance(r, Requirement):
8383
r = Requirement(r)
84+
# Use the parent's extras for marker evaluation because PEP 508
85+
# markers like `extra == "foo"` refer to the parent's install extras.
8486
if requirements_file.evaluate_marker(req, r, req.extras):
8587
requires.add(r)
8688
else:
@@ -529,7 +531,13 @@ def get_build_backend_hook_caller(
529531
build_env: build_environment.BuildEnvironment,
530532
log_filename: str | None = None,
531533
) -> pyproject_hooks.BuildBackendHookCaller:
532-
"""Create pyproject_hooks build backend caller"""
534+
"""Create a ``BuildBackendHookCaller`` with merged environment variables.
535+
536+
Environment variables are merged from three sources, where later
537+
sources override earlier ones: hook-provided ``extra_environ``,
538+
package-specific ``override_environ``, and ``build_env`` virtualenv
539+
variables.
540+
"""
533541

534542
def _run_hook_with_extra_environ(
535543
cmd: typing.Sequence[str],

src/fromager/dependency_graph.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ def _traverse_install_requirements(
169169
start_edges: list[DependencyEdge],
170170
visited: set[str],
171171
) -> typing.Iterable[DependencyEdge]:
172+
# Depth-first walk of install requirement edges, skipping nodes
173+
# already visited to avoid loops in the dependency graph.
172174
for edge in start_edges:
173175
if edge.key in visited:
174176
continue
@@ -220,6 +222,9 @@ def from_dict(
220222
graph_dict: dict[str, dict[str, typing.Any]],
221223
) -> DependencyGraph:
222224
graph = cls()
225+
# Stack-based DFS to reconstruct graph from serialized dict,
226+
# skipping nodes already visited to avoid processing shared
227+
# dependencies twice.
223228
stack = [ROOT]
224229
visited = set()
225230
while stack:

src/fromager/external_commands.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,13 @@ def run(
5858
log_filename: str | None = None,
5959
stdin: TextIOWrapper | None = None,
6060
) -> str:
61-
"""Call the subprocess while logging output"""
61+
"""Run a subprocess with optional network isolation and structured logging.
62+
63+
Captures output to a log file or in-memory pipe and prefixes each
64+
line with the current package name for easier searching. Raises
65+
``NetworkIsolationError`` instead of ``CalledProcessError`` when the
66+
failure output indicates a network access problem.
67+
"""
6268
if extra_environ is None:
6369
extra_environ = {}
6470
env = os.environ.copy()

src/fromager/finders.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@ def find_sdist(
4040
req: Requirement,
4141
dist_version: str,
4242
) -> pathlib.Path | None:
43+
"""Find an sdist archive in downloads_dir for the given requirement.
44+
45+
First checks for a plugin-provided exact filename. If no plugin match,
46+
tries four naming conventions (underscore-normalized, canonical, original,
47+
and dotted) with case-insensitive comparison to handle inconsistent
48+
sdist naming across the Python ecosystem. Case-insensitive globbing
49+
is not available before Python 3.12.
50+
"""
4351
sdist_file_name = overrides.find_and_invoke(
4452
req.name,
4553
"expected_source_archive_name",
@@ -95,6 +103,13 @@ def find_wheel(
95103
dist_version: str,
96104
build_tag: BuildTag = (),
97105
) -> pathlib.Path | None:
106+
"""Find a wheel file in downloads_dir for the given requirement.
107+
108+
Tries four naming conventions (PEP 427 transformed, canonical, original,
109+
and dotted), each suffixed with the build tag when present. Uses
110+
case-insensitive ``startswith`` matching rather than exact base comparison
111+
because wheel filenames include platform/Python tags after the version.
112+
"""
98113
filename_prefix = _dist_name_to_filename(req.name)
99114
canonical_name = canonicalize_name(req.name)
100115
# if build tag is 0 then we can ignore to handle non tagged wheels for backward compatibility
@@ -140,6 +155,15 @@ def find_source_dir(
140155
req: Requirement,
141156
dist_version: str,
142157
) -> pathlib.Path | None:
158+
"""Find the unpacked source directory for a requirement.
159+
160+
Tries three strategies in order:
161+
1. Plugin override providing the exact directory name
162+
2. Derive from the sdist archive name (strip extension), assuming the
163+
unpacked layout is ``<base>/<base>/`` (double-nested)
164+
3. Fall back to four naming conventions with case-insensitive matching,
165+
returning ``<match>/<match>/`` (same double-nested convention)
166+
"""
143167
sdir_name_func = overrides.find_override_method(
144168
req.name, "expected_source_directory_name"
145169
)

src/fromager/pyproject.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@ def _default_build_system(self, doc: tomlkit.TOMLDocument) -> TomlDict:
9393
return build_system
9494

9595
def _update_build_requires(self, build_system: TomlDict) -> None:
96+
"""Merge, remove, and deduplicate build requirements.
97+
98+
Starts with setuptools as a default, adds the existing requirements,
99+
removes unwanted ones, then applies updates. Only writes back if
100+
the resulting set differs from the original.
101+
"""
96102
old_requires = build_system[BUILD_REQUIRES]
97103
# always include setuptools
98104
req_map: dict[NormalizedName, list[Requirement]] = {

src/fromager/requirements_file.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ def evaluate_marker(
6565
if not extras:
6666
marker_envs = [default_env]
6767
else:
68+
# Evaluate once per extra because PEP 508 markers like `extra == "foo"`
69+
# can only match one extra value at a time.
6870
marker_envs = [default_env.copy() | {"extra": e} for e in extras]
6971

7072
for marker_env in marker_envs:

src/fromager/resolver.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,13 @@ def get_project_from_pypi(
222222
*,
223223
override_download_url: str | None = None,
224224
) -> Candidates:
225-
"""Return candidates created from the project name and extras."""
225+
"""Fetch and filter package candidates from a PyPI-compatible server.
226+
227+
Filters the project's package list by: project status, filename
228+
validity, package type (sdist/wheel), yanked status, Python version
229+
compatibility, and platform tags. Can substitute
230+
``override_download_url`` into each candidate's URL.
231+
"""
226232
found_candidates: set[str] = set()
227233
ignored_candidates: set[str] = set()
228234
logger.debug("%s: getting available versions from %s", project, sdist_server_url)
@@ -806,6 +812,13 @@ def cache_key(self) -> str:
806812
raise NotImplementedError("GenericProvider does not implement caching")
807813

808814
def find_candidates(self, identifier: typing.Any) -> Candidates:
815+
"""Find matching candidates from the version source.
816+
817+
Accepts three input formats from _version_source:
818+
1. Candidate objects (used directly)
819+
2. (url, Version) tuples
820+
3. (url, str) tuples (version parsed via _match_function)
821+
"""
809822
candidates: list[Candidate] = []
810823
version: Version | None
811824
for item in self._version_source(identifier):

src/fromager/sources.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,12 @@ def download_url(
295295
url: str,
296296
destination_filename: str | None = None,
297297
) -> pathlib.Path:
298+
"""Download a URL to destination_dir, returning the local path.
299+
300+
Returns immediately if the file already exists. Downloads to a
301+
temporary file first and renames it on success to avoid leaving
302+
partial files. Retries on transient network errors.
303+
"""
298304
basename = (
299305
destination_filename
300306
if destination_filename
@@ -500,6 +506,13 @@ def prepare_source(
500506
source_filename: pathlib.Path,
501507
version: Version,
502508
) -> pathlib.Path:
509+
"""Unpack and prepare source for building.
510+
511+
Git URL sources skip the plugin system and are prepared directly.
512+
Non-git sources go through ``find_and_invoke`` which may call a
513+
package-specific override. The plugin may return a ``Path`` or a
514+
``(Path, bool)`` tuple; both forms are handled.
515+
"""
503516
if req.url:
504517
logger.info(
505518
"preparing source cloned from %s into %s, ignoring any plugins",

src/fromager/vendor_rust.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def _cargo_shrink(crate_dir: pathlib.Path) -> None:
5656
for filename in crate_dir.glob(pattern):
5757
logger.debug("removing '%s'", filename.relative_to(crate_dir.parent))
5858
filename.unlink()
59-
filename.touch() # create empty file
59+
filename.touch() # keep empty placeholder so cargo doesn't error on missing files
6060
removed_files.append(str(filename.relative_to(crate_dir)))
6161

6262
# update checksums

0 commit comments

Comments
 (0)