Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5b0e480

Browse files
committed
Add full python core metadata support; fixes #159
1 parent f35cc4d commit 5b0e480

File tree

4 files changed

+70
-18
lines changed

4 files changed

+70
-18
lines changed

Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
* Mixed rust/python layout
1313
* Added PEP 517 support
1414
* Added a `pyo-pack sdist` command as workaround for [pypa/pip#6041](https://github.com/pypa/pip/issues/6041)
15+
* Support settings all applicable fields from the python core metadata specification in Cargo.toml
1516

1617
## [0.6.1]
1718

Readme.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,20 +98,28 @@ my-project
9898

9999
## Python metadata
100100

101+
To specifiy python dependecies, add a list `requires-dist` in a `[package.metadata.pyo3-pack]` section in the Cargo.toml. This list is equivalent to `install_requires` in setuptools:
102+
103+
```toml
104+
[package.metadata.pyo3-pack]
105+
requires-dist = ["flask~=1.1.0", "toml==0.10.0"]
106+
```
107+
101108
Pip allows adding so called console scripts, which are shell commands that execute some function in you program. You can add console scripts in a section `[package.metadata.pyo3-pack.scripts]`. The keys are the script names while the values are the path to the function in the format `some.module.path:class.function`, where the `class` part is optional. The function is called with no arguments. Example:
102109

103110
```toml
104111
[package.metadata.pyo3-pack.scripts]
105112
get_42 = "my_project:DummyClass.get_42"
106113
```
107114

108-
You can also specify [trove classifiers](https://pypi.org/classifiers/) in your Cargo.toml under `package.metadata.pyo3-pack.classifier`, e.g.:
115+
You can also specify [trove classifiers](https://pypi.org/classifiers/) in your Cargo.toml under `package.metadata.pyo3-pack.classifier`:
109116

110117
```toml
111118
[package.metadata.pyo3-pack]
112119
classifier = ["Programming Language :: Python"]
113120
```
114121

122+
You can use other fields from the [python core metadata](https://packaging.python.org/specifications/core-metadata/) in the `[package.metadata.pyo3-pack]` section, specifically ` maintainer`, `maintainer-email` and `requires-python` (string fields), as well as `requires-external`, `project-url` and `provides-extra` (lists of strings).
115123

116124
## pyproject.toml
117125

src/cargo_toml.rs

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ impl CargoToml {
6161
match self.package.metadata {
6262
Some(CargoTomlMetadata {
6363
pyo3_pack:
64-
Some(CargoTomlMetadataPyo3Pack {
64+
Some(RemainingCoreMetadata {
6565
scripts: Some(ref scripts),
6666
..
6767
}),
@@ -75,26 +75,49 @@ impl CargoToml {
7575
match self.package.metadata {
7676
Some(CargoTomlMetadata {
7777
pyo3_pack:
78-
Some(CargoTomlMetadataPyo3Pack {
78+
Some(RemainingCoreMetadata {
7979
classifier: Some(ref classifier),
8080
..
8181
}),
8282
}) => classifier.clone(),
8383
_ => Vec::new(),
8484
}
8585
}
86+
87+
/// Returns the value of `[project.metadata.pyo3-pack]` or an empty stub
88+
pub fn remaining_core_metadata(&self) -> RemainingCoreMetadata {
89+
match &self.package.metadata {
90+
Some(CargoTomlMetadata {
91+
pyo3_pack: Some(extra_metadata),
92+
}) => extra_metadata.clone(),
93+
_ => Default::default(),
94+
}
95+
}
8696
}
8797

8898
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
99+
#[serde(rename_all = "kebab-case")]
89100
struct CargoTomlMetadata {
90-
#[serde(rename = "pyo3-pack")]
91-
pyo3_pack: Option<CargoTomlMetadataPyo3Pack>,
101+
pyo3_pack: Option<RemainingCoreMetadata>,
92102
}
93103

94-
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
95-
struct CargoTomlMetadataPyo3Pack {
96-
scripts: Option<HashMap<String, String>>,
97-
classifier: Option<Vec<String>>,
104+
/// The `[project.metadata.pyo3-pack]` with the python specific metadata
105+
///
106+
/// Those fields are the part of the
107+
/// [python core metadata](https://packaging.python.org/specifications/core-metadata/)
108+
/// that doesn't have an equivalent in cargo's `[package]` table
109+
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, Default)]
110+
#[serde(rename_all = "kebab-case")]
111+
pub struct RemainingCoreMetadata {
112+
pub scripts: Option<HashMap<String, String>>,
113+
pub classifier: Option<Vec<String>>,
114+
pub maintainer: Option<String>,
115+
pub maintainer_email: Option<String>,
116+
pub requires_dist: Option<Vec<String>>,
117+
pub requires_python: Option<String>,
118+
pub requires_external: Option<Vec<String>>,
119+
pub project_url: Option<Vec<String>>,
120+
pub provides_extra: Option<Vec<String>>,
98121
}
99122

100123
#[cfg(test)]
@@ -124,6 +147,7 @@ mod test {
124147
125148
[package.metadata.pyo3-pack]
126149
classifier = ["Programming Language :: Python"]
150+
requires-dist = ["flask~=1.1.0", "toml==0.10.0"]
127151
"#
128152
);
129153

@@ -134,7 +158,13 @@ mod test {
134158

135159
let classifier = vec!["Programming Language :: Python".to_string()];
136160

161+
let requires_dist = Some(vec!["flask~=1.1.0".to_string(), "toml==0.10.0".to_string()]);
162+
137163
assert_eq!(cargo_toml.scripts(), scripts);
138164
assert_eq!(cargo_toml.classifier(), classifier);
165+
assert_eq!(
166+
cargo_toml.remaining_core_metadata().requires_dist,
167+
requires_dist
168+
);
139169
}
140170
}

src/metadata.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,14 @@ impl Metadata21 {
8585

8686
let classifier = cargo_toml.classifier();
8787

88+
let extra_metadata = cargo_toml.remaining_core_metadata();
89+
8890
Ok(Metadata21 {
8991
metadata_version: "2.1".to_owned(),
92+
93+
// Mapped from cargo metadata
9094
name: cargo_toml.package.name.to_owned(),
9195
version: cargo_toml.package.version.clone(),
92-
platform: Vec::new(),
93-
supported_platform: Vec::new(),
9496
summary: cargo_toml.package.description.clone(),
9597
description,
9698
description_content_type,
@@ -104,17 +106,25 @@ impl Metadata21 {
104106
// Cargo.toml has no distinction between author and author email
105107
author: Some(authors.to_owned()),
106108
author_email: Some(authors.to_owned()),
107-
maintainer: None,
108-
maintainer_email: None,
109109
license: cargo_toml.package.license.clone(),
110+
111+
// Values provided through `[project.metadata.pyo3-pack]`
110112
classifier,
111-
requires_dist: Vec::new(),
113+
maintainer: extra_metadata.maintainer,
114+
maintainer_email: extra_metadata.maintainer_email,
115+
requires_dist: extra_metadata.requires_dist.unwrap_or_default(),
116+
requires_python: extra_metadata.requires_python,
117+
requires_external: extra_metadata.requires_external.unwrap_or_default(),
118+
project_url: extra_metadata.project_url.unwrap_or_default(),
119+
provides_extra: extra_metadata.provides_extra.unwrap_or_default(),
120+
121+
// Officially rarely used, and afaik not applicable with pyo3
112122
provides_dist: Vec::new(),
113123
obsoletes_dist: Vec::new(),
114-
requires_python: None,
115-
requires_external: Vec::new(),
116-
project_url: Vec::new(),
117-
provides_extra: Vec::new(),
124+
125+
// Open question: Should those also be supported? And if so, how?
126+
platform: Vec::new(),
127+
supported_platform: Vec::new(),
118128
})
119129
}
120130

@@ -281,6 +291,7 @@ mod test {
281291
282292
[package.metadata.pyo3-pack]
283293
classifier = ["Programming Language :: Python"]
294+
requires-dist = ["flask~=1.1.0", "toml==0.10.0"]
284295
"#
285296
)
286297
.replace("readme.md", &readme_path);
@@ -296,6 +307,8 @@ mod test {
296307
Name: info-project
297308
Version: 0.1.0
298309
Classifier: Programming Language :: Python
310+
Requires-Dist: flask~=1.1.0
311+
Requires-Dist: toml==0.10.0
299312
Summary: A test project
300313
Keywords: ffi test
301314
Home-Page: https://example.org

0 commit comments

Comments
 (0)