Skip to content

refactor(bootstrapper): replace recursion with trampoline for iterative execution#1109

Open
rd4398 wants to merge 1 commit intopython-wheel-build:mainfrom
rd4398:implement-iterative-bootstrap
Open

refactor(bootstrapper): replace recursion with trampoline for iterative execution#1109
rd4398 wants to merge 1 commit intopython-wheel-build:mainfrom
rd4398:implement-iterative-bootstrap

Conversation

@rd4398
Copy link
Copy Markdown
Contributor

@rd4398 rd4398 commented May 4, 2026

This commit converts recursive bootstrap methods to generators using the trampoline library, eliminating Python's recursion depth limit for deep/wide dependency graphs.

trampoline source: https://gitlab.com/ferreum/trampoline

Closes: #1068

@rd4398 rd4398 requested a review from a team as a code owner May 4, 2026 18:39
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 4, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0f6092c2-3685-45dd-adaa-011f15cbe780

📥 Commits

Reviewing files that changed from the base of the PR and between c2f6fb6 and 1f7ac06.

📒 Files selected for processing (3)
  • pyproject.toml
  • src/fromager/bootstrapper.py
  • tests/test_bootstrapper.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • pyproject.toml
  • src/fromager/bootstrapper.py

📝 Walkthrough

Walkthrough

The bootstrap flow was converted from direct recursive calls to a generator-based, trampoline-driven model. bootstrap() now invokes self._bootstrap_gen(...) via trampoline(). Methods _bootstrap_gen, _bootstrap_single_version, _bootstrap_impl, _prepare_build_dependencies, _handle_build_requirements, and _build_from_source were changed to yield work and return generator types; call sites were updated to yield those generators. _get_version_from_package_metadata() now runs _prepare_build_dependencies() through trampoline(). pyproject.toml adds trampoline to dependencies and mypy overrides. Tests were adapted to run generators via trampoline() and to use generator-style mocks.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: converting recursive bootstrap methods to use the trampoline library for iterative execution.
Description check ✅ Passed The description is related to the changeset, explaining the conversion to generators using trampoline to eliminate recursion depth limits.
Linked Issues check ✅ Passed The PR addresses issue #1068 by converting recursive bootstrap methods to iterative execution using trampoline, eliminating recursion depth limits for deep dependency graphs.
Out of Scope Changes check ✅ Passed All changes are scoped to the bootstrap refactoring: adding trampoline dependency, converting methods to generators, and updating tests to use trampoline.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@mergify mergify Bot added the ci label May 4, 2026
Copy link
Copy Markdown
Member

@dhellmann dhellmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have to admit, this is a small clean change but I really had to study the trampoline code to make sense of how it works. I'm not sure how I feel about hiding the cleverness in another library vs. having a non-recursive depth-first traversal algorithm here in fromager.


def _bootstrap_gen(
self, req: Requirement, req_type: RequirementType
) -> typing.Generator[typing.Any, typing.Any, None]:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could be more specific with types here, instead of using typing.Any?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we cannot be more specific because of the way the way trampoline works

- YieldType — we yield child generators, but each yield site yields a different generator type, so a single precise type isn't possible within one method 
                                                                 
- SendType — the value received from yield depends on which child generator was yielded (e.g., SourceBuildResult from _build_from_source, None from _bootstrap_gen)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can still declare our type accurately, even if trampoline doesn't care, can't we?

Comment thread src/fromager/bootstrapper.py
@rd4398
Copy link
Copy Markdown
Contributor Author

rd4398 commented May 4, 2026

I have to admit, this is a small clean change but I really had to study the trampoline code to make sense of how it works. I'm not sure how I feel about hiding the cleverness in another library vs. having a non-recursive depth-first traversal algorithm here in fromager.

Yeah, I agree. I wonder whether we want to move back to implementing our plan for iterative bootstrap even though it is a significantly big change. @LalatenduMohanty what do you think? cc @tiran

@rd4398 rd4398 requested a review from LalatenduMohanty May 4, 2026 20:22
@dhellmann
Copy link
Copy Markdown
Member

I have to admit, this is a small clean change but I really had to study the trampoline code to make sense of how it works. I'm not sure how I feel about hiding the cleverness in another library vs. having a non-recursive depth-first traversal algorithm here in fromager.

Yeah, I agree. I wonder whether we want to move back to implementing our plan for iterative bootstrap even though it is a significantly big change. @LalatenduMohanty what do you think? cc @tiran

I'd be interested in seeing the change to compare them for readability.

@rd4398
Copy link
Copy Markdown
Contributor Author

rd4398 commented May 5, 2026

I have to admit, this is a small clean change but I really had to study the trampoline code to make sense of how it works. I'm not sure how I feel about hiding the cleverness in another library vs. having a non-recursive depth-first traversal algorithm here in fromager.

Yeah, I agree. I wonder whether we want to move back to implementing our plan for iterative bootstrap even though it is a significantly big change. @LalatenduMohanty what do you think? cc @tiran

I'd be interested in seeing the change to compare them for readability.

Ack, will submit the PR today with that implementation.

…ve execution

Convert recursive bootstrap methods to generators using the trampoline
library, eliminating Python's recursion depth limit for deep/wide
dependency graphs.

Co-Authored-By: Claude <claude@anthropic.com>
Signed-off-by: Rohan Devasthale <rdevasth@redhat.com>
@rd4398 rd4398 force-pushed the implement-iterative-bootstrap branch from c2f6fb6 to 1f7ac06 Compare May 5, 2026 17:49
@rd4398
Copy link
Copy Markdown
Contributor Author

rd4398 commented May 5, 2026

I have to admit, this is a small clean change but I really had to study the trampoline code to make sense of how it works. I'm not sure how I feel about hiding the cleverness in another library vs. having a non-recursive depth-first traversal algorithm here in fromager.

Yeah, I agree. I wonder whether we want to move back to implementing our plan for iterative bootstrap even though it is a significantly big change. @LalatenduMohanty what do you think? cc @tiran

I'd be interested in seeing the change to compare them for readability.

Ack, will submit the PR today with that implementation.

Done. @dhellmann @LalatenduMohanty #1116 is the alternative implementation. Please take a look when you have time

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Convert Bootstrapper from Recursive to Iterative

2 participants