Error when --script is passing a non-PEP 723 script (#11118)

## Summary

We now show a custom error if (1) the file doesn't exist at all, or (2)
it's not a PEP 723 script.

In the future, `uv lock --script` should probably initialize the script,
but that requires a more extensive refactor. At present, we just
silently lock the project instead, which is pretty bad!

Closes https://github.com/astral-sh/uv/issues/10979.
This commit is contained in:
Charlie Marsh 2025-01-30 15:49:59 -05:00 committed by GitHub
parent e0a19be825
commit bf9fe1d36d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 94 additions and 43 deletions

View file

@ -121,13 +121,11 @@ pub struct Pep723Script {
impl Pep723Script {
/// Read the PEP 723 `script` metadata from a Python file, if it exists.
///
/// Returns `None` if the file is missing a PEP 723 metadata block.
///
/// See: <https://peps.python.org/pep-0723/>
pub async fn read(file: impl AsRef<Path>) -> Result<Option<Self>, Pep723Error> {
let contents = match fs_err::tokio::read(&file).await {
Ok(contents) => contents,
Err(err) if err.kind() == io::ErrorKind::NotFound => return Ok(None),
Err(err) => return Err(err.into()),
};
let contents = fs_err::tokio::read(&file).await?;
// Extract the `script` tag.
let ScriptTag {
@ -286,13 +284,11 @@ impl Pep723Metadata {
/// Read the PEP 723 `script` metadata from a Python file, if it exists.
///
/// Returns `None` if the file is missing a PEP 723 metadata block.
///
/// See: <https://peps.python.org/pep-0723/>
pub async fn read(file: impl AsRef<Path>) -> Result<Option<Self>, Pep723Error> {
let contents = match fs_err::tokio::read(&file).await {
Ok(contents) => contents,
Err(err) if err.kind() == io::ErrorKind::NotFound => return Ok(None),
Err(err) => return Err(err.into()),
};
let contents = fs_err::tokio::read(&file).await?;
// Extract the `script` tag.
let ScriptTag { metadata, .. } = match ScriptTag::parse(&contents) {
@ -341,6 +337,8 @@ pub struct ToolUv {
pub enum Pep723Error {
#[error("An opening tag (`# /// script`) was found without a closing tag (`# ///`). Ensure that every line between the opening and closing tags (including empty lines) starts with a leading `#`.")]
UnclosedBlock,
#[error("The PEP 723 metadata block is missing from the script.")]
MissingTag,
#[error(transparent)]
Io(#[from] io::Error),
#[error(transparent)]