Allow reading --with-requirements from stdin in uv add and uv run (#10447)

For some reason this was banned when originally added (I did not see
discussion about it). I think it's fine to allow. With `uv run`, there's
a bit of nuance because we also allow the script to be read from stdin.
This commit is contained in:
Zanie Blue
2025-01-09 16:39:37 -06:00
committed by GitHub
parent 129a75e2d0
commit 22222e945f
4 changed files with 62 additions and 9 deletions
-5
View File
@@ -98,11 +98,6 @@ pub(crate) async fn add(
RequirementsSource::SetupCfg(_) => {
bail!("Adding requirements from a `setup.cfg` is not supported in `uv add`");
}
RequirementsSource::RequirementsTxt(path) => {
if path == Path::new("-") {
bail!("Reading requirements from stdin is not supported in `uv add`");
}
}
_ => {}
}
}
+14 -1
View File
@@ -93,6 +93,7 @@ pub(crate) async fn run(
) -> anyhow::Result<ExitStatus> {
// These cases seem quite complex because (in theory) they should change the "current package".
// Let's ban them entirely for now.
let mut requirements_from_stdin: bool = false;
for source in &requirements {
match source {
RequirementsSource::PyprojectToml(_) => {
@@ -106,13 +107,22 @@ pub(crate) async fn run(
}
RequirementsSource::RequirementsTxt(path) => {
if path == Path::new("-") {
bail!("Reading requirements from stdin is not supported in `uv run`");
requirements_from_stdin = true;
}
}
_ => {}
}
}
// Fail early if stdin is used for multiple purposes.
if matches!(
command,
Some(RunCommand::PythonStdin(..) | RunCommand::PythonGuiStdin(..))
) && requirements_from_stdin
{
bail!("Cannot read both requirements file and script from stdin");
}
// Initialize any shared state.
let state = SharedState::default();
@@ -169,6 +179,9 @@ pub(crate) async fn run(
)?;
}
Pep723Item::Stdin(_) => {
if requirements_from_stdin {
bail!("Cannot read both requirements file and script from stdin");
}
writeln!(
printer.stderr(),
"Reading inline script metadata from `{}`",
+13
View File
@@ -1,3 +1,5 @@
#![allow(clippy::disallowed_types)]
use anyhow::Result;
use assert_cmd::assert::OutputAssertExt;
use assert_fs::prelude::*;
@@ -4611,6 +4613,17 @@ fn add_requirements_file() -> Result<()> {
);
});
// Passing stdin should succeed
uv_snapshot!(context.filters(), context.add().arg("-r").arg("-").stdin(std::fs::File::open(requirements_txt)?), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved [N] packages in [TIME]
Audited [N] packages in [TIME]
"###);
// Passing a `setup.py` should fail.
uv_snapshot!(context.filters(), context.add().arg("-r").arg("setup.py"), @r###"
success: false
+35 -3
View File
@@ -2124,19 +2124,51 @@ fn run_requirements_txt() -> Result<()> {
+ sniffio==1.3.1
"###);
// But reject `-` as a requirements file.
// Allow `-` for stdin.
uv_snapshot!(context.filters(), context.run()
.arg("--with-requirements")
.arg("-")
.arg("--with")
.arg("iniconfig")
.arg("main.py"), @r###"
.arg("main.py")
.stdin(std::fs::File::open(&requirements_txt)?), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 6 packages in [TIME]
Audited 4 packages in [TIME]
Resolved 2 packages in [TIME]
"###);
// But not in combination with reading the script from stdin
uv_snapshot!(context.filters(), context.run()
.arg("--with-requirements")
.arg("-")
// The script to run
.arg("-")
.stdin(std::fs::File::open(&requirements_txt)?), @r###"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
error: Reading requirements from stdin is not supported in `uv run`
error: Cannot read both requirements file and script from stdin
"###);
uv_snapshot!(context.filters(), context.run()
.arg("--with-requirements")
.arg("-")
.arg("--script")
.arg("-")
.stdin(std::fs::File::open(&requirements_txt)?), @r###"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
error: Cannot read both requirements file and script from stdin
"###);
Ok(())