Consider pythonw when copying entrypoints in uv run (#15134)

## Summary

Follow up from
https://github.com/astral-sh/uv/pull/15068#discussion_r2258586926

It seems when copying entrypoints we're ignoring whether it was pythonw
vs not.

## Test Plan

Updated existing test.
This commit is contained in:
samypr100
2025-08-07 11:06:03 -04:00
committed by GitHub
parent 7f1eaf48c1
commit abc68fc7c1
2 changed files with 78 additions and 1 deletions
+9 -1
View File
@@ -1937,7 +1937,15 @@ fn copy_entrypoint(
return Ok(());
};
let launcher = launcher.with_python_path(python_executable.to_path_buf());
let is_gui = launcher.python_path.ends_with("pythonw.exe");
let python_path = if is_gui {
python_executable.with_file_name("pythonw.exe")
} else {
python_executable.to_path_buf()
};
let launcher = launcher.with_python_path(python_path);
let mut file = fs_err::OpenOptions::new()
.create_new(true)
.write(true)
+69
View File
@@ -1344,6 +1344,9 @@ fn run_with_overlay_interpreter() -> Result<()> {
[project.scripts]
main = "foo:main"
[project.gui-scripts]
main_gui = "foo:main_gui"
"#
})?;
@@ -1362,10 +1365,19 @@ fn run_with_overlay_interpreter() -> Result<()> {
base = Path(sys.executable)
shutil.copyfile(base.with_name("main").with_suffix(base.suffix), sys.argv[1])
def copy_gui_entrypoint():
base = Path(sys.executable)
shutil.copyfile(base.with_name("main_gui").with_suffix(base.suffix), sys.argv[1])
def main():
show_python()
if len(sys.argv) > 1:
copy_entrypoint()
def main_gui():
show_python()
if len(sys.argv) > 1:
copy_gui_entrypoint()
"#
})?;
@@ -1390,6 +1402,20 @@ fn run_with_overlay_interpreter() -> Result<()> {
+ iniconfig==2.0.0
");
// The project's gui entrypoint should be rewritten to use the overlay interpreter.
#[cfg(windows)]
uv_snapshot!(context.filters(), context.run().arg("--with").arg("iniconfig").arg("main_gui").arg(context.temp_dir.child("main_gui").as_os_str()), @r"
success: true
exit_code: 0
----- stdout -----
[CACHE_DIR]/builds-v0/[TMP]/pythonw
----- stderr -----
Resolved 6 packages in [TIME]
Audited 4 packages in [TIME]
Resolved 1 package in [TIME]
");
#[cfg(unix)]
insta::with_settings!({
filters => context.filters(),
@@ -1439,9 +1465,26 @@ fn run_with_overlay_interpreter() -> Result<()> {
+ sniffio==1.3.1
");
// When layering the project on top (via `--with`), the overlay gui interpreter also should be used.
#[cfg(windows)]
uv_snapshot!(context.filters(), context.run().arg("--no-project").arg("--gui-script").arg("--with").arg(".").arg("main_gui"), @r"
success: true
exit_code: 0
----- stdout -----
[CACHE_DIR]/builds-v0/[TMP]/pythonw
----- stderr -----
Resolved 4 packages in [TIME]
");
// Switch to a relocatable virtual environment.
context.venv().arg("--relocatable").assert().success();
// Cleanup previous shutil
fs_err::remove_file(context.temp_dir.child("main"))?;
#[cfg(windows)]
fs_err::remove_file(context.temp_dir.child("main_gui"))?;
// The project's entrypoint should be rewritten to use the overlay interpreter.
uv_snapshot!(context.filters(), context.run().arg("--with").arg("iniconfig").arg("main").arg(context.temp_dir.child("main").as_os_str()), @r"
success: true
@@ -1455,6 +1498,20 @@ fn run_with_overlay_interpreter() -> Result<()> {
Resolved 1 package in [TIME]
");
// The project's gui entrypoint should be rewritten to use the overlay interpreter.
#[cfg(windows)]
uv_snapshot!(context.filters(), context.run().arg("--with").arg("iniconfig").arg("main_gui").arg(context.temp_dir.child("main_gui").as_os_str()), @r"
success: true
exit_code: 0
----- stdout -----
[CACHE_DIR]/builds-v0/[TMP]/pythonw
----- stderr -----
Resolved 6 packages in [TIME]
Audited 4 packages in [TIME]
Resolved 1 package in [TIME]
");
// The package, its dependencies, and the overlay dependencies should be available.
context
.run()
@@ -1498,6 +1555,18 @@ fn run_with_overlay_interpreter() -> Result<()> {
Resolved 4 packages in [TIME]
");
// When layering the project on top (via `--with`), the overlay gui interpreter also should be used.
#[cfg(windows)]
uv_snapshot!(context.filters(), context.run().arg("--no-project").arg("--gui-script").arg("--with").arg(".").arg("main_gui"), @r"
success: true
exit_code: 0
----- stdout -----
[CACHE_DIR]/builds-v0/[TMP]/pythonw
----- stderr -----
Resolved 4 packages in [TIME]
");
Ok(())
}