build-backend: Allow overriding module names for editable builds (#12137)

## Summary

This PR enables module name overrides for editable installs. 

Builds upon https://github.com/astral-sh/uv/pull/11884. The
`tool.uv.build-backend.module-name` option is now respected during
editable build processes.

## Test Plan

Added a test.

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
This commit is contained in:
Ahmed Ilyas 2025-03-14 02:27:51 +01:00 committed by GitHub
parent 897508aeb0
commit f2ff218621
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 74 additions and 1 deletions

View file

@ -282,7 +282,17 @@ pub fn build_editable(
return Err(Error::AbsoluteModuleRoot(settings.module_root.clone()));
}
let src_root = source_tree.join(settings.module_root);
let module_root = src_root.join(pyproject_toml.name().as_dist_info_name().as_ref());
let module_name = if let Some(module_name) = settings.module_name {
module_name
} else {
// Should never error, the rules for package names (in dist-info formatting) are stricter
// than those for identifiers
Identifier::from_str(pyproject_toml.name().as_dist_info_name().as_ref())?
};
debug!("Module name: `{:?}`", module_name);
let module_root = src_root.join(module_name.as_ref());
if !module_root.join("__init__.py").is_file() {
return Err(Error::MissingModule(module_root));
}

View file

@ -368,3 +368,66 @@ fn rename_module() -> Result<()> {
Ok(())
}
/// Test `tool.uv.build-backend.module-name` for editable builds.
#[test]
fn rename_module_editable_build() -> Result<()> {
let context = TestContext::new("3.12");
let temp_dir = TempDir::new()?;
context
.temp_dir
.child("pyproject.toml")
.write_str(indoc! {r#"
[project]
name = "foo"
version = "1.0.0"
[tool.uv.build-backend]
module-name = "bar"
[build-system]
requires = ["uv_build>=0.5,<0.7"]
build-backend = "uv_build"
"#})?;
context
.temp_dir
.child("src/bar/__init__.py")
.write_str(r#"print("Hi from bar")"#)?;
uv_snapshot!(context
.build_backend()
.arg("build-editable")
.arg(temp_dir.path())
.env("UV_PREVIEW", "1"), @r###"
success: true
exit_code: 0
----- stdout -----
foo-1.0.0-py3-none-any.whl
----- stderr -----
"###);
context
.pip_install()
.arg(temp_dir.path().join("foo-1.0.0-py3-none-any.whl"))
.assert()
.success();
// Importing the module with the `module-name` name succeeds.
uv_snapshot!(Command::new(context.interpreter())
.arg("-c")
.arg("import bar")
// Python on windows
.env(EnvVars::PYTHONUTF8, "1"), @r###"
success: true
exit_code: 0
----- stdout -----
Hi from bar
----- stderr -----
"###);
Ok(())
}