mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-02 04:48:18 +00:00
Hint at missing project.name (#6803)
We got user reports where users were confused about why they can't use `[project.urls]` in `pyproject.toml` (i think that's from poetry?). This PR adds a hint that (according to PEP 621), you need to set `project.name` when using any `project` fields. (PEP 621 also requires `project.version` xor `dynamic = ["version"]`, but we check that later.) The intermediate parsing layer to tell apart syntax errors from schema errors doesn't incur a performance penalty according to epage (https://github.com/toml-rs/toml/issues/778#issuecomment-2310369253). Closes #6419 Closes #6760
This commit is contained in:
parent
3d62154849
commit
4aad89cf06
11 changed files with 132 additions and 13 deletions
|
|
@ -29,6 +29,7 @@ rkyv = { workspace = true }
|
|||
serde = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
toml = { workspace = true }
|
||||
toml_edit = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
url = { workspace = true }
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use std::str::FromStr;
|
|||
use indexmap::IndexMap;
|
||||
use itertools::Itertools;
|
||||
use mailparse::{MailHeaderMap, MailParseError};
|
||||
use serde::de::IntoDeserializer;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
use tracing::warn;
|
||||
|
|
@ -44,8 +45,12 @@ pub struct Metadata23 {
|
|||
pub enum MetadataError {
|
||||
#[error(transparent)]
|
||||
MailParse(#[from] MailParseError),
|
||||
#[error("Invalid `pyproject.toml`")]
|
||||
InvalidPyprojectTomlSyntax(#[source] toml_edit::TomlError),
|
||||
#[error("`pyproject.toml` is using the `[project]` table, but the required `project.name` is not set.")]
|
||||
InvalidPyprojectTomlMissingName(#[source] toml_edit::de::Error),
|
||||
#[error(transparent)]
|
||||
Toml(#[from] toml::de::Error),
|
||||
InvalidPyprojectTomlSchema(toml_edit::de::Error),
|
||||
#[error("metadata field {0} not found")]
|
||||
FieldNotFound(&'static str),
|
||||
#[error("invalid version: {0}")]
|
||||
|
|
@ -196,7 +201,7 @@ impl Metadata23 {
|
|||
|
||||
/// Extract the metadata from a `pyproject.toml` file, as specified in PEP 621.
|
||||
pub fn parse_pyproject_toml(contents: &str) -> Result<Self, MetadataError> {
|
||||
let pyproject_toml: PyProjectToml = toml::from_str(contents)?;
|
||||
let pyproject_toml = PyProjectToml::from_toml(contents)?;
|
||||
|
||||
let project = pyproject_toml
|
||||
.project
|
||||
|
|
@ -279,6 +284,23 @@ struct PyProjectToml {
|
|||
tool: Option<Tool>,
|
||||
}
|
||||
|
||||
impl PyProjectToml {
|
||||
fn from_toml(toml: &str) -> Result<Self, MetadataError> {
|
||||
let pyproject_toml: toml_edit::ImDocument<_> = toml_edit::ImDocument::from_str(toml)
|
||||
.map_err(MetadataError::InvalidPyprojectTomlSyntax)?;
|
||||
let pyproject_toml: Self = PyProjectToml::deserialize(pyproject_toml.into_deserializer())
|
||||
.map_err(|err| {
|
||||
// TODO(konsti): A typed error would be nicer, this can break on toml upgrades.
|
||||
if err.message().contains("missing field `name`") {
|
||||
MetadataError::InvalidPyprojectTomlMissingName(err)
|
||||
} else {
|
||||
MetadataError::InvalidPyprojectTomlSchema(err)
|
||||
}
|
||||
})?;
|
||||
Ok(pyproject_toml)
|
||||
}
|
||||
}
|
||||
|
||||
/// PEP 621 project metadata.
|
||||
///
|
||||
/// This is a subset of the full metadata specification, and only includes the fields that are
|
||||
|
|
@ -435,7 +457,7 @@ pub struct RequiresDist {
|
|||
impl RequiresDist {
|
||||
/// Extract the [`RequiresDist`] from a `pyproject.toml` file, as specified in PEP 621.
|
||||
pub fn parse_pyproject_toml(contents: &str) -> Result<Self, MetadataError> {
|
||||
let pyproject_toml: PyProjectToml = toml::from_str(contents)?;
|
||||
let pyproject_toml = PyProjectToml::from_toml(contents)?;
|
||||
|
||||
let project = pyproject_toml
|
||||
.project
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue