Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a trampoline variant that just executes python #8637

Merged
merged 8 commits into from
Oct 29, 2024
Merged

Conversation

zanieb
Copy link
Member

@zanieb zanieb commented Oct 28, 2024

Currently, our trampoline is used to convert <command> [args] to python <command> [args] for script entrypoints installed into virtual environments. For #8458, it'd be nice to convert a shim python3.12 [args] to python [args]. Here, we modify the trampolines to support this use-case.

The only change we really need here is to avoid injecting <command> into the child process. We change the "magic number" at the end of the trampoline executables from UVUV to UVSC and UVPY which define "script" and "python" variants to the trampoline. We then omit the <command> injection in the latter case. We also omit writing the zip script payload when constructing the trampoline.

To support construction of the new variant, a new uv-trampoline-builder crate is introduced — this avoids requirements on uv-install-wheel in future work. I also use uv-trampoline-builder to consolidate some of the test setup for uv-trampoline.

There should be no backwards compatibility concerns, since trampolines are fully self-referential.

I rebased to fix the commits at the end, as this took many iterations to get working via CI. This should roughly be reviewable by commit if you prefer.

@zanieb zanieb force-pushed the zb/bounce-python branch 3 times, most recently from 4084c76 to 868c15a Compare October 28, 2024 18:01
@zanieb zanieb temporarily deployed to uv-test-publish October 28, 2024 18:13 — with GitHub Actions Inactive
@zanieb zanieb temporarily deployed to uv-test-publish October 28, 2024 18:48 — with GitHub Actions Inactive
@zanieb zanieb temporarily deployed to uv-test-publish October 28, 2024 18:55 — with GitHub Actions Inactive
@zanieb zanieb temporarily deployed to uv-test-publish October 28, 2024 19:07 — with GitHub Actions Inactive
@zanieb zanieb temporarily deployed to uv-test-publish October 28, 2024 19:14 — with GitHub Actions Inactive
@zanieb zanieb temporarily deployed to uv-test-publish October 28, 2024 19:25 — with GitHub Actions Inactive
@zanieb zanieb requested review from konstin and BurntSushi October 28, 2024 19:30
@zanieb zanieb marked this pull request as ready for review October 28, 2024 19:38
///
/// <https://github.com/pypa/pip/blob/fd0ea6bc5e8cb95e518c23d901c26ca14db17f89/src/pip/_vendor/distlib/scripts.py#L248-L262>
#[allow(unused_variables)]
pub(crate) fn windows_script_launcher(
Copy link
Member Author

Choose a reason for hiding this comment

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

This moved ~unchanged into uv-trampoline-builder

@@ -1075,54 +969,6 @@ mod test {
Ok(())
}

#[test]
#[cfg(all(windows, target_arch = "x86"))]
fn test_launchers_are_small() {
Copy link
Member Author

Choose a reason for hiding this comment

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

This moved into uv-trampoline-builder, size limit bumped


#[cfg(all(test, windows))]
#[allow(clippy::print_stdout)]
mod test {
Copy link
Member Author

Choose a reason for hiding this comment

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

These tests pulled from uv-trampoline::tests::harness and uv-install-wheel

///
/// Sort of equivalent to a `python` symlink on Unix.
#[allow(unused_variables)]
pub fn windows_python_launcher(
Copy link
Member Author

Choose a reason for hiding this comment

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

This is new

///
/// <https://github.com/pypa/pip/blob/fd0ea6bc5e8cb95e518c23d901c26ca14db17f89/src/pip/_vendor/distlib/scripts.py#L248-L262>
#[allow(unused_variables)]
pub fn windows_script_launcher(
Copy link
Member Author

Choose a reason for hiding this comment

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

This was copied ~unchanged

@@ -1,269 +0,0 @@
use std::io::{Cursor, Write};
Copy link
Member Author

Choose a reason for hiding this comment

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

This moved ~unchanged into uv-trampoline-builder

@zanieb zanieb temporarily deployed to uv-test-publish October 28, 2024 20:47 — with GitHub Actions Inactive
@zanieb zanieb changed the title Add a trampoline variant that executes python Add a trampoline variant that just executes python Oct 28, 2024
@samypr100
Copy link
Collaborator

samypr100 commented Oct 28, 2024

The trampolines increased from ~45kb to ~80kb

Weird, I noticed none of the code added should've increased it this much

Decided to build it locally (release) it's still in the ~45kb. We should probably update the sizes test to keep using the release build size, not the dev size 😅

bounce_build

Dev Sizes were about ~80kb

@zanieb
Copy link
Member Author

zanieb commented Oct 28, 2024

Ohhh I see what's happening here. I was also surprised they increased in size. Thanks for pointing that out. That's... annoying to fix.

Copy link
Member

@BurntSushi BurntSushi left a comment

Choose a reason for hiding this comment

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

LGTM. How did you resolve the test failures from yesterday?

Self::Script => &[b'U', b'V', b'S', b'C'],
Self::Python => &[b'U', b'V', b'P', b'Y'],
Self::Script => b"UVSC",
Self::Python => b"UVPY",
Copy link
Member

Choose a reason for hiding this comment

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

Ah whoops, you already did this. :P

Copy link
Member Author

Choose a reason for hiding this comment

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

Sorry; this is one of those things that wasn't worth moving in the rebase since it was a mess

assert!(
super::LAUNCHER_I686_GUI.len() < 45 * 1024,
super::LAUNCHER_I686_GUI.len() < 80 * 1024,
Copy link
Member

Choose a reason for hiding this comment

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

Would using cfg(not(debug_assertions)) as a proxy for "compiling with optimizations" help here? Otherwise, you can't cfg on opt-level at present. So probably the only alternative is a Cargo feature. (Assuming I'm understanding the problem correctly.)

Copy link
Member Author

Choose a reason for hiding this comment

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

That'd be interesting. I can also just.. run these tests separately from the ones we run to test changes to the trampolines. In CI, we replace the production trampolines with a debug build.

Copy link
Member

Choose a reason for hiding this comment

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

Is the threshold bump still relevant? In the git diff it looks like the binaries even shrank a little

Copy link
Member Author

Choose a reason for hiding this comment

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

Since I moved the tests, they run against the debug builds we create for testing.

I can fix that somehow, or we can just assert on the size of the debug builds (80kb is still very reasonable).

Copy link
Member Author

Choose a reason for hiding this comment

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

@zanieb
Copy link
Member Author

zanieb commented Oct 29, 2024

@BurntSushi I resolved the test failures by moving the tests from uv-trampoline/src/lib.rs into uv-trampoline-builder/src/lib.rs. Still no idea what was going on there.

@zanieb zanieb temporarily deployed to uv-test-publish October 29, 2024 14:19 — with GitHub Actions Inactive
@zanieb
Copy link
Member Author

zanieb commented Oct 29, 2024

Now we test both explicitly

Screenshot 2024-10-29 at 9 19 54 AM

@zanieb
Copy link
Member Author

zanieb commented Oct 29, 2024

Thanks for the reviews!

@zanieb zanieb merged commit c335dc5 into main Oct 29, 2024
63 checks passed
@zanieb zanieb deleted the zb/bounce-python branch October 29, 2024 14:21
@zanieb zanieb added the internal A refactor or improvement that is not user-facing label Oct 29, 2024
zanieb added a commit that referenced this pull request Oct 29, 2024
Currently, our trampoline is used to convert `<command> [args]` to
`python <command> [args]` for script entrypoints installed into virtual
environments. For #8458, it'd be nice to convert a shim `python3.12
[args]` to `python [args]`. Here, we modify the trampolines to support
this use-case.

The only change we really need here is to avoid injecting `<command>`
into the child process. We change the "magic number" at the end of the
trampoline executables from `UVUV` to `UVSC` and `UVPY` which define
"script" and "python" variants to the trampoline. We then omit the
`<command>` injection in the latter case. We also omit writing the zip
script payload.

To support construction of the new variant, a new
`uv-trampoline-builder` crate is introduced — this avoids requirements
on `uv-install-wheel` in future work. I also use `uv-trampoline-builder`
to consolidate some of the test setup for `uv-trampoline`.

There should be no backwards compatibility concerns, since trampolines
are fully self-referential.

I rebased to fix the commits at the end, as this took many iterations to
get working via CI. This should roughly be reviewable by commit if you
prefer.
zanieb added a commit that referenced this pull request Oct 31, 2024
…8663)

Incorporating #8637 into #8458 

- Adds `python-managed` feature selection to Windows CI for `python
install` tests
- Adds trampoline sniffing utilities to `uv-trampoline-builder`
- Uses a trampoline to install Python executables into the `PATH` on
Windows
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
internal A refactor or improvement that is not user-facing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants