diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b9cab297e..60e4ea861 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -481,7 +481,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - - uses: dtolnay/rust-toolchain@1.83.0 + - uses: dtolnay/rust-toolchain@1.85.0 # Caching - name: Cache cargo build uses: Swatinem/rust-cache@v2 diff --git a/Cargo.toml b/Cargo.toml index 9ab3e9b63..fbb674a1d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,8 +29,8 @@ categories = [ "development-tools::ffi", "command-line-utilities", ] -edition = "2021" -rust-version = "1.83" +edition = "2024" +rust-version = "1.85" [[bin]] name = "maturin" diff --git a/src/auditwheel/audit.rs b/src/auditwheel/audit.rs index d99e4ec77..7ffcecfa5 100644 --- a/src/auditwheel/audit.rs +++ b/src/auditwheel/audit.rs @@ -1,11 +1,11 @@ use super::musllinux::{find_musl_libc, get_musl_version}; -use super::policy::{Policy, MANYLINUX_POLICIES, MUSLLINUX_POLICIES}; -use crate::auditwheel::{find_external_libs, PlatformTag}; +use super::policy::{MANYLINUX_POLICIES, MUSLLINUX_POLICIES, Policy}; +use crate::auditwheel::{PlatformTag, find_external_libs}; use crate::compile::BuildArtifact; use crate::target::Target; -use anyhow::{bail, Context, Result}; +use anyhow::{Context, Result, bail}; use fs_err::File; -use goblin::elf::{sym::STT_FUNC, Elf}; +use goblin::elf::{Elf, sym::STT_FUNC}; use lddtree::Library; use once_cell::sync::Lazy; use regex::Regex; @@ -32,19 +32,19 @@ pub enum AuditWheelError { /// The elf file isn't manylinux/musllinux compatible. Contains the list of offending /// libraries. #[error( - "Your library links libpython ({0}), which libraries must not do. Have you forgotten to activate the extension-module feature?", + "Your library links libpython ({0}), which libraries must not do. Have you forgotten to activate the extension-module feature?" )] LinksLibPythonError(String), /// The elf file isn't manylinux/musllinux compatible. Contains the list of offending /// libraries. #[error( - "Your library is not {0} compliant because it links the following forbidden libraries: {1:?}", + "Your library is not {0} compliant because it links the following forbidden libraries: {1:?}" )] LinksForbiddenLibrariesError(Policy, Vec), /// The elf file isn't manylinux/musllinux compatible. Contains the list of offending /// libraries. #[error( - "Your library is not {0} compliant because of the presence of too-recent versioned symbols: {1:?}. Consider building in a manylinux docker container", + "Your library is not {0} compliant because of the presence of too-recent versioned symbols: {1:?}. Consider building in a manylinux docker container" )] VersionedSymbolTooNewError(Policy, Vec), /// The elf file isn't manylinux/musllinux compatible. Contains the list of offending @@ -55,7 +55,9 @@ pub enum AuditWheelError { #[error("Your library is not {0} compliant because it has unsupported architecture: {1}")] UnsupportedArchitecture(Policy, String), /// This platform tag isn't defined by auditwheel yet - #[error("{0} compatibility policy is not defined by auditwheel yet, pass `--auditwheel=skip` to proceed anyway")] + #[error( + "{0} compatibility policy is not defined by auditwheel yet, pass `--auditwheel=skip` to proceed anyway" + )] UndefinedPolicy(PlatformTag), /// Failed to analyze external shared library dependencies of the wheel #[error("Failed to analyze external shared library dependencies of the wheel")] @@ -564,8 +566,8 @@ pub fn relpath(to: &Path, from: &Path) -> PathBuf { #[cfg(test)] mod tests { - use crate::auditwheel::audit::relpath; use crate::Target; + use crate::auditwheel::audit::relpath; use pretty_assertions::assert_eq; use std::path::Path; @@ -623,12 +625,16 @@ rustflags = ["-L", "dependency=/usr/local/lib", "-L", "/some/other/path", "-C", if let Some(paths) = paths { assert_eq!(paths.len(), 2); - assert!(paths - .iter() - .any(|p| p.to_string_lossy() == "/usr/local/lib")); - assert!(paths - .iter() - .any(|p| p.to_string_lossy() == "/some/other/path")); + assert!( + paths + .iter() + .any(|p| p.to_string_lossy() == "/usr/local/lib") + ); + assert!( + paths + .iter() + .any(|p| p.to_string_lossy() == "/some/other/path") + ); } else { // It's possible that rustflags parsing fails in some environments, // so we just verify the function doesn't panic diff --git a/src/auditwheel/patchelf.rs b/src/auditwheel/patchelf.rs index 94b5b5bea..7ff4a9b67 100644 --- a/src/auditwheel/patchelf.rs +++ b/src/auditwheel/patchelf.rs @@ -1,4 +1,4 @@ -use anyhow::{bail, Context, Result}; +use anyhow::{Context, Result, bail}; use std::ffi::OsStr; use std::path::Path; use std::process::Command; diff --git a/src/auditwheel/policy.rs b/src/auditwheel/policy.rs index 7c6cdc46c..e9da0d5fa 100644 --- a/src/auditwheel/policy.rs +++ b/src/auditwheel/policy.rs @@ -121,7 +121,7 @@ impl Policy { #[cfg(test)] mod tests { - use super::{Arch, Policy, MANYLINUX_POLICIES, MUSLLINUX_POLICIES}; + use super::{Arch, MANYLINUX_POLICIES, MUSLLINUX_POLICIES, Policy}; use crate::PlatformTag; use pretty_assertions::assert_eq; diff --git a/src/build_context.rs b/src/build_context.rs index 8b04e8494..ec3bdf9ef 100644 --- a/src/build_context.rs +++ b/src/build_context.rs @@ -1,22 +1,22 @@ -use crate::auditwheel::{get_policy_and_libs, patchelf, relpath, AuditWheelMode}; +use crate::auditwheel::{AuditWheelMode, get_policy_and_libs, patchelf, relpath}; use crate::auditwheel::{PlatformTag, Policy}; use crate::bridge::Abi3Version; use crate::build_options::CargoOptions; -use crate::compile::{warn_missing_py_init, CompileTarget}; +use crate::compile::{CompileTarget, warn_missing_py_init}; use crate::compression::CompressionOptions; use crate::module_writer::{ - add_data, write_bin, write_bindings_module, write_cffi_module, write_python_part, - write_uniffi_module, write_wasm_launcher, WheelWriter, + WheelWriter, add_data, write_bin, write_bindings_module, write_cffi_module, write_python_part, + write_uniffi_module, write_wasm_launcher, }; use crate::project_layout::ProjectLayout; use crate::source_distribution::source_distribution; use crate::target::validate_wheel_filename_for_pypi; use crate::target::{Arch, Os}; use crate::{ - compile, pyproject_toml::Format, BridgeModel, BuildArtifact, Metadata24, ModuleWriter, - PyProjectToml, PythonInterpreter, Target, + BridgeModel, BuildArtifact, Metadata24, ModuleWriter, PyProjectToml, PythonInterpreter, Target, + compile, pyproject_toml::Format, }; -use anyhow::{anyhow, bail, Context, Result}; +use anyhow::{Context, Result, anyhow, bail}; use cargo_metadata::CrateType; use cargo_metadata::Metadata; use fs_err as fs; @@ -399,7 +399,9 @@ impl BuildContext { } if matches!(self.auditwheel, AuditWheelMode::Check) { - eprintln!("🖨️ Your library is not manylinux/musllinux compliant because it requires copying the following libraries:"); + eprintln!( + "🖨️ Your library is not manylinux/musllinux compliant because it requires copying the following libraries:" + ); for lib in ext_libs.iter().flatten() { if let Some(path) = lib.realpath.as_ref() { eprintln!(" {} => {}", lib.name, path.display()) @@ -407,7 +409,9 @@ impl BuildContext { eprintln!(" {} => not found", lib.name) }; } - bail!("Can not repair the wheel because `--auditwheel=check` is specified, re-run with `--auditwheel=repair` to copy the libraries."); + bail!( + "Can not repair the wheel because `--auditwheel=check` is specified, re-run with `--auditwheel=repair` to copy the libraries." + ); } patchelf::verify_patchelf()?; @@ -573,7 +577,9 @@ impl BuildContext { pub fn get_platform_tag(&self, platform_tags: &[PlatformTag]) -> Result { if let Ok(host_platform) = env::var("_PYTHON_HOST_PLATFORM") { let override_platform = host_platform.replace(['.', '-'], "_"); - eprintln!("🚉 Overriding platform tag from _PYTHON_HOST_PLATFORM environment variable as {override_platform}."); + eprintln!( + "🚉 Overriding platform tag from _PYTHON_HOST_PLATFORM environment variable as {override_platform}." + ); return Ok(override_platform); } diff --git a/src/build_options.rs b/src/build_options.rs index 04dce887a..b30ec473f 100644 --- a/src/build_options.rs +++ b/src/build_options.rs @@ -10,7 +10,7 @@ use crate::target::{ detect_arch_from_python, detect_target_from_cross_python, is_arch_supported_by_pypi, }; use crate::{BridgeModel, BuildContext, PyO3, PythonInterpreter, Target}; -use anyhow::{bail, format_err, Context, Result}; +use anyhow::{Context, Result, bail, format_err}; use cargo_metadata::{CrateType, PackageId, TargetKind}; use cargo_metadata::{Metadata, Node}; use cargo_options::heading; @@ -274,16 +274,19 @@ impl BuildOptions { "🐍 Using host {host_python} for cross-compiling preparation" ); // pyo3 - env::set_var("PYO3_PYTHON", &host_python.executable); - // legacy pyo3 versions - env::set_var("PYTHON_SYS_EXECUTABLE", &host_python.executable); + unsafe { + env::set_var("PYO3_PYTHON", &host_python.executable); + env::set_var("PYTHON_SYS_EXECUTABLE", &host_python.executable) + }; let sysconfig_path = find_sysconfigdata(cross_lib_dir.as_ref(), target)?; - env::set_var( - "MATURIN_PYTHON_SYSCONFIGDATA_DIR", - sysconfig_path.parent().unwrap(), - ); + unsafe { + env::set_var( + "MATURIN_PYTHON_SYSCONFIGDATA_DIR", + sysconfig_path.parent().unwrap(), + ) + }; let sysconfig_data = parse_sysconfigdata(host_python, sysconfig_path)?; @@ -342,7 +345,9 @@ impl BuildOptions { }); } else { if interpreter.is_empty() && !self.find_interpreter { - bail!("Couldn't find any python interpreters. Please specify at least one with -i"); + bail!( + "Couldn't find any python interpreters. Please specify at least one with -i" + ); } for interp in interpreter { // If `-i` looks like a file path, check if it's a valid interpreter @@ -445,7 +450,9 @@ impl BuildOptions { .context("Invalid PYO3_CONFIG_FILE")?; Ok(vec![PythonInterpreter::from_config(interpreter_config)]) } else if generate_import_lib { - eprintln!("🐍 Not using a specific python interpreter (automatically generating windows import library)"); + eprintln!( + "🐍 Not using a specific python interpreter (automatically generating windows import library)" + ); let mut found_interpreters = found_interpreters; // fake a python interpreter if none directly found if found_interpreters.is_empty() { @@ -642,11 +649,7 @@ impl BuildContextBuilder { .split("-arch") .filter_map(|x| { let x = x.trim(); - if x.is_empty() { - None - } else { - Some(x) - } + if x.is_empty() { None } else { Some(x) } }) .collect(); match (arches.contains("x86_64"), arches.contains("arm64")) { @@ -817,7 +820,9 @@ impl BuildContextBuilder { let compile_targets = filter_cargo_targets(&cargo_metadata, bridge, config_targets.as_deref())?; if compile_targets.is_empty() { - bail!("No Cargo targets to build, please check your bindings configuration in pyproject.toml."); + bail!( + "No Cargo targets to build, please check your bindings configuration in pyproject.toml." + ); } let crate_name = cargo_toml.package.name; @@ -1219,20 +1224,29 @@ pub fn find_bridge(cargo_metadata: &Metadata, bridge: Option<&str>) -> Result
{ + if !targets.contains(&CrateType::CDyLib) && targets.contains(&CrateType::Bin) { + BridgeModel::Bin(Some(bindings)) + } else { + BridgeModel::PyO3(bindings) + } + } + _ => { + if deps.contains_key("uniffi") { + BridgeModel::UniFfi + } else if targets.contains(&CrateType::CDyLib) { + BridgeModel::Cffi + } else if targets.contains(&CrateType::Bin) { + BridgeModel::Bin(find_pyo3_bindings(&deps, &packages)?) + } else { + bail!( + "Couldn't detect the binding type; Please specify them with --bindings/-b" + ) + } + } + } }; if !bridge.is_pyo3() { @@ -1330,7 +1344,9 @@ fn find_interpreter( .iter() .map(|i| format!("{} {}.{}", i.interpreter_kind, i.major, i.minor)) .collect::>(); - bail!("Interpreters {found:?} were found in maturin's bundled sysconfig, but compiling for Windows without an interpreter requires PyO3's `generate-import-lib` feature"); + bail!( + "Interpreters {found:?} were found in maturin's bundled sysconfig, but compiling for Windows without an interpreter requires PyO3's `generate-import-lib` feature" + ); } found_interpreters.extend(sysconfig_interps); @@ -1343,7 +1359,10 @@ fn find_interpreter( if found_interpreters.is_empty() { if interpreter.is_empty() { if let Some(requires_python) = requires_python { - bail!("Couldn't find any python interpreters with version {}. Please specify at least one with -i", requires_python); + bail!( + "Couldn't find any python interpreters with version {}. Please specify at least one with -i", + requires_python + ); } else { bail!("Couldn't find any python interpreters. Please specify at least one with -i"); } @@ -1378,7 +1397,10 @@ fn find_interpreter_in_host( if interpreters.is_empty() { if let Some(requires_python) = requires_python { - bail!("Couldn't find any python interpreters with {}. Please specify at least one with -i", requires_python); + bail!( + "Couldn't find any python interpreters with {}. Please specify at least one with -i", + requires_python + ); } else { bail!("Couldn't find any python interpreters. Please specify at least one with -i"); } @@ -1431,9 +1453,15 @@ fn find_interpreter_in_sysconfig( } else { // if interpreter not known if std::path::Path::new(&python).is_file() { - bail!("Python interpreter should be a kind of interpreter (e.g. 'python3.14' or 'pypy3.11') when cross-compiling, got path to interpreter: {}", python); + bail!( + "Python interpreter should be a kind of interpreter (e.g. 'python3.14' or 'pypy3.11') when cross-compiling, got path to interpreter: {}", + python + ); } else { - bail!("Unsupported Python interpreter for cross-compilation: {}; supported interpreters are pypy, graalpy, and python (cpython)", python); + bail!( + "Unsupported Python interpreter for cross-compilation: {}; supported interpreters are pypy, graalpy, and python (cpython)", + python + ); } }; if python_ver.is_empty() { diff --git a/src/cargo_toml.rs b/src/cargo_toml.rs index c1f48cf33..8fce279bd 100644 --- a/src/cargo_toml.rs +++ b/src/cargo_toml.rs @@ -1,4 +1,4 @@ -use anyhow::{bail, Context, Result}; +use anyhow::{Context, Result, bail}; use fs_err as fs; use serde::{Deserialize, Serialize}; use std::collections::HashMap; diff --git a/src/ci.rs b/src/ci.rs index c9b18dcda..86d498db2 100644 --- a/src/ci.rs +++ b/src/ci.rs @@ -672,7 +672,7 @@ jobs:\n", #[cfg(test)] mod tests { use super::GenerateCI; - use crate::{bridge::PyO3Crate, Abi3Version, BridgeModel, PyO3}; + use crate::{Abi3Version, BridgeModel, PyO3, bridge::PyO3Crate}; use expect_test::expect; use semver::Version; @@ -1299,12 +1299,12 @@ mod tests { #[test] fn test_generate_github_zig_pytest() { - let gen = GenerateCI { + let r#gen = GenerateCI { zig: true, pytest: true, ..Default::default() }; - let conf = gen + let conf = r#gen .generate_github( "example", &BridgeModel::PyO3(PyO3 { diff --git a/src/compile.rs b/src/compile.rs index c574eb8e4..d0c14a725 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -1,8 +1,8 @@ -use crate::target::RUST_1_64_0; #[cfg(feature = "zig")] use crate::PlatformTag; +use crate::target::RUST_1_64_0; use crate::{BridgeModel, BuildContext, PythonInterpreter, Target}; -use anyhow::{anyhow, bail, Context, Result}; +use anyhow::{Context, Result, anyhow, bail}; use cargo_metadata::CrateType; use fat_macho::FatWriter; use fs_err::{self as fs, File}; diff --git a/src/cross_compile.rs b/src/cross_compile.rs index 7bd8ed284..454cea435 100644 --- a/src/cross_compile.rs +++ b/src/cross_compile.rs @@ -1,6 +1,6 @@ use crate::target::Os; use crate::{PythonInterpreter, Target}; -use anyhow::{bail, Result}; +use anyhow::{Result, bail}; use fs_err::{self as fs, DirEntry}; use normpath::PathExt as _; use std::collections::HashMap; diff --git a/src/develop.rs b/src/develop.rs index 85c4bd404..df53df37a 100644 --- a/src/develop.rs +++ b/src/develop.rs @@ -1,14 +1,14 @@ -use crate::auditwheel::AuditWheelMode; -use crate::build_options::CargoOptions; -use crate::compression::CompressionOptions; -use crate::target::detect_arch_from_python; use crate::BuildContext; use crate::BuildOptions; use crate::PlatformTag; use crate::PythonInterpreter; use crate::Target; +use crate::auditwheel::AuditWheelMode; +use crate::build_options::CargoOptions; +use crate::compression::CompressionOptions; +use crate::target::detect_arch_from_python; use anyhow::ensure; -use anyhow::{anyhow, bail, Context, Result}; +use anyhow::{Context, Result, anyhow, bail}; use cargo_options::heading; use fs_err as fs; use regex::Regex; @@ -65,11 +65,12 @@ impl InstallBackend { InstallBackend::Pip { .. } => Regex::new(r"pip ([\w\.]+).*"), InstallBackend::Uv { .. } => Regex::new(r"uv ([\w\.]+).*"), }; - if let Some(captures) = re.expect("regex should be valid").captures(stdout) { - Ok(semver::Version::parse(&captures[1]) - .with_context(|| format!("failed to parse semver from {stdout:?}"))?) - } else { - bail!("failed to parse version from {:?}", stdout); + match re.expect("regex should be valid").captures(stdout) { + Some(captures) => Ok(semver::Version::parse(&captures[1]) + .with_context(|| format!("failed to parse semver from {stdout:?}"))?), + _ => { + bail!("failed to parse version from {:?}", stdout); + } } } @@ -444,8 +445,10 @@ pub fn develop(develop_options: DevelopOptions, venv_dir: &Path) -> Result<()> { .as_ref() .is_some_and(|p| !p.warn_invalid_version_info()) { - bail!("Cannot build without valid version information. \ - You need to specify either `project.version` or `project.dynamic = [\"version\"]` in pyproject.toml."); + bail!( + "Cannot build without valid version information. \ + You need to specify either `project.version` or `project.dynamic = [\"version\"]` in pyproject.toml." + ); } let interpreter = @@ -531,7 +534,9 @@ Files: my_project-0.1.0+abc123de.dist-info/entry_points.txt my_project.pth "; - let expected_path = PathBuf::from("/foo bar/venv/lib/pythonABC/site-packages/my_project-0.1.0+abc123de.dist-info/direct_url.json"); + let expected_path = PathBuf::from( + "/foo bar/venv/lib/pythonABC/site-packages/my_project-0.1.0+abc123de.dist-info/direct_url.json", + ); assert_eq!( parse_direct_url_path(example_with_direct_url).unwrap(), Some(expected_path) @@ -575,7 +580,9 @@ Files:\r my_project.pth\r "; - let expected_path = PathBuf::from("C:\\foo bar\\venv\\Lib\\site-packages\\my_project-0.1.0+abc123de.dist-info\\direct_url.json"); + let expected_path = PathBuf::from( + "C:\\foo bar\\venv\\Lib\\site-packages\\my_project-0.1.0+abc123de.dist-info\\direct_url.json", + ); assert_eq!( parse_direct_url_path(example_with_direct_url_windows).unwrap(), Some(expected_path) diff --git a/src/generate_json_schema.rs b/src/generate_json_schema.rs index 21e2e30cb..db0b70270 100644 --- a/src/generate_json_schema.rs +++ b/src/generate_json_schema.rs @@ -3,7 +3,7 @@ use fs_err as fs; use std::path::PathBuf; -use anyhow::{bail, Result}; +use anyhow::{Result, bail}; use pretty_assertions::StrComparison; use schemars::schema_for; @@ -46,7 +46,9 @@ pub fn generate_json_schema(args: GenerateJsonSchemaOptions) -> Result<()> { println!("Up-to-date: {filename}"); } else { let comparison = StrComparison::new(¤t, &schema_string); - bail!("{filename} changed, please run `cargo run --features schemars -- generate-json-schema`:\n{comparison}",); + bail!( + "{filename} changed, please run `cargo run --features schemars -- generate-json-schema`:\n{comparison}", + ); } } Mode::Write => { diff --git a/src/lib.rs b/src/lib.rs index b4399bb0f..861ce1633 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,22 +27,22 @@ pub use crate::bridge::{Abi3Version, BridgeModel, PyO3, PyO3Crate}; pub use crate::build_context::{BuildContext, BuiltWheelMetadata}; pub use crate::build_options::{BuildOptions, CargoOptions, TargetTriple}; pub use crate::cargo_toml::CargoToml; -pub use crate::compile::{compile, BuildArtifact}; +pub use crate::compile::{BuildArtifact, compile}; pub use crate::compression::{CompressionMethod, CompressionOptions}; -pub use crate::develop::{develop, DevelopOptions}; +pub use crate::develop::{DevelopOptions, develop}; #[cfg(feature = "schemars")] -pub use crate::generate_json_schema::{generate_json_schema, GenerateJsonSchemaOptions, Mode}; +pub use crate::generate_json_schema::{GenerateJsonSchemaOptions, Mode, generate_json_schema}; pub use crate::metadata::{Metadata24, WheelMetadata}; pub use crate::module_writer::{ - write_dist_info, ModuleWriter, PathWriter, SDistWriter, WheelWriter, + ModuleWriter, PathWriter, SDistWriter, WheelWriter, write_dist_info, }; #[cfg(feature = "scaffolding")] -pub use crate::new_project::{init_project, new_project, GenerateProjectOptions}; +pub use crate::new_project::{GenerateProjectOptions, init_project, new_project}; pub use crate::pyproject_toml::PyProjectToml; pub use crate::python_interpreter::PythonInterpreter; pub use crate::source_distribution::find_path_deps; #[cfg(feature = "upload")] -pub use crate::upload::{upload, upload_ui, PublishOpt, Registry, UploadError}; +pub use crate::upload::{PublishOpt, Registry, UploadError, upload, upload_ui}; pub use auditwheel::PlatformTag; pub use target::Target; diff --git a/src/main.rs b/src/main.rs index d7aeb4a1a..2697d0b3b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,29 +3,29 @@ //! //! Run with --help for usage information -use anyhow::{bail, Context, Result}; +use anyhow::{Context, Result, bail}; use cargo_options::heading; #[cfg(feature = "zig")] use cargo_zigbuild::Zig; #[cfg(feature = "cli-completion")] use clap::CommandFactory; use clap::{Parser, Subcommand}; -#[cfg(feature = "scaffolding")] -use maturin::{ci::GenerateCI, init_project, new_project, GenerateProjectOptions}; use maturin::{ - develop, find_path_deps, write_dist_info, BridgeModel, BuildOptions, CargoOptions, - DevelopOptions, PathWriter, PythonInterpreter, Target, TargetTriple, + BridgeModel, BuildOptions, CargoOptions, DevelopOptions, PathWriter, PythonInterpreter, Target, + TargetTriple, develop, find_path_deps, write_dist_info, }; #[cfg(feature = "schemars")] -use maturin::{generate_json_schema, GenerateJsonSchemaOptions}; +use maturin::{GenerateJsonSchemaOptions, generate_json_schema}; +#[cfg(feature = "scaffolding")] +use maturin::{GenerateProjectOptions, ci::GenerateCI, init_project, new_project}; #[cfg(feature = "upload")] -use maturin::{upload_ui, PublishOpt}; +use maturin::{PublishOpt, upload_ui}; use std::env; use std::path::PathBuf; use std::str::FromStr; use tracing::{debug, instrument}; use tracing_subscriber::filter::Directive; -use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter, Layer}; +use tracing_subscriber::{EnvFilter, Layer, layer::SubscriberExt, util::SubscriberInitExt}; #[derive(Debug, Parser)] #[command( diff --git a/src/metadata.rs b/src/metadata.rs index 0bf3867d6..e8c0c9adc 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -1,5 +1,5 @@ use crate::PyProjectToml; -use anyhow::{bail, format_err, Context, Result}; +use anyhow::{Context, Result, bail, format_err}; use fs_err as fs; use indexmap::IndexMap; use normpath::PathExt; @@ -7,7 +7,7 @@ use pep440_rs::{Version, VersionSpecifiers}; use pep508_rs::{ ExtraName, ExtraOperator, MarkerExpression, MarkerTree, MarkerValueExtra, Requirement, }; -use pyproject_toml::{check_pep639_glob, License}; +use pyproject_toml::{License, check_pep639_glob}; use regex::Regex; use serde::{Deserialize, Serialize}; use std::collections::{HashMap, HashSet}; @@ -218,7 +218,9 @@ impl Metadata24 { content_type, }) => { if file.is_some() && text.is_some() { - bail!("file and text fields of 'project.readme' are mutually-exclusive, only one of them should be specified"); + bail!( + "file and text fields of 'project.readme' are mutually-exclusive, only one of them should be specified" + ); } if let Some(readme_path) = file { let readme_path = pyproject_dir.join(readme_path); @@ -726,7 +728,7 @@ fn fold_header(text: &str) -> String { mod tests { use super::*; use cargo_metadata::MetadataCommand; - use expect_test::{expect, Expect}; + use expect_test::{Expect, expect}; use indoc::indoc; use pretty_assertions::assert_eq; use tempfile::TempDir; diff --git a/src/module_writer.rs b/src/module_writer.rs index 3fdadcc34..682a58793 100644 --- a/src/module_writer.rs +++ b/src/module_writer.rs @@ -2,20 +2,20 @@ use crate::compression::{CompressionMethod, CompressionOptions}; use crate::project_layout::ProjectLayout; use crate::target::Os; -use crate::{pyproject_toml::Format, Metadata24, PyProjectToml, PythonInterpreter, Target}; -use anyhow::{anyhow, bail, Context, Result}; -use base64::engine::general_purpose::URL_SAFE_NO_PAD; +use crate::{Metadata24, PyProjectToml, PythonInterpreter, Target, pyproject_toml::Format}; +use anyhow::{Context, Result, anyhow, bail}; use base64::Engine; -use flate2::write::GzEncoder; +use base64::engine::general_purpose::URL_SAFE_NO_PAD; use flate2::Compression; +use flate2::write::GzEncoder; use fs_err as fs; -#[cfg(unix)] -use fs_err::os::unix::fs::OpenOptionsExt; use fs_err::File; #[cfg(unix)] use fs_err::OpenOptions; -use ignore::overrides::Override; +#[cfg(unix)] +use fs_err::os::unix::fs::OpenOptionsExt; use ignore::WalkBuilder; +use ignore::overrides::Override; use indexmap::IndexMap; use itertools::Itertools; use normpath::PathExt as _; @@ -32,7 +32,7 @@ use std::os::unix::fs::PermissionsExt; use std::path::{Path, PathBuf}; use std::process::{Command, Output}; use std::str; -use tempfile::{tempdir, TempDir}; +use tempfile::{TempDir, tempdir}; use tracing::{debug, instrument}; use zip::{self, DateTime, ZipWriter}; @@ -297,7 +297,9 @@ impl WheelWriter { debug!("Adding {} from {}", target, python_path); self.add_bytes(target, None, python_path.as_bytes())?; } else { - eprintln!("⚠️ source code path contains non-Unicode sequences, editable installs may not work."); + eprintln!( + "⚠️ source code path contains non-Unicode sequences, editable installs may not work." + ); } } Ok(()) diff --git a/src/new_project.rs b/src/new_project.rs index d6bc4f0fb..0f791127d 100644 --- a/src/new_project.rs +++ b/src/new_project.rs @@ -1,11 +1,11 @@ use self::package_name_validations::{cargo_check_name, pypi_check_name}; use crate::ci::GenerateCI; use crate::{BridgeModel, PyO3}; -use anyhow::{bail, Context, Result}; +use anyhow::{Context, Result, bail}; use console::style; -use dialoguer::{theme::ColorfulTheme, Select}; +use dialoguer::{Select, theme::ColorfulTheme}; use fs_err as fs; -use minijinja::{context, Environment}; +use minijinja::{Environment, context}; use semver::Version; use std::path::Path; diff --git a/src/project_layout.rs b/src/project_layout.rs index cfdd66447..5c057dcc3 100644 --- a/src/project_layout.rs +++ b/src/project_layout.rs @@ -1,6 +1,6 @@ -use crate::build_options::{extract_cargo_metadata_args, CargoOptions}; +use crate::build_options::{CargoOptions, extract_cargo_metadata_args}; use crate::{CargoToml, Metadata24, PyProjectToml}; -use anyhow::{bail, format_err, Context, Result}; +use anyhow::{Context, Result, bail, format_err}; use cargo_metadata::{Metadata, MetadataCommand}; use normpath::PathExt as _; use std::collections::HashSet; diff --git a/src/pyproject_toml.rs b/src/pyproject_toml.rs index d7580e61e..3f8d53c74 100644 --- a/src/pyproject_toml.rs +++ b/src/pyproject_toml.rs @@ -1,7 +1,7 @@ //! A pyproject.toml as specified in PEP 517 -use crate::auditwheel::AuditWheelMode; use crate::PlatformTag; +use crate::auditwheel::AuditWheelMode; use anyhow::{Context, Result}; use fs_err as fs; use pep440_rs::Version; @@ -80,7 +80,7 @@ impl GlobPattern { pub fn targets(&self, format: Format) -> Option<&str> { match self { // Not specified defaults to both - Self::Path(ref glob) => Some(glob), + Self::Path(glob) => Some(glob), Self::WithFormat { path, format: formats, @@ -447,11 +447,15 @@ impl PyProjectToml { .as_ref() .is_some_and(|d| d.iter().any(|s| s == "version")); if has_static_version && has_dynamic_version { - eprintln!("⚠️ Warning: `project.dynamic` must not specify `version` when `project.version` is present in pyproject.toml"); + eprintln!( + "⚠️ Warning: `project.dynamic` must not specify `version` when `project.version` is present in pyproject.toml" + ); return false; } if !has_static_version && !has_dynamic_version { - eprintln!("⚠️ Warning: `project.version` field is required in pyproject.toml unless it is present in the `project.dynamic` list"); + eprintln!( + "⚠️ Warning: `project.version` field is required in pyproject.toml unless it is present in the `project.dynamic` list" + ); return false; } true @@ -461,8 +465,8 @@ impl PyProjectToml { #[cfg(test)] mod tests { use crate::{ - pyproject_toml::{Format, Formats, GlobPattern, ToolMaturin}, PyProjectToml, + pyproject_toml::{Format, Formats, GlobPattern, ToolMaturin}, }; use expect_test::expect; use fs_err as fs; diff --git a/src/python_interpreter/config.rs b/src/python_interpreter/config.rs index 6400fa954..7efb2b248 100644 --- a/src/python_interpreter/config.rs +++ b/src/python_interpreter/config.rs @@ -2,9 +2,9 @@ use super::{ InterpreterKind, MAXIMUM_PYPY_MINOR, MAXIMUM_PYTHON_MINOR, MINIMUM_PYPY_MINOR, MINIMUM_PYTHON_MINOR, }; -use crate::target::{Arch, Os}; use crate::Target; -use anyhow::{format_err, Context, Result}; +use crate::target::{Arch, Os}; +use anyhow::{Context, Result, format_err}; use fs_err as fs; use serde::Deserialize; use std::fmt::Write as _; @@ -109,7 +109,9 @@ impl InterpreterConfig { (Os::Linux, GraalPy) => { let (graalpy_major, graalpy_minor) = graalpy_version_for_python_version(major, minor)?; - let ext_suffix = format!(".graalpy{graalpy_major}{graalpy_minor}-{major}{minor}-native-{python_ext_arch}-linux.so"); + let ext_suffix = format!( + ".graalpy{graalpy_major}{graalpy_minor}-{major}{minor}-native-{python_ext_arch}-linux.so" + ); Some(Self { major, minor, @@ -153,7 +155,9 @@ impl InterpreterConfig { (Os::Macos, GraalPy) => { let (graalpy_major, graalpy_minor) = graalpy_version_for_python_version(major, minor)?; - let ext_suffix = format!(".graalpy{graalpy_major}{graalpy_minor}-{major}{minor}-native-{python_ext_arch}-darwin.so"); + let ext_suffix = format!( + ".graalpy{graalpy_major}{graalpy_minor}-{major}{minor}-native-{python_ext_arch}-darwin.so" + ); Some(Self { major, minor, diff --git a/src/python_interpreter/mod.rs b/src/python_interpreter/mod.rs index 2050f8a3f..5321cd025 100644 --- a/src/python_interpreter/mod.rs +++ b/src/python_interpreter/mod.rs @@ -2,7 +2,7 @@ pub use self::config::InterpreterConfig; use crate::auditwheel::PlatformTag; use crate::target::Arch; use crate::{BridgeModel, BuildContext, Target}; -use anyhow::{bail, ensure, format_err, Context, Result}; +use anyhow::{Context, Result, bail, ensure, format_err}; use pep440_rs::{Version, VersionSpecifiers}; use regex::Regex; use serde::Deserialize; @@ -329,7 +329,9 @@ fn fun_with_abiflags( Ok("".to_string()) } } else { - bail!("A python 3 interpreter on Windows does not define abiflags in its sysconfig before Python 3.14 ಠ_ಠ") + bail!( + "A python 3 interpreter on Windows does not define abiflags in its sysconfig before Python 3.14 ಠ_ಠ" + ) } } else if let Some(ref abiflags) = message.abiflags { if message.minor >= 8 { diff --git a/src/source_distribution.rs b/src/source_distribution.rs index 833e4a56a..1fd39ed55 100644 --- a/src/source_distribution.rs +++ b/src/source_distribution.rs @@ -1,7 +1,7 @@ use crate::module_writer::ModuleWriter; use crate::pyproject_toml::SdistGenerator; -use crate::{pyproject_toml::Format, BuildContext, PyProjectToml, SDistWriter}; -use anyhow::{bail, Context, Result}; +use crate::{BuildContext, PyProjectToml, SDistWriter, pyproject_toml::Format}; +use anyhow::{Context, Result, bail}; use cargo_metadata::camino::Utf8Path; use cargo_metadata::{Metadata, MetadataCommand, PackageId}; use fs_err as fs; @@ -72,7 +72,7 @@ fn rewrite_cargo_toml( } else { let mut new_members = toml_edit::Array::new(); for member in members { - if let toml_edit::Value::String(ref s) = member { + if let toml_edit::Value::String(s) = member { let member_path = s.value(); // See https://github.com/rust-lang/cargo/blob/0de91c89e6479016d0ed8719fdc2947044335b36/src/cargo/util/restricted_names.rs#L119-L122 let is_glob_pattern = member_path.contains(['*', '?', '[', ']']); @@ -889,9 +889,5 @@ where break; } } - if found { - Some(final_path) - } else { - None - } + if found { Some(final_path) } else { None } } diff --git a/src/target/mod.rs b/src/target/mod.rs index 7c6bff311..f3d4364d8 100644 --- a/src/target/mod.rs +++ b/src/target/mod.rs @@ -1,9 +1,9 @@ +use crate::PlatformTag; use crate::build_options::TargetTriple; use crate::cross_compile::is_cross_compiling; use crate::python_interpreter::InterpreterKind; use crate::python_interpreter::InterpreterKind::{CPython, GraalPy, PyPy}; -use crate::PlatformTag; -use anyhow::{anyhow, bail, format_err, Result}; +use anyhow::{Result, anyhow, bail, format_err}; use platform_info::*; use rustc_version::VersionMeta; use serde::Deserialize; diff --git a/src/target/pypi_tags.rs b/src/target/pypi_tags.rs index 7682cce87..176cc12ff 100644 --- a/src/target/pypi_tags.rs +++ b/src/target/pypi_tags.rs @@ -24,7 +24,7 @@ use crate::target::legacy_py::{ MUSLLINUX_ARCHES, WINDOWS_ARCHES, }; use crate::target::{Os, Target}; -use anyhow::{anyhow, bail, Result}; +use anyhow::{Result, anyhow, bail}; use target_lexicon::Environment; /// Check for target architectures that we know aren't supported by PyPI to error early. diff --git a/src/upload.rs b/src/upload.rs index f57eb465b..fd0e633de 100644 --- a/src/upload.rs +++ b/src/upload.rs @@ -2,9 +2,9 @@ //! documentation at https://warehouse.readthedocs.io/api-reference/legacy/#upload-api use crate::build_context::hash_file; -use anyhow::{bail, Context, Result}; -use base64::engine::general_purpose::STANDARD; +use anyhow::{Context, Result, bail}; use base64::Engine; +use base64::engine::general_purpose::STANDARD; use bytesize::ByteSize; use configparser::ini::Ini; use fs_err as fs; diff --git a/tests/common/develop.rs b/tests/common/develop.rs index 47f408fa8..ec48905cb 100644 --- a/tests/common/develop.rs +++ b/tests/common/develop.rs @@ -1,8 +1,8 @@ use crate::common::{ - check_installed, create_conda_env, create_virtualenv, maybe_mock_cargo, TestInstallBackend, + TestInstallBackend, check_installed, create_conda_env, create_virtualenv, maybe_mock_cargo, }; use anyhow::Result; -use maturin::{develop, CargoOptions, DevelopOptions}; +use maturin::{CargoOptions, DevelopOptions, develop}; use std::path::{Path, PathBuf}; use std::process::Command; use std::str; diff --git a/tests/common/errors.rs b/tests/common/errors.rs index 7c6abd285..fa32505df 100644 --- a/tests/common/errors.rs +++ b/tests/common/errors.rs @@ -1,5 +1,5 @@ use anyhow::format_err; -use anyhow::{bail, Result}; +use anyhow::{Result, bail}; use clap::Parser; use maturin::BuildOptions; use pretty_assertions::assert_eq; @@ -108,7 +108,10 @@ pub fn invalid_manylinux_does_not_panic() -> Result<()> { .source() .ok_or_else(|| format_err!("{}", err))? .to_string(); - assert_eq!(err_string, "manylinux_2_99 compatibility policy is not defined by auditwheel yet, pass `--auditwheel=skip` to proceed anyway"); + assert_eq!( + err_string, + "manylinux_2_99 compatibility policy is not defined by auditwheel yet, pass `--auditwheel=skip` to proceed anyway" + ); } else { bail!("Should have errored"); } @@ -137,7 +140,9 @@ pub fn warn_on_missing_python_source() -> Result<()> { ); } - assert!(str::from_utf8(&output.stderr)?.contains("Warning: You specified the python source as")); + assert!( + str::from_utf8(&output.stderr)?.contains("Warning: You specified the python source as") + ); Ok(()) } diff --git a/tests/common/integration.rs b/tests/common/integration.rs index 3e821c144..60e139d0e 100644 --- a/tests/common/integration.rs +++ b/tests/common/integration.rs @@ -1,12 +1,12 @@ use crate::common::{ check_installed, create_named_virtualenv, create_virtualenv, maybe_mock_cargo, test_python_path, }; -use anyhow::{bail, Context, Result}; +use anyhow::{Context, Result, bail}; #[cfg(feature = "zig")] use cargo_zigbuild::Zig; use clap::Parser; -use fs4::fs_err3::FileExt; use fs_err::File; +use fs4::fs_err3::FileExt; use maturin::{BuildOptions, PlatformTag, PythonInterpreter, Target}; use normpath::PathExt; use std::collections::HashSet; @@ -27,10 +27,12 @@ pub fn test_integration( maybe_mock_cargo(); // Pass CARGO_BIN_EXE_maturin for testing purpose - env::set_var( - "CARGO_BIN_EXE_cargo-zigbuild", - env!("CARGO_BIN_EXE_maturin"), - ); + unsafe { + env::set_var( + "CARGO_BIN_EXE_cargo-zigbuild", + env!("CARGO_BIN_EXE_maturin"), + ) + }; let package_string = package.as_ref().join("Cargo.toml").display().to_string(); diff --git a/tests/common/metadata.rs b/tests/common/metadata.rs index 97167f9b4..a8f1385bd 100644 --- a/tests/common/metadata.rs +++ b/tests/common/metadata.rs @@ -1,6 +1,6 @@ use anyhow::Result; use insta::assert_snapshot; -use maturin::{write_dist_info, BuildOptions, CargoOptions, ModuleWriter}; +use maturin::{BuildOptions, CargoOptions, ModuleWriter, write_dist_info}; use std::collections::HashMap; use std::path::{Path, PathBuf}; diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 6264f3b8d..d9aa1a47c 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -1,4 +1,4 @@ -use anyhow::{bail, Result}; +use anyhow::{Result, bail}; use fs_err as fs; use maturin::Target; use normpath::PathExt as _; @@ -80,7 +80,7 @@ pub fn maybe_mock_cargo() { path_split.insert(0, mock_cargo_path); let new_path = env::join_paths(path_split).expect("Expected to be able to re-join PATH"); - env::set_var("PATH", new_path); + unsafe { env::set_var("PATH", new_path) }; } } drop(handle); diff --git a/tests/run.rs b/tests/run.rs index 496a3186c..b5873804f 100644 --- a/tests/run.rs +++ b/tests/run.rs @@ -1,8 +1,8 @@ //! To speed up the tests, they are tests all collected in a single module use common::{ - develop, errors, handle_result, integration, other, test_python_implementation, - TestInstallBackend, + TestInstallBackend, develop, errors, handle_result, integration, other, + test_python_implementation, }; use expect_test::expect; use maturin::pyproject_toml::SdistGenerator; @@ -526,16 +526,18 @@ fn integration_wasm_hello_world() { format!("integration-wasm-hello-world-py3-wasm32-wasip1-{python_implementation}"); // Make sure we're actually running wasm - assert!(Path::new("test-crates") - .join("venvs") - .join(venv_name) - .join(if cfg!(target_os = "windows") { - "Scripts" - } else { - "bin" - }) - .join("hello-world.wasm") - .is_file()) + assert!( + Path::new("test-crates") + .join("venvs") + .join(venv_name) + .join(if cfg!(target_os = "windows") { + "Scripts" + } else { + "bin" + }) + .join("hello-world.wasm") + .is_file() + ) } #[test] @@ -970,7 +972,7 @@ fn abi3_python_interpreter_args() { #[test] #[serial(source_date_epoch_env)] fn pyo3_source_date_epoch() { - env::set_var("SOURCE_DATE_EPOCH", "0"); + unsafe { env::set_var("SOURCE_DATE_EPOCH", "0") }; handle_result(other::check_wheel_mtimes( "test-crates/pyo3-mixed-include-exclude", vec![datetime!(1980-01-01 0:00 UTC)], @@ -981,7 +983,7 @@ fn pyo3_source_date_epoch() { #[test] #[serial(source_date_epoch_env)] fn sdist_no_source_date_epoch() { - env::remove_var("SOURCE_DATE_EPOCH"); + unsafe { env::remove_var("SOURCE_DATE_EPOCH") }; handle_result(other::check_sdist_mtimes( "test-crates/pyo3-mixed-include-exclude", 1153704088, @@ -992,7 +994,7 @@ fn sdist_no_source_date_epoch() { #[test] #[serial(source_date_epoch_env)] fn sdist_source_date_epoch() { - env::set_var("SOURCE_DATE_EPOCH", "1"); + unsafe { env::set_var("SOURCE_DATE_EPOCH", "1") }; handle_result(other::check_sdist_mtimes( "test-crates/pyo3-mixed-include-exclude", 1,