From 0319b8cf2b11672b9488c867193458c08aad051b Mon Sep 17 00:00:00 2001 From: Matthijs Brobbel Date: Tue, 8 Nov 2022 15:35:11 +0100 Subject: [PATCH 01/17] Add `[tool.maturin.include]` and `[tool.maturin.exclude]` --- guide/src/metadata.md | 5 ++ src/build_context.rs | 74 +++++++++++++++--- src/lib.rs | 2 +- src/module_writer.rs | 129 +++++++++++++++++++++++++++++-- src/pyproject_toml.rs | 151 ++++++++++++++++++++++++++++++++++++- src/source_distribution.rs | 47 ++++++++---- 6 files changed, 375 insertions(+), 33 deletions(-) diff --git a/guide/src/metadata.md b/guide/src/metadata.md index 0b10ac556..4b0088689 100644 --- a/guide/src/metadata.md +++ b/guide/src/metadata.md @@ -108,7 +108,12 @@ in the `tool.maturin` section of `pyproject.toml`. ```toml [tool.maturin] # Include arbitrary files in the sdist +# NOTE: deprecated, please use `include` with `format="sdist"` sdist-include = [] +# Include additional files +include = [] +# Exclude files +exclude = [] # Bindings type bindings = "pyo3" # Control the platform tag on linux diff --git a/src/build_context.rs b/src/build_context.rs index 37ed2369b..a95f56a31 100644 --- a/src/build_context.rs +++ b/src/build_context.rs @@ -10,12 +10,15 @@ use crate::project_layout::ProjectLayout; use crate::python_interpreter::InterpreterKind; use crate::source_distribution::source_distribution; use crate::{ - compile, BuildArtifact, Metadata21, ModuleWriter, PyProjectToml, PythonInterpreter, Target, + compile, BuildArtifact, Format, Metadata21, ModuleWriter, PyProjectToml, PythonInterpreter, + Target, }; use anyhow::{anyhow, bail, Context, Result}; use cargo_metadata::Metadata; use fs_err as fs; +use ignore::overrides::{Override, OverrideBuilder}; use lddtree::Library; +use normpath::PathExt; use regex::Regex; use sha2::{Digest, Sha256}; use std::collections::{HashMap, HashSet}; @@ -249,8 +252,9 @@ impl BuildContext { match self.pyproject_toml.as_ref() { Some(pyproject) => { - let sdist_path = source_distribution(self, pyproject) - .context("Failed to build source distribution")?; + let sdist_path = + source_distribution(self, pyproject, self.excludes(Format::Sdist)?) + .context("Failed to build source distribution")?; Ok(Some((sdist_path, "source".to_string()))) } None => Ok(None), @@ -450,6 +454,23 @@ impl BuildContext { Ok(()) } + fn excludes(&self, format: Format) -> Result> { + if let Some(pyproject) = self.pyproject_toml.as_ref() { + let pyproject_dir = self.pyproject_toml_path.normalize()?.into_path_buf(); + if let Some(glob_patterns) = &pyproject.exclude() { + let mut excludes = OverrideBuilder::new(pyproject_dir.parent().unwrap()); + for glob in glob_patterns + .iter() + .filter_map(|glob_pattern| glob_pattern.targets(format)) + { + excludes.add(glob)?; + } + return Ok(Some(excludes.build()?)); + } + } + Ok(None) + } + fn write_binding_wheel_abi3( &self, artifact: BuildArtifact, @@ -463,7 +484,13 @@ impl BuildContext { .get_platform_tag(platform_tags, self.universal2)?; let tag = format!("cp{}{}-abi3-{}", major, min_minor, platform); - let mut writer = WheelWriter::new(&tag, &self.out, &self.metadata21, &[tag.clone()])?; + let mut writer = WheelWriter::new( + &tag, + &self.out, + &self.metadata21, + &[tag.clone()], + self.excludes(Format::Wheel)?, + )?; self.add_external_libs(&mut writer, &[&artifact], &[ext_libs])?; write_bindings_module( @@ -474,6 +501,8 @@ impl BuildContext { None, &self.target, self.editable, + &self.metadata21, + self.pyproject_toml.as_ref(), ) .context("Failed to add the files to the wheel")?; @@ -534,7 +563,13 @@ impl BuildContext { ) -> Result { let tag = python_interpreter.get_tag(&self.target, platform_tags, self.universal2)?; - let mut writer = WheelWriter::new(&tag, &self.out, &self.metadata21, &[tag.clone()])?; + let mut writer = WheelWriter::new( + &tag, + &self.out, + &self.metadata21, + &[tag.clone()], + self.excludes(Format::Wheel)?, + )?; self.add_external_libs(&mut writer, &[&artifact], &[ext_libs])?; write_bindings_module( @@ -545,6 +580,8 @@ impl BuildContext { Some(python_interpreter), &self.target, self.editable, + &self.metadata21, + self.pyproject_toml.as_ref(), ) .context("Failed to add the files to the wheel")?; @@ -651,7 +688,13 @@ impl BuildContext { .target .get_universal_tags(platform_tags, self.universal2)?; - let mut writer = WheelWriter::new(&tag, &self.out, &self.metadata21, &tags)?; + let mut writer = WheelWriter::new( + &tag, + &self.out, + &self.metadata21, + &tags, + self.excludes(Format::Wheel)?, + )?; self.add_external_libs(&mut writer, &[&artifact], &[ext_libs])?; write_cffi_module( @@ -663,6 +706,8 @@ impl BuildContext { &artifact.path, &self.interpreter[0].executable, self.editable, + &self.metadata21, + self.pyproject_toml.as_ref(), )?; self.add_pth(&mut writer)?; @@ -754,7 +799,13 @@ impl BuildContext { self.metadata21.clone() }; - let mut writer = WheelWriter::new(&tag, &self.out, &metadata21, &tags)?; + let mut writer = WheelWriter::new( + &tag, + &self.out, + &metadata21, + &tags, + self.excludes(Format::Wheel)?, + )?; if let Some(python_module) = &self.project_layout.python_module { if self.target.is_wasi() { @@ -763,8 +814,13 @@ impl BuildContext { bail!("Sorry, adding python code to a wasm binary is currently not supported") } if !self.editable { - write_python_part(&mut writer, python_module) - .context("Failed to add the python module to the package")?; + write_python_part( + &mut writer, + python_module, + &metadata21, + self.pyproject_toml.as_ref(), + ) + .context("Failed to add the python module to the package")?; } } diff --git a/src/lib.rs b/src/lib.rs index 89fb65583..2ffb156bb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,7 +35,7 @@ pub use crate::module_writer::{ write_dist_info, ModuleWriter, PathWriter, SDistWriter, WheelWriter, }; pub use crate::new_project::{init_project, new_project, GenerateProjectOptions}; -pub use crate::pyproject_toml::PyProjectToml; +pub use crate::pyproject_toml::{Format, Formats, GlobPattern, PyProjectToml}; pub use crate::python_interpreter::PythonInterpreter; pub use crate::target::Target; #[cfg(feature = "upload")] diff --git a/src/module_writer.rs b/src/module_writer.rs index 00cf053ed..983d1c25b 100644 --- a/src/module_writer.rs +++ b/src/module_writer.rs @@ -1,11 +1,12 @@ //! The wheel format is (mostly) specified in PEP 427 use crate::project_layout::ProjectLayout; -use crate::{BridgeModel, Metadata21, PythonInterpreter, Target}; +use crate::{BridgeModel, Format, Metadata21, PyProjectToml, PythonInterpreter, Target}; use anyhow::{anyhow, bail, Context, Result}; use flate2::write::GzEncoder; use flate2::Compression; use fs_err as fs; use fs_err::File; +use ignore::overrides::Override; use ignore::WalkBuilder; use normpath::PathExt as _; use sha2::{Digest, Sha256}; @@ -202,6 +203,7 @@ pub struct WheelWriter { record: Vec<(String, String, usize)>, record_file: PathBuf, wheel_path: PathBuf, + excludes: Option, } impl ModuleWriter for WheelWriter { @@ -215,8 +217,12 @@ impl ModuleWriter for WheelWriter { bytes: &[u8], permissions: u32, ) -> Result<()> { + let target = target.as_ref(); + if self.exclude(target) { + return Ok(()); + } // The zip standard mandates using unix style paths - let target = target.as_ref().to_str().unwrap().replace('\\', "/"); + let target = target.to_str().unwrap().replace('\\', "/"); // Unlike users which can use the develop subcommand, the tests have to go through // packing a zip which pip than has to unpack. This makes this 2-3 times faster @@ -247,6 +253,7 @@ impl WheelWriter { wheel_dir: &Path, metadata21: &Metadata21, tags: &[String], + excludes: Option, ) -> Result { let wheel_path = wheel_dir.join(format!( "{}-{}-{}.whl", @@ -262,6 +269,7 @@ impl WheelWriter { record: Vec::new(), record_file: metadata21.get_dist_info_dir().join("RECORD"), wheel_path, + excludes, }; write_dist_info(&mut builder, metadata21, tags)?; @@ -289,6 +297,15 @@ impl WheelWriter { Ok(()) } + /// Returns `true` if the given path should be excluded + fn exclude(&self, path: impl AsRef) -> bool { + if let Some(excludes) = &self.excludes { + excludes.matched(path.as_ref(), false).is_whitelist() + } else { + false + } + } + /// Creates the record file and finishes the zip pub fn finish(mut self) -> Result { let compression_method = if cfg!(feature = "faster-tests") { @@ -318,6 +335,7 @@ pub struct SDistWriter { tar: tar::Builder>, path: PathBuf, files: HashSet, + excludes: Option, } impl ModuleWriter for SDistWriter { @@ -332,6 +350,10 @@ impl ModuleWriter for SDistWriter { permissions: u32, ) -> Result<()> { let target = target.as_ref(); + if self.exclude(target) { + return Ok(()); + } + if self.files.contains(target) { // Ignore duplicate files return Ok(()); @@ -354,6 +376,9 @@ impl ModuleWriter for SDistWriter { fn add_file(&mut self, target: impl AsRef, source: impl AsRef) -> Result<()> { let source = source.as_ref(); + if self.exclude(source) { + return Ok(()); + } let target = target.as_ref(); if source == self.path { bail!( @@ -381,7 +406,11 @@ impl ModuleWriter for SDistWriter { impl SDistWriter { /// Create a source distribution .tar.gz which can be subsequently expanded - pub fn new(wheel_dir: impl AsRef, metadata21: &Metadata21) -> Result { + pub fn new( + wheel_dir: impl AsRef, + metadata21: &Metadata21, + excludes: Option, + ) -> Result { let path = wheel_dir.as_ref().join(format!( "{}-{}.tar.gz", &metadata21.get_distribution_escaped(), @@ -396,9 +425,19 @@ impl SDistWriter { tar, path, files: HashSet::new(), + excludes, }) } + /// Returns `true` if the given path should be excluded + fn exclude(&self, path: impl AsRef) -> bool { + if let Some(excludes) = &self.excludes { + excludes.matched(path.as_ref(), false).is_whitelist() + } else { + false + } + } + /// Finished the .tar.gz archive pub fn finish(mut self) -> Result { self.tar.finish()?; @@ -634,6 +673,8 @@ pub fn write_bindings_module( python_interpreter: Option<&PythonInterpreter>, target: &Target, editable: bool, + metadata: &Metadata21, + pyproject_toml: Option<&PyProjectToml>, ) -> Result<()> { let ext_name = &project_layout.extension_name; let so_filename = match python_interpreter { @@ -664,7 +705,7 @@ pub fn write_bindings_module( target.display() ))?; } else { - write_python_part(writer, python_module) + write_python_part(writer, python_module, metadata, pyproject_toml) .context("Failed to add the python module to the package")?; let relative = project_layout @@ -714,6 +755,8 @@ pub fn write_cffi_module( artifact: &Path, python: &Path, editable: bool, + metadata21: &Metadata21, + pyproject_toml: Option<&PyProjectToml>, ) -> Result<()> { let cffi_declarations = generate_cffi_declarations(crate_dir, target_dir, python)?; @@ -721,7 +764,7 @@ pub fn write_cffi_module( if let Some(python_module) = &project_layout.python_module { if !editable { - write_python_part(writer, python_module) + write_python_part(writer, python_module, metadata21, pyproject_toml) .context("Failed to add the python module to the package")?; } @@ -848,11 +891,14 @@ if __name__ == '__main__': pub fn write_python_part( writer: &mut impl ModuleWriter, python_module: impl AsRef, + metadata21: &Metadata21, + pyproject_toml: Option<&PyProjectToml>, ) -> Result<()> { - for absolute in WalkBuilder::new(&python_module).hidden(false).build() { + let python_module = python_module.as_ref(); + for absolute in WalkBuilder::new(python_module).hidden(false).build() { let absolute = absolute?.into_path(); let relative = absolute - .strip_prefix(python_module.as_ref().parent().unwrap()) + .strip_prefix(python_module.parent().unwrap()) .unwrap(); if absolute.is_dir() { writer.add_directory(relative)?; @@ -870,6 +916,34 @@ pub fn write_python_part( } } + // Include additional files + if let Some(pyproject) = pyproject_toml { + let root_dir = PathBuf::from(format!( + "{}-{}", + &metadata21.get_distribution_escaped(), + &metadata21.get_version_escaped() + )); + if let Some(glob_patterns) = pyproject.include() { + for pattern in glob_patterns + .iter() + .filter_map(|glob_pattern| glob_pattern.targets(Format::Sdist)) + { + println!("📦 Including files matching \"{}\"", pattern); + for source in glob::glob(&python_module.join(pattern).to_string_lossy()) + .expect("No files found for pattern") + .filter_map(Result::ok) + { + let target = root_dir.join(source.strip_prefix(python_module).unwrap()); + if source.is_dir() { + writer.add_directory(target)?; + } else { + writer.add_file(target, source)?; + } + } + } + } + } + Ok(()) } @@ -972,3 +1046,44 @@ pub fn add_data(writer: &mut impl ModuleWriter, data: Option<&Path>) -> Result<( } Ok(()) } + +#[cfg(test)] +mod tests { + use ignore::overrides::OverrideBuilder; + + use super::*; + + #[test] + // The mechanism is the same for wheel_writer + fn sdist_writer_excludes() -> Result<(), Box> { + let metadata = Metadata21::default(); + let perm = 0o777; + + // No excludes + let tmp_dir = TempDir::new()?; + let mut writer = SDistWriter::new(&tmp_dir, &metadata, None)?; + assert!(writer.files.is_empty()); + writer.add_bytes_with_permissions("test", &[], perm)?; + assert_eq!(writer.files.len(), 1); + writer.finish()?; + tmp_dir.close()?; + + // A test filter + let tmp_dir = TempDir::new()?; + let mut excludes = OverrideBuilder::new(&tmp_dir); + excludes.add("test*")?; + excludes.add("!test2")?; + let mut writer = SDistWriter::new(&tmp_dir, &metadata, Some(excludes.build()?))?; + writer.add_bytes_with_permissions("test1", &[], perm)?; + writer.add_bytes_with_permissions("test3", &[], perm)?; + assert!(writer.files.is_empty()); + writer.add_bytes_with_permissions("test2", &[], perm)?; + assert!(!writer.files.is_empty()); + writer.add_bytes_with_permissions("yes", &[], perm)?; + assert_eq!(writer.files.len(), 2); + writer.finish()?; + tmp_dir.close()?; + + Ok(()) + } +} diff --git a/src/pyproject_toml.rs b/src/pyproject_toml.rs index cd0629ccb..dfac6bfcb 100644 --- a/src/pyproject_toml.rs +++ b/src/pyproject_toml.rs @@ -12,12 +12,82 @@ pub struct Tool { maturin: Option, } +#[derive(Copy, Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] +#[serde(rename_all = "lowercase")] +/// The target format for the include or exclude [GlobPattern]. +/// +/// See [Formats]. +pub enum Format { + /// Source distribution + Sdist, + /// Wheel + Wheel, +} + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] +#[serde(untagged)] +/// A single [Format] or multiple [Format] values for a [GlobPattern]. +pub enum Formats { + /// A single [Format] value + Single(Format), + /// Multiple [Format] values + Multiple(Vec), +} + +impl Formats { + /// Returns `true` if the inner [Format] value(s) target the given [Format] + pub fn targets(&self, format: Format) -> bool { + match self { + Self::Single(val) if val == &format => true, + Self::Multiple(formats) if formats.contains(&format) => true, + _ => false, + } + } +} + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] +#[serde(untagged)] +/// A glob pattern for the include and exclude configuration. +/// +/// See [PyProjectToml::include] and [PyProject::exclude]. +/// +/// Based on . +pub enum GlobPattern { + /// A glob + Path(String), + /// A glob `path` with a `format` key to specify one ore more [Format] values + WithFormat { + /// A glob + path: String, + /// One ore more [Format] values + format: Formats, + }, +} + +impl GlobPattern { + /// Returns the glob pattern for this patter if it targets the given [Format], else this returns `None`. + pub fn targets(&self, format: Format) -> Option<&str> { + match self { + // Not specified defaults to both + Self::Path(ref glob) => Some(glob), + Self::WithFormat { + path, + format: formats, + } if formats.targets(format) => Some(path), + _ => None, + } + } +} + /// The `[tool.maturin]` section of a pyproject.toml #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(rename_all = "kebab-case")] pub struct ToolMaturin { // maturin specific options + // TODO(0.15.0): remove deprecated sdist_include: Option>, + include: Option>, + exclude: Option>, bindings: Option, #[serde(alias = "manylinux")] compatibility: Option, @@ -98,10 +168,24 @@ impl PyProjectToml { } /// Returns the value of `[tool.maturin.sdist-include]` in pyproject.toml + #[deprecated( + since = "0.14.0", + note = "please use `PyProjectToml::include` ()" + )] pub fn sdist_include(&self) -> Option<&Vec> { self.maturin()?.sdist_include.as_ref() } + /// Returns the value of `[tool.maturin.include]` in pyproject.toml + pub fn include(&self) -> Option<&[GlobPattern]> { + self.maturin()?.include.as_ref().map(AsRef::as_ref) + } + + /// Returns the value of `[tool.maturin.exclude]` in pyproject.toml + pub fn exclude(&self) -> Option<&[GlobPattern]> { + self.maturin()?.exclude.as_ref().map(AsRef::as_ref) + } + /// Returns the value of `[tool.maturin.bindings]` in pyproject.toml pub fn bindings(&self) -> Option<&str> { self.maturin()?.bindings.as_deref() @@ -193,7 +277,10 @@ impl PyProjectToml { #[cfg(test)] mod tests { - use crate::PyProjectToml; + use crate::{ + pyproject_toml::{Format, Formats, GlobPattern, ToolMaturin}, + PyProjectToml, + }; use fs_err as fs; use pretty_assertions::assert_eq; use std::path::Path; @@ -261,4 +348,66 @@ mod tests { let without_constraint = PyProjectToml::new(pyproject_file).unwrap(); assert!(!without_constraint.warn_missing_maturin_version()); } + + #[test] + fn deserialize_include_exclude() { + let single = r#"include = ["single"]"#; + assert_eq!( + toml_edit::easy::from_str::(single) + .unwrap() + .include, + Some(vec![GlobPattern::Path("single".to_string())]) + ); + + let multiple = r#"include = ["one", "two"]"#; + assert_eq!( + toml_edit::easy::from_str::(multiple) + .unwrap() + .include, + Some(vec![ + GlobPattern::Path("one".to_string()), + GlobPattern::Path("two".to_string()) + ]) + ); + + let single_format = r#"include = [{path = "path", format="sdist"}]"#; + assert_eq!( + toml_edit::easy::from_str::(single_format) + .unwrap() + .include, + Some(vec![GlobPattern::WithFormat { + path: "path".to_string(), + format: Formats::Single(Format::Sdist) + },]) + ); + + let multiple_formats = r#"include = [{path = "path", format=["sdist", "wheel"]}]"#; + assert_eq!( + toml_edit::easy::from_str::(multiple_formats) + .unwrap() + .include, + Some(vec![GlobPattern::WithFormat { + path: "path".to_string(), + format: Formats::Multiple(vec![Format::Sdist, Format::Wheel]) + },]) + ); + + let mixed = r#"include = ["one", {path = "two", format="sdist"}, {path = "three", format=["sdist", "wheel"]}]"#; + assert_eq!( + toml_edit::easy::from_str::(mixed) + .unwrap() + .include, + Some(vec![ + GlobPattern::Path("one".to_string()), + GlobPattern::WithFormat { + path: "two".to_string(), + format: Formats::Single(Format::Sdist), + }, + GlobPattern::WithFormat { + path: "three".to_string(), + format: Formats::Multiple(vec![Format::Sdist, Format::Wheel]) + } + ]) + ); + } } diff --git a/src/source_distribution.rs b/src/source_distribution.rs index 909d1d27e..7b8ee35e9 100644 --- a/src/source_distribution.rs +++ b/src/source_distribution.rs @@ -1,15 +1,16 @@ use crate::module_writer::{add_data, ModuleWriter}; use crate::polyfill::MetadataCommandExt; -use crate::{BuildContext, PyProjectToml, SDistWriter}; +use crate::{BuildContext, Format, PyProjectToml, SDistWriter}; use anyhow::{bail, Context, Result}; use cargo_metadata::{Metadata, MetadataCommand}; use fs_err as fs; +use ignore::overrides::Override; use normpath::PathExt as _; use std::collections::HashMap; use std::path::{Path, PathBuf}; use std::process::Command; use std::str; -use tracing::debug; +use tracing::{debug, warn}; const LOCAL_DEPENDENCIES_FOLDER: &str = "local_dependencies"; /// Inheritable workspace fields, see @@ -411,6 +412,7 @@ fn find_path_deps(cargo_metadata: &Metadata) -> Result> pub fn source_distribution( build_context: &BuildContext, pyproject: &PyProjectToml, + excludes: Option, ) -> Result { let metadata21 = &build_context.metadata21; let manifest_path = &build_context.manifest_path; @@ -427,7 +429,7 @@ pub fn source_distribution( let known_path_deps = find_path_deps(&build_context.cargo_metadata)?; - let mut writer = SDistWriter::new(&build_context.out, metadata21)?; + let mut writer = SDistWriter::new(&build_context.out, metadata21, excludes)?; let root_dir = PathBuf::from(format!( "{}-{}", &metadata21.get_distribution_escaped(), @@ -551,20 +553,35 @@ pub fn source_distribution( } } + let mut include = |pattern| -> Result<()> { + println!("📦 Including files matching \"{}\"", pattern); + for source in glob::glob(&pyproject_dir.join(pattern).to_string_lossy()) + .expect("No files found for pattern") + .filter_map(Result::ok) + { + let target = root_dir.join(source.strip_prefix(pyproject_dir).unwrap()); + if source.is_dir() { + writer.add_directory(target)?; + } else { + writer.add_file(target, source)?; + } + } + Ok(()) + }; + if let Some(include_targets) = pyproject.sdist_include() { + warn!("`[tool.maturin.sdist-include]` is deprecated, please use `[tool.maturin.include]`"); for pattern in include_targets { - println!("📦 Including files matching \"{}\"", pattern); - for source in glob::glob(&pyproject_dir.join(pattern).to_string_lossy()) - .expect("No files found for pattern") - .filter_map(Result::ok) - { - let target = root_dir.join(source.strip_prefix(pyproject_dir).unwrap()); - if source.is_dir() { - writer.add_directory(target)?; - } else { - writer.add_file(target, source)?; - } - } + include(pattern.as_str())?; + } + } + + if let Some(glob_patterns) = pyproject.include() { + for pattern in glob_patterns + .iter() + .filter_map(|glob_pattern| glob_pattern.targets(Format::Sdist)) + { + include(pattern)?; } } From 1b925be39c7d27d084bda0c8b7e6c9acdcbdaee6 Mon Sep 17 00:00:00 2001 From: Matthijs Brobbel Date: Tue, 8 Nov 2022 16:07:19 +0100 Subject: [PATCH 02/17] Add Clippy exception for internal use of deprecated `sdist_include` --- src/source_distribution.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/source_distribution.rs b/src/source_distribution.rs index 7b8ee35e9..b7af389d1 100644 --- a/src/source_distribution.rs +++ b/src/source_distribution.rs @@ -569,6 +569,7 @@ pub fn source_distribution( Ok(()) }; + #[allow(deprecated)] if let Some(include_targets) = pyproject.sdist_include() { warn!("`[tool.maturin.sdist-include]` is deprecated, please use `[tool.maturin.include]`"); for pattern in include_targets { From d8b49b9d479ab7843450c7689db2c6081343c2c5 Mon Sep 17 00:00:00 2001 From: Matthijs Brobbel Date: Tue, 8 Nov 2022 16:09:31 +0100 Subject: [PATCH 03/17] Fix some spellcheck problems --- src/pyproject_toml.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pyproject_toml.rs b/src/pyproject_toml.rs index dfac6bfcb..a78959fe4 100644 --- a/src/pyproject_toml.rs +++ b/src/pyproject_toml.rs @@ -55,17 +55,17 @@ impl Formats { pub enum GlobPattern { /// A glob Path(String), - /// A glob `path` with a `format` key to specify one ore more [Format] values + /// A glob `path` with a `format` key to specify one or more [Format] values WithFormat { /// A glob path: String, - /// One ore more [Format] values + /// One or more [Format] values format: Formats, }, } impl GlobPattern { - /// Returns the glob pattern for this patter if it targets the given [Format], else this returns `None`. + /// Returns the glob pattern for this pattern if it targets the given [Format], else this returns `None`. pub fn targets(&self, format: Format) -> Option<&str> { match self { // Not specified defaults to both From 3535530b5e2e4d0668fe1a8d0e8efb2bb365189d Mon Sep 17 00:00:00 2001 From: Matthijs Brobbel Date: Tue, 8 Nov 2022 16:15:37 +0100 Subject: [PATCH 04/17] Use `eprintln` instead of `warn` --- src/source_distribution.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/source_distribution.rs b/src/source_distribution.rs index b7af389d1..f7b87a8c3 100644 --- a/src/source_distribution.rs +++ b/src/source_distribution.rs @@ -571,7 +571,9 @@ pub fn source_distribution( #[allow(deprecated)] if let Some(include_targets) = pyproject.sdist_include() { - warn!("`[tool.maturin.sdist-include]` is deprecated, please use `[tool.maturin.include]`"); + eprintln!( + "`[tool.maturin.sdist-include]` is deprecated, please use `[tool.maturin.include]`" + ); for pattern in include_targets { include(pattern.as_str())?; } From 76a7db6be6ce56811df5161f947d8e172d007e3a Mon Sep 17 00:00:00 2001 From: Matthijs Brobbel Date: Tue, 8 Nov 2022 16:20:59 +0100 Subject: [PATCH 05/17] Add warning emoji to deprecation notice Co-authored-by: messense --- src/source_distribution.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/source_distribution.rs b/src/source_distribution.rs index f7b87a8c3..d12c2ff9d 100644 --- a/src/source_distribution.rs +++ b/src/source_distribution.rs @@ -572,7 +572,7 @@ pub fn source_distribution( #[allow(deprecated)] if let Some(include_targets) = pyproject.sdist_include() { eprintln!( - "`[tool.maturin.sdist-include]` is deprecated, please use `[tool.maturin.include]`" + "⚠️ Warning: `[tool.maturin.sdist-include]` is deprecated, please use `[tool.maturin.include]`" ); for pattern in include_targets { include(pattern.as_str())?; From e340e9d4e13293f45277f537e55a62222a77b687 Mon Sep 17 00:00:00 2001 From: Matthijs Brobbel Date: Tue, 8 Nov 2022 16:24:15 +0100 Subject: [PATCH 06/17] Add changelog entry --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index 7a2fd09b7..8c00f2631 100644 --- a/Changelog.md +++ b/Changelog.md @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Fixes the compatibility tags for Pyston. * Set default macOS deployment target version if `MACOSX_DEPLOYMENT_TARGET` isn't specified in [#1251](https://github.com/PyO3/maturin/pull/1251) * Add support for 32-bit x86 FreeBSD target in [#1254](https://github.com/PyO3/maturin/pull/1254) +* Add `[tool.maturin.include]` and `[tool.maturin.exclude]` and deprecate `[tool.maturin.sdist-include]` [#1255](https://github.com/PyO3/maturin/pull/1255) ## [0.13.7] - 2022-10-29 From 72b439ae1d53b53cc62493d832671c3b9fb2b6d3 Mon Sep 17 00:00:00 2001 From: Matthijs Brobbel Date: Tue, 8 Nov 2022 16:35:45 +0100 Subject: [PATCH 07/17] Add some docs for `[tool.maturin.include]` and `[tool.maturin.exclude]` --- README.md | 4 ++-- guide/src/distribution.md | 4 ++-- guide/src/metadata.md | 23 +++++++++++++++++++++++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index be600e370..83c20ff4d 100644 --- a/README.md +++ b/README.md @@ -223,11 +223,11 @@ compatibility = "linux" `manylinux` option is also accepted as an alias of `compatibility` for backward compatibility with old version of maturin. -To include arbitrary files in the sdist for use during compilation specify `sdist-include` as an array of globs: +To include arbitrary files in the sdist for use during compilation specify `include` as an array of `path` globs with `format` set to `sdist`: ```toml [tool.maturin] -sdist-include = ["path/**/*"] +include = [{ path = "path/**/*", format = "sdist" }] ``` There's a `maturin sdist` command for only building a source distribution as workaround for [pypa/pip#6041](https://github.com/pypa/pip/issues/6041). diff --git a/guide/src/distribution.md b/guide/src/distribution.md index 22ad2304f..421bc9521 100644 --- a/guide/src/distribution.md +++ b/guide/src/distribution.md @@ -32,11 +32,11 @@ compatibility = "linux" `manylinux` option is also accepted as an alias of `compatibility` for backward compatibility with old version of maturin. -To include arbitrary files in the sdist for use during compilation specify `sdist-include` as an array of globs: +To include arbitrary files in the sdist for use during compilation specify `include` as an array of `path` globs with `format` set to `sdist`: ```toml [tool.maturin] -sdist-include = ["path/**/*"] +include = [{ path = "path/**/*", format = "sdist" }] ``` ## Build Wheels diff --git a/guide/src/metadata.md b/guide/src/metadata.md index 4b0088689..f0ed3ff24 100644 --- a/guide/src/metadata.md +++ b/guide/src/metadata.md @@ -143,3 +143,26 @@ unstable-flags = [] # Extra arguments that will be passed to rustc as `cargo rustc [...] -- [...] [arg1] [arg2]` rustc-args = [] ``` + +The `[tool.maturin.include]` and `[tool.maturin.exclude]` configuration are +inspired by +[Poetry](https://python-poetry.org/docs/pyproject/#include-and-exclude). + +To specify files or globs directly: + +```toml +include = ["path/**/*", "some/other/file"] +``` + +To specify a specific target format (`sdist` or `wheel`): + +```toml +include = [ + { path = "path/**/*", format = "sdist" }, + { path = "all", format = ["sdist", "wheel"] }, + { path = "for/wheel/**/*", format = "wheel" } +] +``` + +The default behavior is apply these configurations to both `sdist` and `wheel` +targets. From 5f8cc6458436f22d940d8f7342c96d15da2ecd3f Mon Sep 17 00:00:00 2001 From: Matthijs Brobbel Date: Tue, 8 Nov 2022 16:48:41 +0100 Subject: [PATCH 08/17] Remove unused use statement --- src/source_distribution.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/source_distribution.rs b/src/source_distribution.rs index d12c2ff9d..ba53d13ab 100644 --- a/src/source_distribution.rs +++ b/src/source_distribution.rs @@ -10,7 +10,7 @@ use std::collections::HashMap; use std::path::{Path, PathBuf}; use std::process::Command; use std::str; -use tracing::{debug, warn}; +use tracing::debug; const LOCAL_DEPENDENCIES_FOLDER: &str = "local_dependencies"; /// Inheritable workspace fields, see From bb7e2f45b538225ef5857d1af915d0efabfffd84 Mon Sep 17 00:00:00 2001 From: Matthijs Brobbel Date: Tue, 8 Nov 2022 16:51:11 +0100 Subject: [PATCH 09/17] Add integration tests for `[tool.maturin.include]` and `[tool.maturin.exclude]` --- .../pyo3-mixed-include-exclude/.gitignore | 1 + .../pyo3-mixed-include-exclude/Cargo.lock | 289 ++++++++++++++++++ .../pyo3-mixed-include-exclude/Cargo.toml | 16 + .../pyo3-mixed-include-exclude/README.md | 30 ++ .../check_installed/check_installed.py | 9 + .../exclude_this_file | 0 .../include_this_file | 0 .../pyo3-config.txt | 6 + .../pyo3_mixed_include_exclude/__init__.py | 6 + .../python_module/__init__.py | 0 .../python_module/double.py | 5 + .../pyo3-mixed-include-exclude/pyproject.toml | 16 + .../pyo3-mixed-include-exclude/src/lib.rs | 13 + .../tests/test_pyo3_mixed_include_exclude.py | 7 + .../pyo3-mixed-include-exclude/tox.ini | 7 + tests/run.rs | 57 ++++ 16 files changed, 462 insertions(+) create mode 100644 test-crates/pyo3-mixed-include-exclude/.gitignore create mode 100644 test-crates/pyo3-mixed-include-exclude/Cargo.lock create mode 100644 test-crates/pyo3-mixed-include-exclude/Cargo.toml create mode 100644 test-crates/pyo3-mixed-include-exclude/README.md create mode 100755 test-crates/pyo3-mixed-include-exclude/check_installed/check_installed.py create mode 100644 test-crates/pyo3-mixed-include-exclude/exclude_this_file create mode 100644 test-crates/pyo3-mixed-include-exclude/include_this_file create mode 100644 test-crates/pyo3-mixed-include-exclude/pyo3-config.txt create mode 100644 test-crates/pyo3-mixed-include-exclude/pyo3_mixed_include_exclude/__init__.py create mode 100644 test-crates/pyo3-mixed-include-exclude/pyo3_mixed_include_exclude/python_module/__init__.py create mode 100644 test-crates/pyo3-mixed-include-exclude/pyo3_mixed_include_exclude/python_module/double.py create mode 100644 test-crates/pyo3-mixed-include-exclude/pyproject.toml create mode 100644 test-crates/pyo3-mixed-include-exclude/src/lib.rs create mode 100644 test-crates/pyo3-mixed-include-exclude/tests/test_pyo3_mixed_include_exclude.py create mode 100644 test-crates/pyo3-mixed-include-exclude/tox.ini diff --git a/test-crates/pyo3-mixed-include-exclude/.gitignore b/test-crates/pyo3-mixed-include-exclude/.gitignore new file mode 100644 index 000000000..d3a83a04c --- /dev/null +++ b/test-crates/pyo3-mixed-include-exclude/.gitignore @@ -0,0 +1 @@ +include_this_file diff --git a/test-crates/pyo3-mixed-include-exclude/Cargo.lock b/test-crates/pyo3-mixed-include-exclude/Cargo.lock new file mode 100644 index 000000000..7b0a64772 --- /dev/null +++ b/test-crates/pyo3-mixed-include-exclude/Cargo.lock @@ -0,0 +1,289 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "cc" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "indoc" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adab1eaa3408fb7f0c777a73e7465fd5656136fc93b670eb6df3c88c2c1344e3" + +[[package]] +name = "libc" +version = "0.2.137" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys", +] + +[[package]] +name = "proc-macro2" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "pyo3" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "268be0c73583c183f2b14052337465768c07726936a260f480f0857cb95ba543" +dependencies = [ + "cfg-if", + "indoc", + "libc", + "memoffset", + "parking_lot", + "pyo3-build-config", + "pyo3-ffi", + "pyo3-macros", + "unindent", +] + +[[package]] +name = "pyo3-build-config" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28fcd1e73f06ec85bf3280c48c67e731d8290ad3d730f8be9dc07946923005c8" +dependencies = [ + "once_cell", + "python3-dll-a", + "target-lexicon", +] + +[[package]] +name = "pyo3-ffi" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f6cb136e222e49115b3c51c32792886defbfb0adead26a688142b346a0b9ffc" +dependencies = [ + "libc", + "pyo3-build-config", +] + +[[package]] +name = "pyo3-macros" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94144a1266e236b1c932682136dc35a9dee8d3589728f68130c7c3861ef96b28" +dependencies = [ + "proc-macro2", + "pyo3-macros-backend", + "quote", + "syn", +] + +[[package]] +name = "pyo3-macros-backend" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8df9be978a2d2f0cdebabb03206ed73b11314701a5bfe71b0d753b81997777f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pyo3-mixed-include-exclude" +version = "2.1.3" +dependencies = [ + "pyo3", +] + +[[package]] +name = "python3-dll-a" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a915bd72824962bf190bbd3e8a044cccb695d1409f73ff5493712eda5136c7a8" +dependencies = [ + "cc", +] + +[[package]] +name = "quote" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "syn" +version = "1.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "target-lexicon" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c02424087780c9b71cc96799eaeddff35af2bc513278cda5c99fc1f5d026d3c1" + +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" + +[[package]] +name = "unindent" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58ee9362deb4a96cef4d437d1ad49cffc9b9e92d202b6995674e928ce684f112" + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" diff --git a/test-crates/pyo3-mixed-include-exclude/Cargo.toml b/test-crates/pyo3-mixed-include-exclude/Cargo.toml new file mode 100644 index 000000000..82f69433c --- /dev/null +++ b/test-crates/pyo3-mixed-include-exclude/Cargo.toml @@ -0,0 +1,16 @@ +[package] +authors = [] +name = "pyo3-mixed-include-exclude" +version = "2.1.3" +description = "Implements a dummy function combining rust and python" +edition = "2021" + +[dependencies] +pyo3 = { version = "0.17.3", features = [ + "extension-module", + "generate-import-lib", +] } + +[lib] +name = "pyo3_mixed_include_exclude" +crate-type = ["cdylib"] diff --git a/test-crates/pyo3-mixed-include-exclude/README.md b/test-crates/pyo3-mixed-include-exclude/README.md new file mode 100644 index 000000000..ea9cc57d7 --- /dev/null +++ b/test-crates/pyo3-mixed-include-exclude/README.md @@ -0,0 +1,30 @@ +# pyo3-mixed-include-exclude + +A package for testing maturin with a mixed pyo3/python project with include and exclude configurations. + +## Usage + +```bash +pip install . +``` + +```python +import pyo3_mixed_include_exclude +assert pyo3_mixed_include_exclude.get_42() == 42 +``` + +## Testing + +Install tox: + +```bash +pip install tox +``` + +Run it: + +```bash +tox +``` + +The tests are in `test_pyo3_mixed_include_exclude.py`, while the configuration is in tox.ini diff --git a/test-crates/pyo3-mixed-include-exclude/check_installed/check_installed.py b/test-crates/pyo3-mixed-include-exclude/check_installed/check_installed.py new file mode 100755 index 000000000..cd5e62181 --- /dev/null +++ b/test-crates/pyo3-mixed-include-exclude/check_installed/check_installed.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python3 + +from boltons.strutils import slugify +import pyo3_mixed_include_exclude + +assert pyo3_mixed_include_exclude.get_42() == 42 +assert slugify("First post! Hi!!!!~1 ") == "first_post_hi_1" + +print("SUCCESS") diff --git a/test-crates/pyo3-mixed-include-exclude/exclude_this_file b/test-crates/pyo3-mixed-include-exclude/exclude_this_file new file mode 100644 index 000000000..e69de29bb diff --git a/test-crates/pyo3-mixed-include-exclude/include_this_file b/test-crates/pyo3-mixed-include-exclude/include_this_file new file mode 100644 index 000000000..e69de29bb diff --git a/test-crates/pyo3-mixed-include-exclude/pyo3-config.txt b/test-crates/pyo3-mixed-include-exclude/pyo3-config.txt new file mode 100644 index 000000000..da3ba7691 --- /dev/null +++ b/test-crates/pyo3-mixed-include-exclude/pyo3-config.txt @@ -0,0 +1,6 @@ +implementation=CPython +version=3.10 +shared=true +abi3=false +suppress_build_script_link_lines=false +pointer_width=64 diff --git a/test-crates/pyo3-mixed-include-exclude/pyo3_mixed_include_exclude/__init__.py b/test-crates/pyo3-mixed-include-exclude/pyo3_mixed_include_exclude/__init__.py new file mode 100644 index 000000000..2114fe5d3 --- /dev/null +++ b/test-crates/pyo3-mixed-include-exclude/pyo3_mixed_include_exclude/__init__.py @@ -0,0 +1,6 @@ +from .python_module.double import double +from .pyo3_mixed_include_exclude import get_21 + + +def get_42() -> int: + return double(get_21) diff --git a/test-crates/pyo3-mixed-include-exclude/pyo3_mixed_include_exclude/python_module/__init__.py b/test-crates/pyo3-mixed-include-exclude/pyo3_mixed_include_exclude/python_module/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/test-crates/pyo3-mixed-include-exclude/pyo3_mixed_include_exclude/python_module/double.py b/test-crates/pyo3-mixed-include-exclude/pyo3_mixed_include_exclude/python_module/double.py new file mode 100644 index 000000000..2eed18d52 --- /dev/null +++ b/test-crates/pyo3-mixed-include-exclude/pyo3_mixed_include_exclude/python_module/double.py @@ -0,0 +1,5 @@ +from typing import Callable + + +def double(fn: Callable[[], int]) -> int: + return 2 * fn() diff --git a/test-crates/pyo3-mixed-include-exclude/pyproject.toml b/test-crates/pyo3-mixed-include-exclude/pyproject.toml new file mode 100644 index 000000000..df4db10d8 --- /dev/null +++ b/test-crates/pyo3-mixed-include-exclude/pyproject.toml @@ -0,0 +1,16 @@ +[build-system] +requires = ["maturin>=0.13,<0.14"] +build-backend = "maturin" + +[project] +name = "pyo3-mixed-include-exclude" +classifiers = ["Programming Language :: Python", "Programming Language :: Rust"] +requires-python = ">=3.7" +dependencies = ["boltons"] + +[project.scripts] +get_42 = "pyo3_mixed_include_exclude:get_42" + +[tool.maturin] +include = ["include_this_file", "missing"] +exclude = ["exclude_this_file", "tests/**/*", ".gitignore", "unused"] diff --git a/test-crates/pyo3-mixed-include-exclude/src/lib.rs b/test-crates/pyo3-mixed-include-exclude/src/lib.rs new file mode 100644 index 000000000..142e0fce3 --- /dev/null +++ b/test-crates/pyo3-mixed-include-exclude/src/lib.rs @@ -0,0 +1,13 @@ +use pyo3::prelude::*; + +#[pyfunction] +fn get_21() -> usize { + 21 +} + +#[pymodule] +fn pyo3_mixed_include_exclude(_py: Python, m: &PyModule) -> PyResult<()> { + m.add_wrapped(wrap_pyfunction!(get_21))?; + + Ok(()) +} diff --git a/test-crates/pyo3-mixed-include-exclude/tests/test_pyo3_mixed_include_exclude.py b/test-crates/pyo3-mixed-include-exclude/tests/test_pyo3_mixed_include_exclude.py new file mode 100644 index 000000000..cbb54868d --- /dev/null +++ b/test-crates/pyo3-mixed-include-exclude/tests/test_pyo3_mixed_include_exclude.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python3 + +import pyo3_mixed_include_exclude + + +def test_get_42(): + assert pyo3_mixed_include_exclude.get_42() == 42 diff --git a/test-crates/pyo3-mixed-include-exclude/tox.ini b/test-crates/pyo3-mixed-include-exclude/tox.ini new file mode 100644 index 000000000..421774193 --- /dev/null +++ b/test-crates/pyo3-mixed-include-exclude/tox.ini @@ -0,0 +1,7 @@ +[tox] +envlist = py36,py37,py38 +isolated_build = True + +[testenv] +deps = pytest +commands = pytest tests/ diff --git a/tests/run.rs b/tests/run.rs index e2c61054a..2fde4365a 100644 --- a/tests/run.rs +++ b/tests/run.rs @@ -44,6 +44,16 @@ fn develop_pyo3_mixed() { )); } +#[test] +fn develop_pyo3_mixed_include_exclude() { + handle_result(develop::test_develop( + "test-crates/pyo3-mixed-include-exclude", + None, + "develop-pyo3-mixed-include-exclude", + false, + )); +} + #[test] fn develop_pyo3_mixed_submodule() { handle_result(develop::test_develop( @@ -132,6 +142,15 @@ fn editable_pyo3_mixed() { )); } +#[test] +fn editable_pyo3_mixed_include_exclude() { + handle_result(editable::test_editable( + "test-crates/pyo3-mixed-include-exclude", + None, + "editable-pyo3-mixed-include-exclude", + )); +} + #[test] fn editable_pyo3_mixed_py_subdir() { handle_result(editable::test_editable( @@ -193,6 +212,17 @@ fn integration_pyo3_mixed() { )); } +#[test] +fn integration_pyo3_mixed_include_exclude() { + handle_result(integration::test_integration( + "test-crates/pyo3-mixed-include-exclude", + None, + "integration-pyo3-mixed-include-exclude", + false, + None, + )); +} + #[test] fn integration_pyo3_mixed_submodule() { handle_result(integration::test_integration( @@ -463,6 +493,33 @@ fn pyo3_mixed_src_layout_sdist() { )) } +#[test] +fn pyo3_mixed_include_exclude_src_layout_sdist() { + handle_result(other::test_source_distribution( + "test-crates/pyo3-mixed-include-exclude", + vec![ + // "pyo3_mixed_include_exclude-2.1.3/.gitignore", // excluded + "pyo3_mixed_include_exclude-2.1.3/Cargo.lock", + "pyo3_mixed_include_exclude-2.1.3/Cargo.toml", + "pyo3_mixed_include_exclude-2.1.3/PKG-INFO", + "pyo3_mixed_include_exclude-2.1.3/README.md", + "pyo3_mixed_include_exclude-2.1.3/check_installed/check_installed.py", + "pyo3_mixed_include_exclude-2.1.3/include_this_file", // included + // "pyo3_mixed_include_exclude-2.1.3/exclude_this_file, excluded + "pyo3_mixed_include_exclude-2.1.3/pyo3-config.txt", + "pyo3_mixed_include_exclude-2.1.3/pyo3_mixed_include_exclude/__init__.py", + "pyo3_mixed_include_exclude-2.1.3/pyo3_mixed_include_exclude/python_module/__init__.py", + "pyo3_mixed_include_exclude-2.1.3/pyo3_mixed_include_exclude/python_module/double.py", + "pyo3_mixed_include_exclude-2.1.3/pyproject.toml", + "pyo3_mixed_include_exclude-2.1.3/src/lib.rs", + // "pyo3_mixed_include_exclude-2.1.3/tests/test_pyo3_mixed_include_exclude.py", excluded + "pyo3_mixed_include_exclude-2.1.3/tox.ini", + ], + None, + "sdist-pyo3-mixed-include-exclude-src-layout", + )) +} + #[test] fn workspace_with_path_dep_sdist() { handle_result(other::test_source_distribution( From 0e2bcb35468719b6fa7e47bab25f1c762edf3e61 Mon Sep 17 00:00:00 2001 From: Matthijs Brobbel Date: Tue, 8 Nov 2022 19:30:04 +0100 Subject: [PATCH 10/17] Remove unused file --- test-crates/pyo3-mixed-include-exclude/pyo3-config.txt | 6 ------ tests/run.rs | 1 - 2 files changed, 7 deletions(-) delete mode 100644 test-crates/pyo3-mixed-include-exclude/pyo3-config.txt diff --git a/test-crates/pyo3-mixed-include-exclude/pyo3-config.txt b/test-crates/pyo3-mixed-include-exclude/pyo3-config.txt deleted file mode 100644 index da3ba7691..000000000 --- a/test-crates/pyo3-mixed-include-exclude/pyo3-config.txt +++ /dev/null @@ -1,6 +0,0 @@ -implementation=CPython -version=3.10 -shared=true -abi3=false -suppress_build_script_link_lines=false -pointer_width=64 diff --git a/tests/run.rs b/tests/run.rs index 2fde4365a..733fffd7f 100644 --- a/tests/run.rs +++ b/tests/run.rs @@ -506,7 +506,6 @@ fn pyo3_mixed_include_exclude_src_layout_sdist() { "pyo3_mixed_include_exclude-2.1.3/check_installed/check_installed.py", "pyo3_mixed_include_exclude-2.1.3/include_this_file", // included // "pyo3_mixed_include_exclude-2.1.3/exclude_this_file, excluded - "pyo3_mixed_include_exclude-2.1.3/pyo3-config.txt", "pyo3_mixed_include_exclude-2.1.3/pyo3_mixed_include_exclude/__init__.py", "pyo3_mixed_include_exclude-2.1.3/pyo3_mixed_include_exclude/python_module/__init__.py", "pyo3_mixed_include_exclude-2.1.3/pyo3_mixed_include_exclude/python_module/double.py", From 1855d805c8bd62fb414fd2674c695081faa2c070 Mon Sep 17 00:00:00 2001 From: Matthijs Brobbel Date: Tue, 8 Nov 2022 19:31:00 +0100 Subject: [PATCH 11/17] Apply suggestions from code review Co-authored-by: messense --- tests/run.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/run.rs b/tests/run.rs index 733fffd7f..04964b2a7 100644 --- a/tests/run.rs +++ b/tests/run.rs @@ -494,7 +494,7 @@ fn pyo3_mixed_src_layout_sdist() { } #[test] -fn pyo3_mixed_include_exclude_src_layout_sdist() { +fn pyo3_mixed_include_exclude_sdist() { handle_result(other::test_source_distribution( "test-crates/pyo3-mixed-include-exclude", vec![ @@ -515,7 +515,7 @@ fn pyo3_mixed_include_exclude_src_layout_sdist() { "pyo3_mixed_include_exclude-2.1.3/tox.ini", ], None, - "sdist-pyo3-mixed-include-exclude-src-layout", + "sdist-pyo3-mixed-include-exclude", )) } From 587054ed3355636ccf2c345b3840b741d78ba349 Mon Sep 17 00:00:00 2001 From: Matthijs Brobbel Date: Tue, 8 Nov 2022 21:05:20 +0100 Subject: [PATCH 12/17] Add wheel files check --- src/build_context.rs | 12 +---- src/module_writer.rs | 17 +++---- .../.gitignore | 0 .../exclude_this_file | 0 .../include_this_file | 0 .../pyo3-mixed-include-exclude/pyproject.toml | 13 +++++- tests/common/other.rs | 44 +++++++++++++++++++ tests/run.rs | 23 +++++++++- 8 files changed, 83 insertions(+), 26 deletions(-) rename test-crates/pyo3-mixed-include-exclude/{ => pyo3_mixed_include_exclude}/.gitignore (100%) rename test-crates/pyo3-mixed-include-exclude/{ => pyo3_mixed_include_exclude}/exclude_this_file (100%) rename test-crates/pyo3-mixed-include-exclude/{ => pyo3_mixed_include_exclude}/include_this_file (100%) diff --git a/src/build_context.rs b/src/build_context.rs index a95f56a31..6866dc4d7 100644 --- a/src/build_context.rs +++ b/src/build_context.rs @@ -501,7 +501,6 @@ impl BuildContext { None, &self.target, self.editable, - &self.metadata21, self.pyproject_toml.as_ref(), ) .context("Failed to add the files to the wheel")?; @@ -580,7 +579,6 @@ impl BuildContext { Some(python_interpreter), &self.target, self.editable, - &self.metadata21, self.pyproject_toml.as_ref(), ) .context("Failed to add the files to the wheel")?; @@ -706,7 +704,6 @@ impl BuildContext { &artifact.path, &self.interpreter[0].executable, self.editable, - &self.metadata21, self.pyproject_toml.as_ref(), )?; @@ -814,13 +811,8 @@ impl BuildContext { bail!("Sorry, adding python code to a wasm binary is currently not supported") } if !self.editable { - write_python_part( - &mut writer, - python_module, - &metadata21, - self.pyproject_toml.as_ref(), - ) - .context("Failed to add the python module to the package")?; + write_python_part(&mut writer, python_module, self.pyproject_toml.as_ref()) + .context("Failed to add the python module to the package")?; } } diff --git a/src/module_writer.rs b/src/module_writer.rs index 983d1c25b..1079dc59c 100644 --- a/src/module_writer.rs +++ b/src/module_writer.rs @@ -673,7 +673,6 @@ pub fn write_bindings_module( python_interpreter: Option<&PythonInterpreter>, target: &Target, editable: bool, - metadata: &Metadata21, pyproject_toml: Option<&PyProjectToml>, ) -> Result<()> { let ext_name = &project_layout.extension_name; @@ -705,7 +704,7 @@ pub fn write_bindings_module( target.display() ))?; } else { - write_python_part(writer, python_module, metadata, pyproject_toml) + write_python_part(writer, python_module, pyproject_toml) .context("Failed to add the python module to the package")?; let relative = project_layout @@ -755,7 +754,6 @@ pub fn write_cffi_module( artifact: &Path, python: &Path, editable: bool, - metadata21: &Metadata21, pyproject_toml: Option<&PyProjectToml>, ) -> Result<()> { let cffi_declarations = generate_cffi_declarations(crate_dir, target_dir, python)?; @@ -764,7 +762,7 @@ pub fn write_cffi_module( if let Some(python_module) = &project_layout.python_module { if !editable { - write_python_part(writer, python_module, metadata21, pyproject_toml) + write_python_part(writer, python_module, pyproject_toml) .context("Failed to add the python module to the package")?; } @@ -891,7 +889,6 @@ if __name__ == '__main__': pub fn write_python_part( writer: &mut impl ModuleWriter, python_module: impl AsRef, - metadata21: &Metadata21, pyproject_toml: Option<&PyProjectToml>, ) -> Result<()> { let python_module = python_module.as_ref(); @@ -918,22 +915,18 @@ pub fn write_python_part( // Include additional files if let Some(pyproject) = pyproject_toml { - let root_dir = PathBuf::from(format!( - "{}-{}", - &metadata21.get_distribution_escaped(), - &metadata21.get_version_escaped() - )); + let pyproject_dir = python_module.parent().unwrap(); if let Some(glob_patterns) = pyproject.include() { for pattern in glob_patterns .iter() .filter_map(|glob_pattern| glob_pattern.targets(Format::Sdist)) { println!("📦 Including files matching \"{}\"", pattern); - for source in glob::glob(&python_module.join(pattern).to_string_lossy()) + for source in glob::glob(&pyproject_dir.join(pattern).to_string_lossy()) .expect("No files found for pattern") .filter_map(Result::ok) { - let target = root_dir.join(source.strip_prefix(python_module).unwrap()); + let target = source.strip_prefix(pyproject_dir)?.to_path_buf(); if source.is_dir() { writer.add_directory(target)?; } else { diff --git a/test-crates/pyo3-mixed-include-exclude/.gitignore b/test-crates/pyo3-mixed-include-exclude/pyo3_mixed_include_exclude/.gitignore similarity index 100% rename from test-crates/pyo3-mixed-include-exclude/.gitignore rename to test-crates/pyo3-mixed-include-exclude/pyo3_mixed_include_exclude/.gitignore diff --git a/test-crates/pyo3-mixed-include-exclude/exclude_this_file b/test-crates/pyo3-mixed-include-exclude/pyo3_mixed_include_exclude/exclude_this_file similarity index 100% rename from test-crates/pyo3-mixed-include-exclude/exclude_this_file rename to test-crates/pyo3-mixed-include-exclude/pyo3_mixed_include_exclude/exclude_this_file diff --git a/test-crates/pyo3-mixed-include-exclude/include_this_file b/test-crates/pyo3-mixed-include-exclude/pyo3_mixed_include_exclude/include_this_file similarity index 100% rename from test-crates/pyo3-mixed-include-exclude/include_this_file rename to test-crates/pyo3-mixed-include-exclude/pyo3_mixed_include_exclude/include_this_file diff --git a/test-crates/pyo3-mixed-include-exclude/pyproject.toml b/test-crates/pyo3-mixed-include-exclude/pyproject.toml index df4db10d8..9c8bc0307 100644 --- a/test-crates/pyo3-mixed-include-exclude/pyproject.toml +++ b/test-crates/pyo3-mixed-include-exclude/pyproject.toml @@ -12,5 +12,14 @@ dependencies = ["boltons"] get_42 = "pyo3_mixed_include_exclude:get_42" [tool.maturin] -include = ["include_this_file", "missing"] -exclude = ["exclude_this_file", "tests/**/*", ".gitignore", "unused"] +include = [ + "pyo3_mixed_include_exclude/include_this_file", + "missing", + "README.md", +] +exclude = [ + "pyo3_mixed_include_exclude/exclude_this_file", + "pyo3_mixed_include_exclude/.gitignore", + "tests/**/*", + "unused", +] diff --git a/tests/common/other.rs b/tests/common/other.rs index cbdb7dc01..322316b63 100644 --- a/tests/common/other.rs +++ b/tests/common/other.rs @@ -4,10 +4,12 @@ use flate2::read::GzDecoder; use maturin::{BuildOptions, CargoOptions}; use pretty_assertions::assert_eq; use std::collections::BTreeSet; +use std::fs::File; use std::io::Read; use std::iter::FromIterator; use std::path::{Path, PathBuf}; use tar::Archive; +use zip::ZipArchive; /// Tries to compile a sample crate (pyo3-pure) for musl, /// given that rustup and the the musl target are installed @@ -169,6 +171,48 @@ pub fn test_source_distribution( Ok(()) } +pub fn check_wheel_files( + package: impl AsRef, + expected_files: Vec<&str>, + unique_name: &str, +) -> Result<()> { + let manifest_path = package.as_ref().join("Cargo.toml"); + let wheel_directory = Path::new("test-crates").join("wheels").join(unique_name); + + let build_options = BuildOptions { + out: Some(wheel_directory), + cargo: CargoOptions { + manifest_path: Some(manifest_path), + quiet: true, + target_dir: Some(PathBuf::from( + "test-crates/targets/test_workspace_cargo_lock", + )), + ..Default::default() + }, + ..Default::default() + }; + + let build_context = build_options.into_build_context(false, false, false)?; + let wheels = build_context + .build_wheels() + .context("Failed to build wheels")?; + assert!(!wheels.is_empty()); + let (wheel_path, _) = &wheels[0]; + + let wheel = ZipArchive::new(File::open(wheel_path)?)?; + let drop_platform_specific_files = |file: &&str| -> bool { + !matches!(Path::new(file).extension(), Some(ext) if ext == "pyc" || ext == "pyd" || ext == "so") + }; + assert_eq!( + wheel + .file_names() + .filter(drop_platform_specific_files) + .collect::>(), + expected_files.into_iter().collect::>() + ); + Ok(()) +} + pub fn abi3_python_interpreter_args() -> Result<()> { // Case 1: maturin build without `-i`, should work let options = BuildOptions::try_parse_from(vec![ diff --git a/tests/run.rs b/tests/run.rs index 04964b2a7..98e6598d9 100644 --- a/tests/run.rs +++ b/tests/run.rs @@ -504,9 +504,9 @@ fn pyo3_mixed_include_exclude_sdist() { "pyo3_mixed_include_exclude-2.1.3/PKG-INFO", "pyo3_mixed_include_exclude-2.1.3/README.md", "pyo3_mixed_include_exclude-2.1.3/check_installed/check_installed.py", - "pyo3_mixed_include_exclude-2.1.3/include_this_file", // included - // "pyo3_mixed_include_exclude-2.1.3/exclude_this_file, excluded + // "pyo3_mixed_include_exclude-2.1.3/pyo3_mixed_include_exclude/exclude_this_file, excluded "pyo3_mixed_include_exclude-2.1.3/pyo3_mixed_include_exclude/__init__.py", + "pyo3_mixed_include_exclude-2.1.3/pyo3_mixed_include_exclude/include_this_file", // included "pyo3_mixed_include_exclude-2.1.3/pyo3_mixed_include_exclude/python_module/__init__.py", "pyo3_mixed_include_exclude-2.1.3/pyo3_mixed_include_exclude/python_module/double.py", "pyo3_mixed_include_exclude-2.1.3/pyproject.toml", @@ -519,6 +519,25 @@ fn pyo3_mixed_include_exclude_sdist() { )) } +#[test] +fn pyo3_mixed_include_exclude_wheel_files() { + handle_result(other::check_wheel_files( + "test-crates/pyo3-mixed-include-exclude", + vec![ + "pyo3_mixed_include_exclude-2.1.3.dist-info/METADATA", + "pyo3_mixed_include_exclude-2.1.3.dist-info/RECORD", + "pyo3_mixed_include_exclude-2.1.3.dist-info/WHEEL", + "pyo3_mixed_include_exclude-2.1.3.dist-info/entry_points.txt", + "pyo3_mixed_include_exclude/__init__.py", + "pyo3_mixed_include_exclude/include_this_file", + "pyo3_mixed_include_exclude/python_module/__init__.py", + "pyo3_mixed_include_exclude/python_module/double.py", + "README.md", + ], + "wheel-files-pyo3-mixed-include-exclude", + )) +} + #[test] fn workspace_with_path_dep_sdist() { handle_result(other::test_source_distribution( From 9b595851f17161c954c532e4872da7c473987274 Mon Sep 17 00:00:00 2001 From: Matthijs Brobbel Date: Wed, 9 Nov 2022 09:50:21 +0100 Subject: [PATCH 13/17] Apply suggestions from code review Co-authored-by: messense --- .../check_installed/check_installed.py | 2 -- test-crates/pyo3-mixed-include-exclude/pyproject.toml | 1 - tests/common/other.rs | 2 +- tests/run.rs | 9 --------- 4 files changed, 1 insertion(+), 13 deletions(-) diff --git a/test-crates/pyo3-mixed-include-exclude/check_installed/check_installed.py b/test-crates/pyo3-mixed-include-exclude/check_installed/check_installed.py index cd5e62181..d135ea2b2 100755 --- a/test-crates/pyo3-mixed-include-exclude/check_installed/check_installed.py +++ b/test-crates/pyo3-mixed-include-exclude/check_installed/check_installed.py @@ -1,9 +1,7 @@ #!/usr/bin/env python3 -from boltons.strutils import slugify import pyo3_mixed_include_exclude assert pyo3_mixed_include_exclude.get_42() == 42 -assert slugify("First post! Hi!!!!~1 ") == "first_post_hi_1" print("SUCCESS") diff --git a/test-crates/pyo3-mixed-include-exclude/pyproject.toml b/test-crates/pyo3-mixed-include-exclude/pyproject.toml index 9c8bc0307..6de4ebe79 100644 --- a/test-crates/pyo3-mixed-include-exclude/pyproject.toml +++ b/test-crates/pyo3-mixed-include-exclude/pyproject.toml @@ -6,7 +6,6 @@ build-backend = "maturin" name = "pyo3-mixed-include-exclude" classifiers = ["Programming Language :: Python", "Programming Language :: Rust"] requires-python = ">=3.7" -dependencies = ["boltons"] [project.scripts] get_42 = "pyo3_mixed_include_exclude:get_42" diff --git a/tests/common/other.rs b/tests/common/other.rs index 322316b63..bb01340d6 100644 --- a/tests/common/other.rs +++ b/tests/common/other.rs @@ -185,7 +185,7 @@ pub fn check_wheel_files( manifest_path: Some(manifest_path), quiet: true, target_dir: Some(PathBuf::from( - "test-crates/targets/test_workspace_cargo_lock", + format!("test-crates/targets/{}", unique_name), )), ..Default::default() }, diff --git a/tests/run.rs b/tests/run.rs index 98e6598d9..8ed3090a9 100644 --- a/tests/run.rs +++ b/tests/run.rs @@ -142,15 +142,6 @@ fn editable_pyo3_mixed() { )); } -#[test] -fn editable_pyo3_mixed_include_exclude() { - handle_result(editable::test_editable( - "test-crates/pyo3-mixed-include-exclude", - None, - "editable-pyo3-mixed-include-exclude", - )); -} - #[test] fn editable_pyo3_mixed_py_subdir() { handle_result(editable::test_editable( From 50fac05e149befbca26c45c276186bc0b91b6144 Mon Sep 17 00:00:00 2001 From: Matthijs Brobbel Date: Wed, 9 Nov 2022 09:54:59 +0100 Subject: [PATCH 14/17] Mark `pyproject_toml` mod pub to remove some root re-exports --- src/build_context.rs | 4 ++-- src/lib.rs | 4 ++-- src/module_writer.rs | 4 +++- src/pyproject_toml.rs | 3 +++ src/source_distribution.rs | 2 +- 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/build_context.rs b/src/build_context.rs index 6866dc4d7..c50124073 100644 --- a/src/build_context.rs +++ b/src/build_context.rs @@ -10,8 +10,8 @@ use crate::project_layout::ProjectLayout; use crate::python_interpreter::InterpreterKind; use crate::source_distribution::source_distribution; use crate::{ - compile, BuildArtifact, Format, Metadata21, ModuleWriter, PyProjectToml, PythonInterpreter, - Target, + compile, pyproject_toml::Format, BuildArtifact, Metadata21, ModuleWriter, PyProjectToml, + PythonInterpreter, Target, }; use anyhow::{anyhow, bail, Context, Result}; use cargo_metadata::Metadata; diff --git a/src/lib.rs b/src/lib.rs index 2ffb156bb..91a37c97a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,7 +35,7 @@ pub use crate::module_writer::{ write_dist_info, ModuleWriter, PathWriter, SDistWriter, WheelWriter, }; pub use crate::new_project::{init_project, new_project, GenerateProjectOptions}; -pub use crate::pyproject_toml::{Format, Formats, GlobPattern, PyProjectToml}; +pub use crate::pyproject_toml::PyProjectToml; pub use crate::python_interpreter::PythonInterpreter; pub use crate::target::Target; #[cfg(feature = "upload")] @@ -54,7 +54,7 @@ mod module_writer; mod new_project; mod polyfill; mod project_layout; -mod pyproject_toml; +pub mod pyproject_toml; mod python_interpreter; mod source_distribution; mod target; diff --git a/src/module_writer.rs b/src/module_writer.rs index 1079dc59c..e65ce757b 100644 --- a/src/module_writer.rs +++ b/src/module_writer.rs @@ -1,6 +1,8 @@ //! The wheel format is (mostly) specified in PEP 427 use crate::project_layout::ProjectLayout; -use crate::{BridgeModel, Format, Metadata21, PyProjectToml, PythonInterpreter, Target}; +use crate::{ + pyproject_toml::Format, BridgeModel, Metadata21, PyProjectToml, PythonInterpreter, Target, +}; use anyhow::{anyhow, bail, Context, Result}; use flate2::write::GzEncoder; use flate2::Compression; diff --git a/src/pyproject_toml.rs b/src/pyproject_toml.rs index a78959fe4..60cd5f3b5 100644 --- a/src/pyproject_toml.rs +++ b/src/pyproject_toml.rs @@ -1,3 +1,5 @@ +//! A pyproject.toml as specified in PEP 517 + use crate::PlatformTag; use anyhow::{format_err, Result}; use fs_err as fs; @@ -118,6 +120,7 @@ pub struct ToolMaturin { pub config: Option>, /// Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details pub unstable_flags: Option>, + /// Additional rustc arguments pub rustc_args: Option>, } diff --git a/src/source_distribution.rs b/src/source_distribution.rs index ba53d13ab..6bb80d707 100644 --- a/src/source_distribution.rs +++ b/src/source_distribution.rs @@ -1,6 +1,6 @@ use crate::module_writer::{add_data, ModuleWriter}; use crate::polyfill::MetadataCommandExt; -use crate::{BuildContext, Format, PyProjectToml, SDistWriter}; +use crate::{pyproject_toml::Format, BuildContext, PyProjectToml, SDistWriter}; use anyhow::{bail, Context, Result}; use cargo_metadata::{Metadata, MetadataCommand}; use fs_err as fs; From c4fd67ce49546a82ed8a9c255fb97505f5969e33 Mon Sep 17 00:00:00 2001 From: Matthijs Brobbel Date: Wed, 9 Nov 2022 10:05:02 +0100 Subject: [PATCH 15/17] Apply rustfmt --- tests/common/other.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/common/other.rs b/tests/common/other.rs index bb01340d6..4e3360d77 100644 --- a/tests/common/other.rs +++ b/tests/common/other.rs @@ -184,9 +184,10 @@ pub fn check_wheel_files( cargo: CargoOptions { manifest_path: Some(manifest_path), quiet: true, - target_dir: Some(PathBuf::from( - format!("test-crates/targets/{}", unique_name), - )), + target_dir: Some(PathBuf::from(format!( + "test-crates/targets/{}", + unique_name + ))), ..Default::default() }, ..Default::default() From b37daa5819ee0a9ee4a30d852e6357e0e61db3ff Mon Sep 17 00:00:00 2001 From: Matthijs Brobbel Date: Wed, 9 Nov 2022 11:13:02 +0100 Subject: [PATCH 16/17] Set `platform_tags` to `Linux` in wheel files check --- tests/common/other.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/common/other.rs b/tests/common/other.rs index 4e3360d77..9ec5594af 100644 --- a/tests/common/other.rs +++ b/tests/common/other.rs @@ -1,7 +1,7 @@ use anyhow::{Context, Result}; use clap::Parser; use flate2::read::GzDecoder; -use maturin::{BuildOptions, CargoOptions}; +use maturin::{BuildOptions, CargoOptions, PlatformTag}; use pretty_assertions::assert_eq; use std::collections::BTreeSet; use std::fs::File; @@ -190,6 +190,7 @@ pub fn check_wheel_files( ))), ..Default::default() }, + platform_tag: vec![PlatformTag::Linux], ..Default::default() }; From 66e3421c043a2cee1cb4509c33b1cadb7bcc05a4 Mon Sep 17 00:00:00 2001 From: messense Date: Wed, 9 Nov 2022 23:04:09 +0800 Subject: [PATCH 17/17] Ignore `.so` and `.py[cd]` files in sdist by default --- src/source_distribution.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/source_distribution.rs b/src/source_distribution.rs index 6bb80d707..090d5e615 100644 --- a/src/source_distribution.rs +++ b/src/source_distribution.rs @@ -305,10 +305,18 @@ fn add_crate_to_source_distribution( }) // We rewrite Cargo.toml and add it separately .filter(|(target, source)| { + #[allow(clippy::if_same_then_else)] // Skip generated files. See https://github.com/rust-lang/cargo/issues/7938#issuecomment-593280660 // and https://github.com/PyO3/maturin/issues/449 if target == Path::new("Cargo.toml.orig") || target == Path::new("Cargo.toml") { false + } else if matches!(target.extension(), Some(ext) if ext == "pyc" || ext == "pyd" || ext == "so") { + // Technically, `cargo package --list` should handle this, + // but somehow it doesn't on Alpine Linux running in GitHub Actions, + // so we do it manually here. + // See https://github.com/PyO3/maturin/pull/1255#issuecomment-1308838786 + debug!("Ignoring {}", target.display()); + false } else { source.exists() }