mirror of https://github.com/astral-sh/uv
Tweak language for build backend validation errors (#16720)
Validation errors can also come from files pulled in by `pyproject.toml`, and `pyproject.toml` can be in a subdirectory.
This commit is contained in:
parent
8390b311f8
commit
eaa1882c51
|
|
@ -32,9 +32,9 @@ use crate::settings::ModuleName;
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Io(#[from] io::Error),
|
Io(#[from] io::Error),
|
||||||
#[error("Invalid pyproject.toml")]
|
#[error("Invalid metadata format in: {}", _0.user_display())]
|
||||||
Toml(#[from] toml::de::Error),
|
Toml(PathBuf, #[source] toml::de::Error),
|
||||||
#[error("Invalid pyproject.toml")]
|
#[error("Invalid project metadata")]
|
||||||
Validation(#[from] ValidationError),
|
Validation(#[from] ValidationError),
|
||||||
#[error("Invalid module name: {0}")]
|
#[error("Invalid module name: {0}")]
|
||||||
InvalidModuleName(String, #[source] IdentifierParseError),
|
InvalidModuleName(String, #[source] IdentifierParseError),
|
||||||
|
|
|
||||||
|
|
@ -154,8 +154,11 @@ impl PyProjectToml {
|
||||||
&self.project.version
|
&self.project.version
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn parse(contents: &str) -> Result<Self, Error> {
|
pub(crate) fn parse(path: &Path) -> Result<Self, Error> {
|
||||||
Ok(toml::from_str(contents)?)
|
let contents = fs_err::read_to_string(path)?;
|
||||||
|
let pyproject_toml =
|
||||||
|
toml::from_str(&contents).map_err(|err| Error::Toml(path.to_path_buf(), err))?;
|
||||||
|
Ok(pyproject_toml)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn readme(&self) -> Option<&Readme> {
|
pub(crate) fn readme(&self) -> Option<&Readme> {
|
||||||
|
|
@ -949,7 +952,7 @@ mod tests {
|
||||||
requires = ["uv_build>=0.4.15,<0.5.0"]
|
requires = ["uv_build>=0.4.15,<0.5.0"]
|
||||||
build-backend = "uv_build"
|
build-backend = "uv_build"
|
||||||
"#;
|
"#;
|
||||||
let pyproject_toml = PyProjectToml::parse(contents).unwrap();
|
let pyproject_toml: PyProjectToml = toml::from_str(contents).unwrap();
|
||||||
let temp_dir = TempDir::new().unwrap();
|
let temp_dir = TempDir::new().unwrap();
|
||||||
|
|
||||||
let metadata = pyproject_toml.to_metadata(temp_dir.path()).unwrap();
|
let metadata = pyproject_toml.to_metadata(temp_dir.path()).unwrap();
|
||||||
|
|
@ -1034,7 +1037,7 @@ mod tests {
|
||||||
"#
|
"#
|
||||||
};
|
};
|
||||||
|
|
||||||
let pyproject_toml = PyProjectToml::parse(contents).unwrap();
|
let pyproject_toml: PyProjectToml = toml::from_str(contents).unwrap();
|
||||||
let metadata = pyproject_toml.to_metadata(temp_dir.path()).unwrap();
|
let metadata = pyproject_toml.to_metadata(temp_dir.path()).unwrap();
|
||||||
|
|
||||||
assert_snapshot!(metadata.core_metadata_format(), @r###"
|
assert_snapshot!(metadata.core_metadata_format(), @r###"
|
||||||
|
|
@ -1128,7 +1131,7 @@ mod tests {
|
||||||
"#
|
"#
|
||||||
};
|
};
|
||||||
|
|
||||||
let pyproject_toml = PyProjectToml::parse(contents).unwrap();
|
let pyproject_toml: PyProjectToml = toml::from_str(contents).unwrap();
|
||||||
let metadata = pyproject_toml.to_metadata(temp_dir.path()).unwrap();
|
let metadata = pyproject_toml.to_metadata(temp_dir.path()).unwrap();
|
||||||
|
|
||||||
assert_snapshot!(metadata.core_metadata_format(), @r"
|
assert_snapshot!(metadata.core_metadata_format(), @r"
|
||||||
|
|
@ -1220,7 +1223,7 @@ mod tests {
|
||||||
"#
|
"#
|
||||||
};
|
};
|
||||||
|
|
||||||
let pyproject_toml = PyProjectToml::parse(contents).unwrap();
|
let pyproject_toml: PyProjectToml = toml::from_str(contents).unwrap();
|
||||||
let metadata = pyproject_toml.to_metadata(temp_dir.path()).unwrap();
|
let metadata = pyproject_toml.to_metadata(temp_dir.path()).unwrap();
|
||||||
|
|
||||||
assert_snapshot!(metadata.core_metadata_format(), @r###"
|
assert_snapshot!(metadata.core_metadata_format(), @r###"
|
||||||
|
|
@ -1281,7 +1284,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn build_system_valid() {
|
fn build_system_valid() {
|
||||||
let contents = extend_project("");
|
let contents = extend_project("");
|
||||||
let pyproject_toml = PyProjectToml::parse(&contents).unwrap();
|
let pyproject_toml: PyProjectToml = toml::from_str(&contents).unwrap();
|
||||||
assert_snapshot!(
|
assert_snapshot!(
|
||||||
pyproject_toml.check_build_system("0.4.15+test").join("\n"),
|
pyproject_toml.check_build_system("0.4.15+test").join("\n"),
|
||||||
@""
|
@""
|
||||||
|
|
@ -1299,7 +1302,7 @@ mod tests {
|
||||||
requires = ["uv_build"]
|
requires = ["uv_build"]
|
||||||
build-backend = "uv_build"
|
build-backend = "uv_build"
|
||||||
"#};
|
"#};
|
||||||
let pyproject_toml = PyProjectToml::parse(contents).unwrap();
|
let pyproject_toml: PyProjectToml = toml::from_str(contents).unwrap();
|
||||||
assert_snapshot!(
|
assert_snapshot!(
|
||||||
pyproject_toml.check_build_system("0.4.15+test").join("\n"),
|
pyproject_toml.check_build_system("0.4.15+test").join("\n"),
|
||||||
@r###"`build_system.requires = ["uv_build"]` is missing an upper bound on the `uv_build` version such as `<0.5`. Without bounding the `uv_build` version, the source distribution will break when a future, breaking version of `uv_build` is released."###
|
@r###"`build_system.requires = ["uv_build"]` is missing an upper bound on the `uv_build` version such as `<0.5`. Without bounding the `uv_build` version, the source distribution will break when a future, breaking version of `uv_build` is released."###
|
||||||
|
|
@ -1317,7 +1320,7 @@ mod tests {
|
||||||
requires = ["uv_build>=0.4.15,<0.5.0", "wheel"]
|
requires = ["uv_build>=0.4.15,<0.5.0", "wheel"]
|
||||||
build-backend = "uv_build"
|
build-backend = "uv_build"
|
||||||
"#};
|
"#};
|
||||||
let pyproject_toml = PyProjectToml::parse(contents).unwrap();
|
let pyproject_toml: PyProjectToml = toml::from_str(contents).unwrap();
|
||||||
assert_snapshot!(
|
assert_snapshot!(
|
||||||
pyproject_toml.check_build_system("0.4.15+test").join("\n"),
|
pyproject_toml.check_build_system("0.4.15+test").join("\n"),
|
||||||
@"Expected a single uv requirement in `build-system.requires`, found ``"
|
@"Expected a single uv requirement in `build-system.requires`, found ``"
|
||||||
|
|
@ -1335,7 +1338,7 @@ mod tests {
|
||||||
requires = ["setuptools"]
|
requires = ["setuptools"]
|
||||||
build-backend = "uv_build"
|
build-backend = "uv_build"
|
||||||
"#};
|
"#};
|
||||||
let pyproject_toml = PyProjectToml::parse(contents).unwrap();
|
let pyproject_toml: PyProjectToml = toml::from_str(contents).unwrap();
|
||||||
assert_snapshot!(
|
assert_snapshot!(
|
||||||
pyproject_toml.check_build_system("0.4.15+test").join("\n"),
|
pyproject_toml.check_build_system("0.4.15+test").join("\n"),
|
||||||
@"Expected a single uv requirement in `build-system.requires`, found ``"
|
@"Expected a single uv requirement in `build-system.requires`, found ``"
|
||||||
|
|
@ -1353,7 +1356,7 @@ mod tests {
|
||||||
requires = ["uv_build>=0.4.15,<0.5.0"]
|
requires = ["uv_build>=0.4.15,<0.5.0"]
|
||||||
build-backend = "setuptools"
|
build-backend = "setuptools"
|
||||||
"#};
|
"#};
|
||||||
let pyproject_toml = PyProjectToml::parse(contents).unwrap();
|
let pyproject_toml: PyProjectToml = toml::from_str(contents).unwrap();
|
||||||
assert_snapshot!(
|
assert_snapshot!(
|
||||||
pyproject_toml.check_build_system("0.4.15+test").join("\n"),
|
pyproject_toml.check_build_system("0.4.15+test").join("\n"),
|
||||||
@r###"The value for `build_system.build-backend` should be `"uv_build"`, not `"setuptools"`"###
|
@r###"The value for `build_system.build-backend` should be `"uv_build"`, not `"setuptools"`"###
|
||||||
|
|
@ -1364,7 +1367,7 @@ mod tests {
|
||||||
fn minimal() {
|
fn minimal() {
|
||||||
let contents = extend_project("");
|
let contents = extend_project("");
|
||||||
|
|
||||||
let metadata = PyProjectToml::parse(&contents)
|
let metadata = toml::from_str::<PyProjectToml>(&contents)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_metadata(Path::new("/do/not/read"))
|
.to_metadata(Path::new("/do/not/read"))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
@ -1383,15 +1386,14 @@ mod tests {
|
||||||
"#
|
"#
|
||||||
});
|
});
|
||||||
|
|
||||||
let err = PyProjectToml::parse(&contents).unwrap_err();
|
let err = toml::from_str::<PyProjectToml>(&contents).unwrap_err();
|
||||||
assert_snapshot!(format_err(err), @r###"
|
assert_snapshot!(format_err(err), @r#"
|
||||||
Invalid pyproject.toml
|
TOML parse error at line 4, column 10
|
||||||
Caused by: TOML parse error at line 4, column 10
|
|
||||||
|
|
|
|
||||||
4 | readme = { path = "Readme.md" }
|
4 | readme = { path = "Readme.md" }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
data did not match any variant of untagged enum Readme
|
data did not match any variant of untagged enum Readme
|
||||||
"###);
|
"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -1401,7 +1403,7 @@ mod tests {
|
||||||
"#
|
"#
|
||||||
});
|
});
|
||||||
|
|
||||||
let err = PyProjectToml::parse(&contents)
|
let err = toml::from_str::<PyProjectToml>(&contents)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_metadata(Path::new("/do/not/read"))
|
.to_metadata(Path::new("/do/not/read"))
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
|
|
@ -1423,14 +1425,14 @@ mod tests {
|
||||||
"#
|
"#
|
||||||
});
|
});
|
||||||
|
|
||||||
let err = PyProjectToml::parse(&contents)
|
let err = toml::from_str::<PyProjectToml>(&contents)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_metadata(Path::new("/do/not/read"))
|
.to_metadata(Path::new("/do/not/read"))
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert_snapshot!(format_err(err), @r###"
|
assert_snapshot!(format_err(err), @r"
|
||||||
Invalid pyproject.toml
|
Invalid project metadata
|
||||||
Caused by: `project.description` must be a single line
|
Caused by: `project.description` must be a single line
|
||||||
"###);
|
");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -1441,14 +1443,14 @@ mod tests {
|
||||||
"#
|
"#
|
||||||
});
|
});
|
||||||
|
|
||||||
let err = PyProjectToml::parse(&contents)
|
let err = toml::from_str::<PyProjectToml>(&contents)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_metadata(Path::new("/do/not/read"))
|
.to_metadata(Path::new("/do/not/read"))
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert_snapshot!(format_err(err), @r###"
|
assert_snapshot!(format_err(err), @r"
|
||||||
Invalid pyproject.toml
|
Invalid project metadata
|
||||||
Caused by: When `project.license-files` is defined, `project.license` must be an SPDX expression string
|
Caused by: When `project.license-files` is defined, `project.license` must be an SPDX expression string
|
||||||
"###);
|
");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -1457,7 +1459,7 @@ mod tests {
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
"#
|
"#
|
||||||
});
|
});
|
||||||
let metadata = PyProjectToml::parse(&contents)
|
let metadata = toml::from_str::<PyProjectToml>(&contents)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_metadata(Path::new("/do/not/read"))
|
.to_metadata(Path::new("/do/not/read"))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
@ -1475,13 +1477,13 @@ mod tests {
|
||||||
license = "MIT XOR Apache-2"
|
license = "MIT XOR Apache-2"
|
||||||
"#
|
"#
|
||||||
});
|
});
|
||||||
let err = PyProjectToml::parse(&contents)
|
let err = toml::from_str::<PyProjectToml>(&contents)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_metadata(Path::new("/do/not/read"))
|
.to_metadata(Path::new("/do/not/read"))
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
// TODO(konsti): We mess up the indentation in the error.
|
// TODO(konsti): We mess up the indentation in the error.
|
||||||
assert_snapshot!(format_err(err), @r"
|
assert_snapshot!(format_err(err), @r"
|
||||||
Invalid pyproject.toml
|
Invalid project metadata
|
||||||
Caused by: `project.license` is not a valid SPDX expression: MIT XOR Apache-2
|
Caused by: `project.license` is not a valid SPDX expression: MIT XOR Apache-2
|
||||||
Caused by: MIT XOR Apache-2
|
Caused by: MIT XOR Apache-2
|
||||||
^^^ unknown term
|
^^^ unknown term
|
||||||
|
|
@ -1495,18 +1497,18 @@ mod tests {
|
||||||
"#
|
"#
|
||||||
});
|
});
|
||||||
|
|
||||||
let err = PyProjectToml::parse(&contents)
|
let err = toml::from_str::<PyProjectToml>(&contents)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_metadata(Path::new("/do/not/read"))
|
.to_metadata(Path::new("/do/not/read"))
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert_snapshot!(format_err(err), @r###"
|
assert_snapshot!(format_err(err), @r"
|
||||||
Invalid pyproject.toml
|
Invalid project metadata
|
||||||
Caused by: Dynamic metadata is not supported
|
Caused by: Dynamic metadata is not supported
|
||||||
"###);
|
");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_error(contents: &str) -> String {
|
fn script_error(contents: &str) -> String {
|
||||||
let err = PyProjectToml::parse(contents)
|
let err = toml::from_str::<PyProjectToml>(contents)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_entry_points()
|
.to_entry_points()
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,7 @@ pub fn build_source_dist(
|
||||||
uv_version: &str,
|
uv_version: &str,
|
||||||
show_warnings: bool,
|
show_warnings: bool,
|
||||||
) -> Result<SourceDistFilename, Error> {
|
) -> Result<SourceDistFilename, Error> {
|
||||||
let contents = fs_err::read_to_string(source_tree.join("pyproject.toml"))?;
|
let pyproject_toml = PyProjectToml::parse(&source_tree.join("pyproject.toml"))?;
|
||||||
let pyproject_toml = PyProjectToml::parse(&contents)?;
|
|
||||||
let filename = SourceDistFilename {
|
let filename = SourceDistFilename {
|
||||||
name: pyproject_toml.name().clone(),
|
name: pyproject_toml.name().clone(),
|
||||||
version: pyproject_toml.version().clone(),
|
version: pyproject_toml.version().clone(),
|
||||||
|
|
@ -45,8 +44,7 @@ pub fn list_source_dist(
|
||||||
uv_version: &str,
|
uv_version: &str,
|
||||||
show_warnings: bool,
|
show_warnings: bool,
|
||||||
) -> Result<(SourceDistFilename, FileList), Error> {
|
) -> Result<(SourceDistFilename, FileList), Error> {
|
||||||
let contents = fs_err::read_to_string(source_tree.join("pyproject.toml"))?;
|
let pyproject_toml = PyProjectToml::parse(&source_tree.join("pyproject.toml"))?;
|
||||||
let pyproject_toml = PyProjectToml::parse(&contents)?;
|
|
||||||
let filename = SourceDistFilename {
|
let filename = SourceDistFilename {
|
||||||
name: pyproject_toml.name().clone(),
|
name: pyproject_toml.name().clone(),
|
||||||
version: pyproject_toml.version().clone(),
|
version: pyproject_toml.version().clone(),
|
||||||
|
|
@ -188,8 +186,7 @@ fn write_source_dist(
|
||||||
uv_version: &str,
|
uv_version: &str,
|
||||||
show_warnings: bool,
|
show_warnings: bool,
|
||||||
) -> Result<SourceDistFilename, Error> {
|
) -> Result<SourceDistFilename, Error> {
|
||||||
let contents = fs_err::read_to_string(source_tree.join("pyproject.toml"))?;
|
let pyproject_toml = PyProjectToml::parse(&source_tree.join("pyproject.toml"))?;
|
||||||
let pyproject_toml = PyProjectToml::parse(&contents)?;
|
|
||||||
for warning in pyproject_toml.check_build_system(uv_version) {
|
for warning in pyproject_toml.check_build_system(uv_version) {
|
||||||
warn_user_once!("{warning}");
|
warn_user_once!("{warning}");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,7 @@ pub fn build_wheel(
|
||||||
uv_version: &str,
|
uv_version: &str,
|
||||||
show_warnings: bool,
|
show_warnings: bool,
|
||||||
) -> Result<WheelFilename, Error> {
|
) -> Result<WheelFilename, Error> {
|
||||||
let contents = fs_err::read_to_string(source_tree.join("pyproject.toml"))?;
|
let pyproject_toml = PyProjectToml::parse(&source_tree.join("pyproject.toml"))?;
|
||||||
let pyproject_toml = PyProjectToml::parse(&contents)?;
|
|
||||||
for warning in pyproject_toml.check_build_system(uv_version) {
|
for warning in pyproject_toml.check_build_system(uv_version) {
|
||||||
warn_user_once!("{warning}");
|
warn_user_once!("{warning}");
|
||||||
}
|
}
|
||||||
|
|
@ -71,8 +70,7 @@ pub fn list_wheel(
|
||||||
uv_version: &str,
|
uv_version: &str,
|
||||||
show_warnings: bool,
|
show_warnings: bool,
|
||||||
) -> Result<(WheelFilename, FileList), Error> {
|
) -> Result<(WheelFilename, FileList), Error> {
|
||||||
let contents = fs_err::read_to_string(source_tree.join("pyproject.toml"))?;
|
let pyproject_toml = PyProjectToml::parse(&source_tree.join("pyproject.toml"))?;
|
||||||
let pyproject_toml = PyProjectToml::parse(&contents)?;
|
|
||||||
for warning in pyproject_toml.check_build_system(uv_version) {
|
for warning in pyproject_toml.check_build_system(uv_version) {
|
||||||
warn_user_once!("{warning}");
|
warn_user_once!("{warning}");
|
||||||
}
|
}
|
||||||
|
|
@ -273,8 +271,7 @@ pub fn build_editable(
|
||||||
uv_version: &str,
|
uv_version: &str,
|
||||||
show_warnings: bool,
|
show_warnings: bool,
|
||||||
) -> Result<WheelFilename, Error> {
|
) -> Result<WheelFilename, Error> {
|
||||||
let contents = fs_err::read_to_string(source_tree.join("pyproject.toml"))?;
|
let pyproject_toml = PyProjectToml::parse(&source_tree.join("pyproject.toml"))?;
|
||||||
let pyproject_toml = PyProjectToml::parse(&contents)?;
|
|
||||||
for warning in pyproject_toml.check_build_system(uv_version) {
|
for warning in pyproject_toml.check_build_system(uv_version) {
|
||||||
warn_user_once!("{warning}");
|
warn_user_once!("{warning}");
|
||||||
}
|
}
|
||||||
|
|
@ -335,8 +332,7 @@ pub fn metadata(
|
||||||
metadata_directory: &Path,
|
metadata_directory: &Path,
|
||||||
uv_version: &str,
|
uv_version: &str,
|
||||||
) -> Result<String, Error> {
|
) -> Result<String, Error> {
|
||||||
let contents = fs_err::read_to_string(source_tree.join("pyproject.toml"))?;
|
let pyproject_toml = PyProjectToml::parse(&source_tree.join("pyproject.toml"))?;
|
||||||
let pyproject_toml = PyProjectToml::parse(&contents)?;
|
|
||||||
for warning in pyproject_toml.check_build_system(uv_version) {
|
for warning in pyproject_toml.check_build_system(uv_version) {
|
||||||
warn_user_once!("{warning}");
|
warn_user_once!("{warning}");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -792,15 +792,15 @@ fn license_glob_without_matches_errors() -> Result<()> {
|
||||||
.build_backend()
|
.build_backend()
|
||||||
.arg("build-wheel")
|
.arg("build-wheel")
|
||||||
.arg(context.temp_dir.path())
|
.arg(context.temp_dir.path())
|
||||||
.current_dir(project.path()), @r###"
|
.current_dir(project.path()), @r"
|
||||||
success: false
|
success: false
|
||||||
exit_code: 2
|
exit_code: 2
|
||||||
----- stdout -----
|
----- stdout -----
|
||||||
|
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
error: Invalid pyproject.toml
|
error: Invalid project metadata
|
||||||
Caused by: `project.license-files` glob `abc` did not match any files
|
Caused by: `project.license-files` glob `abc` did not match any files
|
||||||
"###);
|
");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -835,15 +835,15 @@ fn license_file_must_be_utf8() -> Result<()> {
|
||||||
.build_backend()
|
.build_backend()
|
||||||
.arg("build-wheel")
|
.arg("build-wheel")
|
||||||
.arg(context.temp_dir.path())
|
.arg(context.temp_dir.path())
|
||||||
.current_dir(project.path()), @r###"
|
.current_dir(project.path()), @r"
|
||||||
success: false
|
success: false
|
||||||
exit_code: 2
|
exit_code: 2
|
||||||
----- stdout -----
|
----- stdout -----
|
||||||
|
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
error: Invalid pyproject.toml
|
error: Invalid project metadata
|
||||||
Caused by: License file `LICENSE.bin` must be UTF-8 encoded
|
Caused by: License file `LICENSE.bin` must be UTF-8 encoded
|
||||||
"###);
|
");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -1185,3 +1185,40 @@ fn warn_on_redundant_module_names() -> Result<()> {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn invalid_pyproject_toml() -> Result<()> {
|
||||||
|
let context = TestContext::new("3.12");
|
||||||
|
|
||||||
|
context
|
||||||
|
.temp_dir
|
||||||
|
.child("child")
|
||||||
|
.child("pyproject.toml")
|
||||||
|
.write_str(indoc! {r#"
|
||||||
|
[project]
|
||||||
|
name = 1
|
||||||
|
version = "1.0.0"
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["uv_build>=0.9,<10000"]
|
||||||
|
build-backend = "uv_build"
|
||||||
|
"#})?;
|
||||||
|
|
||||||
|
uv_snapshot!(context.filters(), context.build().arg("child"), @r"
|
||||||
|
success: false
|
||||||
|
exit_code: 2
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
Building source distribution (uv build backend)...
|
||||||
|
× Failed to build `[TEMP_DIR]/child`
|
||||||
|
├─▶ Invalid metadata format in: child/pyproject.toml
|
||||||
|
╰─▶ TOML parse error at line 2, column 8
|
||||||
|
|
|
||||||
|
2 | name = 1
|
||||||
|
| ^
|
||||||
|
invalid type: integer `1`, expected a string
|
||||||
|
");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue