Retain trailing comments after PEP 723 metadata block (#13460)

## Summary

Closes https://github.com/astral-sh/uv/issues/13447.
This commit is contained in:
Charlie Marsh
2025-05-14 17:54:20 -04:00
committed by GitHub
parent 395039afd1
commit b326bb92a0
2 changed files with 74 additions and 9 deletions
+7 -9
View File
@@ -455,14 +455,9 @@ impl ScriptTag {
// > consists of only a single #).
let mut toml = vec![];
// Extract the content that follows the metadata block.
let mut python_script = vec![];
while let Some(line) = lines.next() {
for line in lines {
// Remove the leading `#`.
let Some(line) = line.strip_prefix('#') else {
python_script.push(line);
python_script.extend(lines);
break;
};
@@ -474,8 +469,6 @@ impl ScriptTag {
// Otherwise, the line _must_ start with ` `.
let Some(line) = line.strip_prefix(' ') else {
python_script.push(line);
python_script.extend(lines);
break;
};
@@ -517,7 +510,12 @@ impl ScriptTag {
// Join the lines into a single string.
let prelude = prelude.to_string();
let metadata = toml.join("\n") + "\n";
let postlude = python_script.join("\n") + "\n";
let postlude = contents
.lines()
.skip(index + 1)
.collect::<Vec<_>>()
.join("\n")
+ "\n";
Ok(Some(Self {
prelude,
+67
View File
@@ -5762,6 +5762,73 @@ fn add_script_settings() -> Result<()> {
Ok(())
}
#[test]
fn add_script_trailing_comment_lines() -> Result<()> {
let context = TestContext::new("3.12");
let script = context.temp_dir.child("script.py");
script.write_str(indoc! {r#"
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "requests<3",
# "rich",
# ]
# ///
#
# Additional description
import requests
from rich.pretty import pprint
resp = requests.get("https://peps.python.org/api/peps.json")
data = resp.json()
pprint([(k, v["title"]) for k, v in data.items()][:10])
"#})?;
uv_snapshot!(context.filters(), context.add().arg("anyio").arg("--script").arg("script.py"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Updated `script.py`
"###);
let script_content = context.read("script.py");
insta::with_settings!({
filters => context.filters(),
}, {
assert_snapshot!(
script_content, @r##"
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "anyio",
# "requests<3",
# "rich",
# ]
# ///
#
# Additional description
import requests
from rich.pretty import pprint
resp = requests.get("https://peps.python.org/api/peps.json")
data = resp.json()
pprint([(k, v["title"]) for k, v in data.items()][:10])
"##
);
});
// Adding to a script without a lockfile shouldn't create a lockfile.
assert!(!context.temp_dir.join("script.py.lock").exists());
Ok(())
}
/// Add to a script without an existing metadata table.
#[test]
fn add_script_without_metadata_table() -> Result<()> {