mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-03 10:33:49 +00:00
Read package metadata from pyproject.toml
when statically defined (#2676)
## Summary Now that we're resolving metadata more aggressively for local sources, it's worth doing this. We now pull metadata from the `pyproject.toml` directly if it's statically-defined. Closes https://github.com/astral-sh/uv/issues/2629.
This commit is contained in:
parent
248d6f89ef
commit
365c292525
9 changed files with 302 additions and 34 deletions
|
@ -61,8 +61,12 @@ pub enum Error {
|
|||
NotFound(PathBuf),
|
||||
#[error("The source distribution is missing a `PKG-INFO` file")]
|
||||
MissingPkgInfo,
|
||||
#[error("The source distribution does not support static metadata")]
|
||||
#[error("The source distribution does not support static metadata in `PKG-INFO`")]
|
||||
DynamicPkgInfo(#[source] pypi_types::Error),
|
||||
#[error("The source distribution is missing a `pyproject.toml` file")]
|
||||
MissingPyprojectToml,
|
||||
#[error("The source distribution does not support static metadata in `pyproject.toml`")]
|
||||
DynamicPyprojectToml(#[source] pypi_types::Error),
|
||||
#[error("Unsupported scheme in URL: {0}")]
|
||||
UnsupportedScheme(String),
|
||||
|
||||
|
|
|
@ -955,10 +955,10 @@ impl<'a, T: BuildContext> SourceDistCachedBuilder<'a, T> {
|
|||
) -> Result<Option<Metadata23>, Error> {
|
||||
debug!("Preparing metadata for: {source}");
|
||||
|
||||
// Attempt to read static metadata from the source distribution.
|
||||
// Attempt to read static metadata from the `PKG-INFO` file.
|
||||
match read_pkg_info(source_root).await {
|
||||
Ok(metadata) => {
|
||||
debug!("Found static metadata for: {source}");
|
||||
debug!("Found static `PKG-INFO` for: {source}");
|
||||
|
||||
// Validate the metadata.
|
||||
if let Some(name) = source.name() {
|
||||
|
@ -973,7 +973,30 @@ impl<'a, T: BuildContext> SourceDistCachedBuilder<'a, T> {
|
|||
return Ok(Some(metadata));
|
||||
}
|
||||
Err(err @ (Error::MissingPkgInfo | Error::DynamicPkgInfo(_))) => {
|
||||
debug!("No static metadata available for: {source} ({err:?})");
|
||||
debug!("No static `PKG-INFO` available for: {source} ({err:?})");
|
||||
}
|
||||
Err(err) => return Err(err),
|
||||
}
|
||||
|
||||
// Attempt to read static metadata from the `pyproject.toml`.
|
||||
match read_pyproject_toml(source_root).await {
|
||||
Ok(metadata) => {
|
||||
debug!("Found static `pyproject.toml` for: {source}");
|
||||
|
||||
// Validate the metadata.
|
||||
if let Some(name) = source.name() {
|
||||
if metadata.name != *name {
|
||||
return Err(Error::NameMismatch {
|
||||
metadata: metadata.name,
|
||||
given: name.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(Some(metadata));
|
||||
}
|
||||
Err(err @ (Error::MissingPyprojectToml | Error::DynamicPyprojectToml(_))) => {
|
||||
debug!("No static `pyproject.toml` available for: {source} ({err:?})");
|
||||
}
|
||||
Err(err) => return Err(err),
|
||||
}
|
||||
|
@ -1105,6 +1128,25 @@ pub(crate) async fn read_pkg_info(source_tree: &Path) -> Result<Metadata23, Erro
|
|||
Ok(metadata)
|
||||
}
|
||||
|
||||
/// Read the [`Metadata23`] from a source distribution's `pyproject.tom` file, if it defines static
|
||||
/// metadata consistent with PEP 621.
|
||||
pub(crate) async fn read_pyproject_toml(source_tree: &Path) -> Result<Metadata23, Error> {
|
||||
// Read the `pyproject.toml` file.
|
||||
let content = match fs::read_to_string(source_tree.join("pyproject.toml")).await {
|
||||
Ok(content) => content,
|
||||
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
|
||||
return Err(Error::MissingPyprojectToml);
|
||||
}
|
||||
Err(err) => return Err(Error::CacheRead(err)),
|
||||
};
|
||||
|
||||
// Parse the metadata.
|
||||
let metadata =
|
||||
Metadata23::parse_pyproject_toml(&content).map_err(Error::DynamicPyprojectToml)?;
|
||||
|
||||
Ok(metadata)
|
||||
}
|
||||
|
||||
/// Read an existing HTTP-cached [`Manifest`], if it exists.
|
||||
pub(crate) fn read_http_manifest(cache_entry: &CacheEntry) -> Result<Option<Manifest>, Error> {
|
||||
match fs_err::File::open(cache_entry.path()) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue