mirror of
https://github.com/astral-sh/uv.git
synced 2025-10-13 20:12:03 +00:00
Support modules with different casing in build backend (#12240)
Match the module name to its module directory with potentially different casing. For example, a package may have the dist-info-normalized package name `pil_util`, but the importable module is named `PIL_util`. We get the module name either as dist-info-normalized package name, or explicitly from the user. For dist-info-normalizing a package name, the rules are lowercasing, replacing `.` with `_` and replace `-` with `_`. Since `.` and `-` are not allowed in module names, we can check whether a directory name matches our expected module name by lowercasing it. Fixes #12187 --------- Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
This commit is contained in:
parent
9af989e30c
commit
fb1b3232e8
3 changed files with 187 additions and 13 deletions
|
@ -7,15 +7,19 @@ pub use metadata::{check_direct_build, PyProjectToml};
|
|||
pub use source_dist::{build_source_dist, list_source_dist};
|
||||
pub use wheel::{build_editable, build_wheel, list_wheel, metadata};
|
||||
|
||||
use crate::metadata::ValidationError;
|
||||
use std::fs::FileType;
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use itertools::Itertools;
|
||||
use thiserror::Error;
|
||||
use tracing::debug;
|
||||
|
||||
use uv_fs::Simplified;
|
||||
use uv_globfilter::PortableGlobError;
|
||||
use uv_pypi_types::IdentifierParseError;
|
||||
use uv_pypi_types::{Identifier, IdentifierParseError};
|
||||
|
||||
use crate::metadata::ValidationError;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum Error {
|
||||
|
@ -54,8 +58,25 @@ pub enum Error {
|
|||
Zip(#[from] zip::result::ZipError),
|
||||
#[error("Failed to write RECORD file")]
|
||||
Csv(#[from] csv::Error),
|
||||
#[error("Expected a Python module with an `__init__.py` at: `{}`", _0.user_display())]
|
||||
#[error(
|
||||
"Expected a Python module directory at: `{}`",
|
||||
_0.user_display()
|
||||
)]
|
||||
MissingModule(PathBuf),
|
||||
#[error(
|
||||
"Expected an `__init__.py` at: `{}`",
|
||||
_0.user_display()
|
||||
)]
|
||||
MissingInitPy(PathBuf),
|
||||
#[error(
|
||||
"Expected an `__init__.py` at `{}`, found multiple:\n* `{}`",
|
||||
module_name,
|
||||
paths.iter().map(Simplified::user_display).join("`\n* `")
|
||||
)]
|
||||
MultipleModules {
|
||||
module_name: Identifier,
|
||||
paths: Vec<PathBuf>,
|
||||
},
|
||||
#[error("Absolute module root is not allowed: `{}`", _0.display())]
|
||||
AbsoluteModuleRoot(PathBuf),
|
||||
#[error("Inconsistent metadata between prepare and build step: `{0}`")]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue