Allow --with-requirements to load extensionless inline-metadata scripts (#16744)

Resolves https://github.com/astral-sh/uv/issues/16732

This diff treats extensionless files that contain
[PEP 723](https://peps.python.org/pep-0723/) metadata as scripts when
resolving `--with-requirements`, so inline metadata works even when the
script doesn’t end in `.py`.

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
This commit is contained in:
liam
2025-11-20 21:33:41 -05:00
committed by GitHub
parent b086eabe5f
commit f3cdfac93e
4 changed files with 117 additions and 45 deletions
+32 -21
View File
@@ -175,28 +175,16 @@ impl Pep723Script {
///
/// See: <https://peps.python.org/pep-0723/>
pub async fn read(file: impl AsRef<Path>) -> Result<Option<Self>, Pep723Error> {
let contents = fs_err::tokio::read(&file).await?;
let file = file.as_ref();
let contents = fs_err::tokio::read(file).await?;
Self::from_contents(file, &contents)
}
// Extract the `script` tag.
let ScriptTag {
prelude,
metadata,
postlude,
} = match ScriptTag::parse(&contents) {
Ok(Some(tag)) => tag,
Ok(None) => return Ok(None),
Err(err) => return Err(err),
};
// Parse the metadata.
let metadata = Pep723Metadata::from_str(&metadata)?;
Ok(Some(Self {
path: std::path::absolute(file)?,
metadata,
prelude,
postlude,
}))
/// Read the PEP 723 `script` metadata from a Python file using blocking I/O.
pub fn read_sync(file: impl AsRef<Path>) -> Result<Option<Self>, Pep723Error> {
let file = file.as_ref();
let contents = fs_err::read(file)?;
Self::from_contents(file, &contents)
}
/// Reads a Python script and generates a default PEP 723 metadata table.
@@ -349,6 +337,29 @@ impl Pep723Script {
.and_then(|uv| uv.sources.as_ref())
.unwrap_or(&EMPTY)
}
fn from_contents(path: &Path, contents: &[u8]) -> Result<Option<Self>, Pep723Error> {
let script_tag = match ScriptTag::parse(contents) {
Ok(Some(tag)) => tag,
Ok(None) => return Ok(None),
Err(err) => return Err(err),
};
let ScriptTag {
prelude,
metadata,
postlude,
} = script_tag;
let metadata = Pep723Metadata::from_str(&metadata)?;
Ok(Some(Self {
path: std::path::absolute(path)?,
metadata,
prelude,
postlude,
}))
}
}
/// PEP 723 metadata as parsed from a `script` comment block.