Unify poetry check types (#18260)

Found this duplication when looking at the toml parsing code.
This commit is contained in:
konsti
2026-03-03 19:13:01 +01:00
committed by GitHub
parent 74fe4a0431
commit 55cbe85d74
7 changed files with 31 additions and 58 deletions
Generated
-1
View File
@@ -6945,7 +6945,6 @@ dependencies = [
"fs-err",
"futures",
"rustc-hash",
"serde",
"thiserror 2.0.18",
"toml",
"tracing",
@@ -14,7 +14,7 @@ use crate::MetadataError;
#[serde(rename_all = "kebab-case")]
pub struct PyProjectToml {
pub project: Option<Project>,
pub(super) tool: Option<Tool>,
pub tool: Option<Tool>,
}
impl PyProjectToml {
@@ -80,11 +80,12 @@ impl TryFrom<PyprojectTomlWire> for Project {
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "kebab-case")]
pub(super) struct Tool {
pub(super) poetry: Option<ToolPoetry>,
pub struct Tool {
pub poetry: Option<ToolPoetry>,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "kebab-case")]
#[expect(clippy::empty_structs_with_brackets)]
pub(super) struct ToolPoetry {}
pub struct ToolPoetry {
pub name: Option<PackageName>,
}
-1
View File
@@ -41,7 +41,6 @@ console = { workspace = true }
fs-err = { workspace = true, features = ["tokio"] }
futures = { workspace = true }
rustc-hash = { workspace = true }
serde = { workspace = true }
thiserror = { workspace = true }
toml = { workspace = true }
tracing = { workspace = true }
+1 -1
View File
@@ -284,7 +284,7 @@ impl RequirementsSpecification {
));
}
};
let pyproject_toml = toml::from_str::<PyProjectToml>(&content)
let pyproject_toml = PyProjectToml::from_toml(&content)
.with_context(|| format!("Failed to parse: `{}`", path.user_display()))?;
Self {
+2 -30
View File
@@ -5,7 +5,6 @@ use std::sync::Arc;
use configparser::ini::Ini;
use futures::{TryStreamExt, stream::FuturesOrdered};
use serde::Deserialize;
use tracing::debug;
use url::Host;
@@ -17,8 +16,7 @@ use uv_distribution_types::{
};
use uv_normalize::PackageName;
use uv_pep508::{UnnamedRequirement, VersionOrUrl};
use uv_pypi_types::Metadata10;
use uv_pypi_types::{ParsedUrl, VerbatimParsedUrl};
use uv_pypi_types::{Metadata10, ParsedUrl, PyProjectToml, VerbatimParsedUrl};
use uv_resolver::{InMemoryIndex, MetadataResponse};
use uv_types::{BuildContext, HashStrategy};
@@ -168,7 +166,7 @@ impl<'a, Context: BuildContext> NamedRequirementsResolver<'a, Context> {
let project_path = parsed_directory_url.install_path.join("pyproject.toml");
if let Some(pyproject) = fs_err::read_to_string(project_path)
.ok()
.and_then(|contents| toml::from_str::<PyProjectToml>(&contents).ok())
.and_then(|contents| PyProjectToml::from_toml(&contents).ok())
{
// Read PEP 621 metadata from the `pyproject.toml`.
if let Some(project) = pyproject.project {
@@ -315,29 +313,3 @@ impl<'a, Context: BuildContext> NamedRequirementsResolver<'a, Context> {
})
}
}
/// A pyproject.toml as specified in PEP 517.
#[derive(Deserialize, Debug)]
#[serde(rename_all = "kebab-case")]
struct PyProjectToml {
project: Option<Project>,
tool: Option<Tool>,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "kebab-case")]
struct Project {
name: PackageName,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "kebab-case")]
struct Tool {
poetry: Option<ToolPoetry>,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "kebab-case")]
struct ToolPoetry {
name: Option<PackageName>,
}
+21 -20
View File
@@ -1793,27 +1793,28 @@ impl Lock {
// metadata object.
let parent = root.join(source_tree);
let path = parent.join("pyproject.toml");
let metadata =
match fs_err::tokio::read_to_string(&path).await {
Ok(contents) => {
let pyproject_toml = toml::from_str::<PyProjectToml>(&contents)
.map_err(|err| LockErrorKind::InvalidPyprojectToml {
let metadata = match fs_err::tokio::read_to_string(&path).await {
Ok(contents) => {
let pyproject_toml =
PyProjectToml::from_toml(&contents).map_err(|err| {
LockErrorKind::InvalidPyprojectToml {
path: path.clone(),
err,
})?;
database
.requires_dist(&parent, &pyproject_toml)
.await
.map_err(|err| LockErrorKind::Resolution {
id: package.id.clone(),
err,
})?
}
Err(err) if err.kind() == io::ErrorKind::NotFound => None,
Err(err) => {
return Err(LockErrorKind::UnreadablePyprojectToml { path, err }.into());
}
};
}
})?;
database
.requires_dist(&parent, &pyproject_toml)
.await
.map_err(|err| LockErrorKind::Resolution {
id: package.id.clone(),
err,
})?
}
Err(err) if err.kind() == io::ErrorKind::NotFound => None,
Err(err) => {
return Err(LockErrorKind::UnreadablePyprojectToml { path, err }.into());
}
};
let satisfied = metadata.is_some_and(|metadata| {
// Validate that the package is still dynamic.
@@ -5986,7 +5987,7 @@ enum LockErrorKind {
InvalidPyprojectToml {
path: PathBuf,
#[source]
err: toml::de::Error,
err: uv_pypi_types::MetadataError,
},
/// An error that occurs when a workspace member has a non-local source.
#[error("Workspace member `{id}` has non-local source", id = id.cyan())]
+1
View File
@@ -132,6 +132,7 @@ fn invalid_pyproject_toml_syntax() -> Result<()> {
key with no value, expected `=`
error: Failed to parse: `pyproject.toml`
Caused by: Invalid `pyproject.toml`
Caused by: TOML parse error at line 1, column 5
|
1 | 123 - 456