Skip to content
Merged
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
14 changes: 8 additions & 6 deletions crates/uv-build-frontend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -921,13 +921,15 @@ impl PythonRunner {
) -> Result<PythonRunnerOutput, Error> {
/// Read lines from a reader and store them in a buffer.
async fn read_from(
mut reader: tokio::io::Lines<tokio::io::BufReader<impl tokio::io::AsyncRead + Unpin>>,
mut reader: tokio::io::Split<tokio::io::BufReader<impl tokio::io::AsyncRead + Unpin>>,
mut printer: Printer,
buffer: &mut Vec<String>,
) -> io::Result<()> {
loop {
match reader.next_line().await? {
Some(line) => {
match reader.next_segment().await? {
Some(line_buf) => {
let line_buf = line_buf.strip_suffix(b"\r").unwrap_or(&line_buf);
let line = String::from_utf8_lossy(line_buf).into();
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.

I do think bstr would be better for this, and would suggest using it (since we already depend on it, albeit transitively, in uv), but my memory here is that we need to write valid UTF-8. So while bstr wouldn't require this "lossy" step, I believe writing to the underlying stderr would still require valid UTF-8 anyway. So bstr would just absolve you of needing to handle line iteration, but I think this is fine as-is.

let _ = write!(printer, "{line}");
buffer.push(line);
}
Expand All @@ -945,7 +947,7 @@ impl PythonRunner {
.env("PATH", modified_path)
.env("VIRTUAL_ENV", venv.root())
.env("CLICOLOR_FORCE", "1")
.env("PYTHONIOENCODING", "utf-8")
.env("PYTHONIOENCODING", "utf-8:backslashreplace")
.stdout(std::process::Stdio::piped())
.stderr(std::process::Stdio::piped())
.spawn()
Expand All @@ -956,8 +958,8 @@ impl PythonRunner {
let mut stderr_buf = Vec::with_capacity(1024);

// Create separate readers for `stdout` and `stderr`.
let stdout_reader = tokio::io::BufReader::new(child.stdout.take().unwrap()).lines();
let stderr_reader = tokio::io::BufReader::new(child.stderr.take().unwrap()).lines();
let stdout_reader = tokio::io::BufReader::new(child.stdout.take().unwrap()).split(b'\n');
let stderr_reader = tokio::io::BufReader::new(child.stderr.take().unwrap()).split(b'\n');
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.

First thought upon seeing this was thinking, "but what about \r?" But it looks like you handled that above. Nice. :-)


// Asynchronously read from the in-memory pipes.
let printer = Printer::from(self.level);
Expand Down