mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-04 02:48:17 +00:00
Treat .pyw
files as scripts in uv run
on Windows (#6453)
Closes https://github.com/astral-sh/uv/issues/6435
This commit is contained in:
parent
cba329ee21
commit
99d278f9f5
2 changed files with 76 additions and 0 deletions
|
@ -722,6 +722,8 @@ enum RunCommand {
|
|||
Python(Vec<OsString>),
|
||||
/// Execute a `python` script.
|
||||
PythonScript(PathBuf, Vec<OsString>),
|
||||
/// Execute a `pythonw` script (Windows only).
|
||||
PythonGuiScript(PathBuf, Vec<OsString>),
|
||||
/// Execute an external command.
|
||||
External(OsString, Vec<OsString>),
|
||||
/// Execute an empty command (in practice, `python` with no arguments).
|
||||
|
@ -734,6 +736,7 @@ impl RunCommand {
|
|||
match self {
|
||||
Self::Python(_) => Cow::Borrowed("python"),
|
||||
Self::PythonScript(_, _) | Self::Empty => Cow::Borrowed("python"),
|
||||
Self::PythonGuiScript(_, _) => Cow::Borrowed("pythonw"),
|
||||
Self::External(executable, _) => executable.to_string_lossy(),
|
||||
}
|
||||
}
|
||||
|
@ -752,6 +755,25 @@ impl RunCommand {
|
|||
process.args(args);
|
||||
process
|
||||
}
|
||||
Self::PythonGuiScript(target, args) => {
|
||||
let python_executable = interpreter.sys_executable();
|
||||
|
||||
// Use `pythonw.exe` if it exists, otherwise fall back to `python.exe`.
|
||||
// See `install-wheel-rs::get_script_executable`.gd
|
||||
let pythonw_executable = python_executable
|
||||
.file_name()
|
||||
.map(|name| {
|
||||
let new_name = name.to_string_lossy().replace("python", "pythonw");
|
||||
python_executable.with_file_name(new_name)
|
||||
})
|
||||
.filter(|path| path.is_file())
|
||||
.unwrap_or_else(|| python_executable.to_path_buf());
|
||||
|
||||
let mut process = Command::new(&pythonw_executable);
|
||||
process.arg(target);
|
||||
process.args(args);
|
||||
process
|
||||
}
|
||||
Self::External(executable, args) => {
|
||||
let mut process = Command::new(executable);
|
||||
process.args(args);
|
||||
|
@ -779,6 +801,13 @@ impl std::fmt::Display for RunCommand {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
Self::PythonGuiScript(target, args) => {
|
||||
write!(f, "pythonw {}", target.display())?;
|
||||
for arg in args {
|
||||
write!(f, " {}", arg.to_string_lossy())?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Self::External(executable, args) => {
|
||||
write!(f, "{}", executable.to_string_lossy())?;
|
||||
for arg in args {
|
||||
|
@ -811,6 +840,13 @@ impl From<&ExternalCommand> for RunCommand {
|
|||
&& target_path.exists()
|
||||
{
|
||||
Self::PythonScript(target_path, args.to_vec())
|
||||
} else if cfg!(windows)
|
||||
&& target_path
|
||||
.extension()
|
||||
.is_some_and(|ext| ext.eq_ignore_ascii_case("pyw"))
|
||||
&& target_path.exists()
|
||||
{
|
||||
Self::PythonGuiScript(target_path, args.to_vec())
|
||||
} else {
|
||||
Self::External(
|
||||
target.clone(),
|
||||
|
|
|
@ -356,6 +356,46 @@ fn run_pep723_script() -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Run a `.pyw` script. The script should be executed with `pythonw.exe`.
|
||||
#[test]
|
||||
#[cfg(windows)]
|
||||
fn run_pythonw_script() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
let pyproject_toml = context.temp_dir.child("pyproject.toml");
|
||||
pyproject_toml.write_str(indoc! { r#"
|
||||
[project]
|
||||
name = "foo"
|
||||
version = "1.0.0"
|
||||
requires-python = ">=3.8"
|
||||
dependencies = ["anyio"]
|
||||
"#
|
||||
})?;
|
||||
|
||||
let test_script = context.temp_dir.child("main.pyw");
|
||||
test_script.write_str(indoc! { r"
|
||||
import anyio
|
||||
"
|
||||
})?;
|
||||
|
||||
uv_snapshot!(context.filters(), context.run().arg("--preview").arg("main.pyw"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 6 packages in [TIME]
|
||||
Prepared 4 packages in [TIME]
|
||||
Installed 4 packages in [TIME]
|
||||
+ anyio==4.3.0
|
||||
+ foo==1.0.0 (from file://[TEMP_DIR]/)
|
||||
+ idna==3.6
|
||||
+ sniffio==1.3.1
|
||||
"###);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Run a PEP 723-compatible script with `tool.uv` metadata.
|
||||
#[test]
|
||||
fn run_pep723_script_metadata() -> Result<()> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue