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

Pipe input directly in uv run command #8301

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ tempfile = { version = "3.12.0" }
textwrap = { version = "0.16.1" }
thiserror = { version = "1.0.63" }
tl = { git = "https://github.com/charliermarsh/tl.git", rev = "6e25b2ee2513d75385101a8ff9f591ef51f314ec" }
tokio = { version = "1.40.0", features = ["fs", "io-util", "macros", "process", "signal", "sync"] }
tokio = { version = "1.40.0", features = ["fs", "io-util", "macros", "process", "signal", "sync", "io-std"] }
tokio-stream = { version = "0.1.16" }
tokio-util = { version = "0.7.12", features = ["compat"] }
toml = { version = "0.8.19" }
Expand Down
40 changes: 36 additions & 4 deletions crates/uv/src/commands/project/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ use std::borrow::Cow;
use std::collections::BTreeMap;
use std::ffi::OsString;
use std::fmt::Write;
use std::io::Read;
use std::io::{stdin, Read};
use std::path::{Path, PathBuf};
use std::process::Stdio; // for synchronous reading from stdin

use anstream::eprint;
use anyhow::{anyhow, bail, Context};
use futures::StreamExt;
use itertools::Itertools;
use owo_colors::OwoColorize;
use tokio::io::{self, AsyncWriteExt};
use tokio::process::Command;
use tracing::{debug, warn};
use url::Url;
Expand Down Expand Up @@ -1210,9 +1212,39 @@ impl RunCommand {
let is_dir = metadata.as_ref().map_or(false, std::fs::Metadata::is_dir);

if target.eq_ignore_ascii_case("-") {
let mut buf = Vec::with_capacity(1024);
std::io::stdin().read_to_end(&mut buf)?;
Ok(Self::PythonStdin(buf))
// Spawn the Python process with piped stdin
let mut child = Command::new("python3")
.stdin(Stdio::piped()) // Pipe parent's stdin to the child process
.stdout(Stdio::inherit()) // Use parent's stdout
.stderr(Stdio::inherit()) // Use parent's stderr
.spawn()?; // Spawn the child process

// If we successfully opened the child's stdin
if let Some(mut child_stdin) = child.stdin.take() {
// Spawning a blocking task to read stdin and send it to the child process
let buffer = tokio::task::spawn_blocking(move || {
let mut buffer = Vec::new();
stdin()
.read_to_end(&mut buffer)
.expect("Failed to read from stdin");
buffer
})
.await
.map_err(|e| {
io::Error::new(io::ErrorKind::Other, format!("Task join error: {}", e))
})?;

// Writing buffer to the child's stdin asynchronously
child_stdin.write_all(&buffer).await?;
}

// Waiting for the child process to finish
let status = child.wait().await?;
if !status.success() {
eprintln!("Python script failed with status: {:?}", status);
}

Ok(Self::PythonStdin(vec![]))
} else if target.eq_ignore_ascii_case("python") {
Ok(Self::Python(args.to_vec()))
} else if target_path
Expand Down
Loading