maturin 1.8.4__tar.gz → 1.8.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of maturin might be problematic. Click here for more details.

Files changed (62) hide show
  1. {maturin-1.8.4 → maturin-1.8.7}/.pre-commit-config.yaml +2 -2
  2. {maturin-1.8.4 → maturin-1.8.7}/Cargo.lock +101 -19
  3. {maturin-1.8.4 → maturin-1.8.7}/Cargo.toml +5 -3
  4. {maturin-1.8.4 → maturin-1.8.7}/Changelog.md +18 -1
  5. {maturin-1.8.4 → maturin-1.8.7}/PKG-INFO +1 -1
  6. {maturin-1.8.4 → maturin-1.8.7}/maturin/bootstrap.py +14 -6
  7. {maturin-1.8.4 → maturin-1.8.7}/pyproject.toml +8 -10
  8. {maturin-1.8.4 → maturin-1.8.7}/src/bridge.rs +12 -2
  9. {maturin-1.8.4 → maturin-1.8.7}/src/build_context.rs +48 -9
  10. {maturin-1.8.4 → maturin-1.8.7}/src/build_options.rs +25 -26
  11. {maturin-1.8.4 → maturin-1.8.7}/src/ci.rs +3 -3
  12. maturin-1.8.7/src/compression.rs +88 -0
  13. {maturin-1.8.4 → maturin-1.8.7}/src/develop.rs +9 -1
  14. {maturin-1.8.4 → maturin-1.8.7}/src/lib.rs +3 -1
  15. {maturin-1.8.4 → maturin-1.8.7}/src/main.rs +12 -3
  16. {maturin-1.8.4 → maturin-1.8.7}/src/metadata.rs +4 -2
  17. {maturin-1.8.4 → maturin-1.8.7}/src/module_writer.rs +29 -27
  18. {maturin-1.8.4 → maturin-1.8.7}/src/python_interpreter/mod.rs +2 -2
  19. {maturin-1.8.4 → maturin-1.8.7}/src/templates/Cargo.toml.j2 +1 -1
  20. {maturin-1.8.4 → maturin-1.8.7}/.cirrus.yml +0 -0
  21. {maturin-1.8.4 → maturin-1.8.7}/.codespellrc +0 -0
  22. {maturin-1.8.4 → maturin-1.8.7}/.config/nextest.toml +0 -0
  23. {maturin-1.8.4 → maturin-1.8.7}/.gitignore +0 -0
  24. {maturin-1.8.4 → maturin-1.8.7}/MANIFEST.in +0 -0
  25. {maturin-1.8.4 → maturin-1.8.7}/README.md +0 -0
  26. {maturin-1.8.4 → maturin-1.8.7}/clippy.toml +0 -0
  27. {maturin-1.8.4 → maturin-1.8.7}/license-apache +0 -0
  28. {maturin-1.8.4 → maturin-1.8.7}/license-mit +0 -0
  29. {maturin-1.8.4 → maturin-1.8.7}/maturin/__init__.py +0 -0
  30. {maturin-1.8.4 → maturin-1.8.7}/maturin/__main__.py +0 -0
  31. {maturin-1.8.4 → maturin-1.8.7}/maturin.schema.json +0 -0
  32. {maturin-1.8.4 → maturin-1.8.7}/netlify.toml +0 -0
  33. {maturin-1.8.4 → maturin-1.8.7}/setup.py +0 -0
  34. {maturin-1.8.4 → maturin-1.8.7}/src/auditwheel/audit.rs +0 -0
  35. {maturin-1.8.4 → maturin-1.8.7}/src/auditwheel/manylinux-policy.json +0 -0
  36. {maturin-1.8.4 → maturin-1.8.7}/src/auditwheel/mod.rs +0 -0
  37. {maturin-1.8.4 → maturin-1.8.7}/src/auditwheel/musllinux-policy.json +0 -0
  38. {maturin-1.8.4 → maturin-1.8.7}/src/auditwheel/musllinux.rs +0 -0
  39. {maturin-1.8.4 → maturin-1.8.7}/src/auditwheel/patchelf.rs +0 -0
  40. {maturin-1.8.4 → maturin-1.8.7}/src/auditwheel/platform_tag.rs +0 -0
  41. {maturin-1.8.4 → maturin-1.8.7}/src/auditwheel/policy.rs +0 -0
  42. {maturin-1.8.4 → maturin-1.8.7}/src/auditwheel/repair.rs +0 -0
  43. {maturin-1.8.4 → maturin-1.8.7}/src/cargo_toml.rs +0 -0
  44. {maturin-1.8.4 → maturin-1.8.7}/src/compile.rs +0 -0
  45. {maturin-1.8.4 → maturin-1.8.7}/src/cross_compile.rs +0 -0
  46. {maturin-1.8.4 → maturin-1.8.7}/src/generate_json_schema.rs +0 -0
  47. {maturin-1.8.4 → maturin-1.8.7}/src/new_project.rs +0 -0
  48. {maturin-1.8.4 → maturin-1.8.7}/src/project_layout.rs +0 -0
  49. {maturin-1.8.4 → maturin-1.8.7}/src/pyproject_toml.rs +0 -0
  50. {maturin-1.8.4 → maturin-1.8.7}/src/python_interpreter/config.rs +0 -0
  51. {maturin-1.8.4 → maturin-1.8.7}/src/python_interpreter/get_interpreter_metadata.py +0 -0
  52. {maturin-1.8.4 → maturin-1.8.7}/src/source_distribution.rs +0 -0
  53. {maturin-1.8.4 → maturin-1.8.7}/src/target.rs +0 -0
  54. {maturin-1.8.4 → maturin-1.8.7}/src/templates/.gitignore.j2 +0 -0
  55. {maturin-1.8.4 → maturin-1.8.7}/src/templates/__init__.py.j2 +0 -0
  56. {maturin-1.8.4 → maturin-1.8.7}/src/templates/build.rs.j2 +0 -0
  57. {maturin-1.8.4 → maturin-1.8.7}/src/templates/example.udl.j2 +0 -0
  58. {maturin-1.8.4 → maturin-1.8.7}/src/templates/lib.rs.j2 +0 -0
  59. {maturin-1.8.4 → maturin-1.8.7}/src/templates/main.rs.j2 +0 -0
  60. {maturin-1.8.4 → maturin-1.8.7}/src/templates/pyproject.toml.j2 +0 -0
  61. {maturin-1.8.4 → maturin-1.8.7}/src/templates/test_all.py.j2 +0 -0
  62. {maturin-1.8.4 → maturin-1.8.7}/src/upload.rs +0 -0
@@ -56,12 +56,12 @@ repos:
56
56
  )
57
57
  - id: mixed-line-ending
58
58
  - repo: https://github.com/astral-sh/ruff-pre-commit
59
- rev: v0.11.8
59
+ rev: v0.11.12
60
60
  hooks:
61
61
  - id: ruff-format
62
62
  - id: ruff
63
63
  - repo: https://github.com/pre-commit/mirrors-mypy
64
- rev: v1.15.0
64
+ rev: v1.16.0
65
65
  hooks:
66
66
  - id: mypy
67
67
  entry: mypy maturin/
@@ -262,9 +262,9 @@ dependencies = [
262
262
 
263
263
  [[package]]
264
264
  name = "cargo-xwin"
265
- version = "0.18.4"
265
+ version = "0.18.6"
266
266
  source = "registry+https://github.com/rust-lang/crates.io-index"
267
- checksum = "60f1954e4ffa0f4c47b3df5e6e9508706d8dcaa56152cd672dcee02930ba0326"
267
+ checksum = "5dff83aad332bd6ee29072dd874b48892cd22c58e233c25735eb4417b3999685"
268
268
  dependencies = [
269
269
  "anyhow",
270
270
  "cargo-config2",
@@ -330,11 +330,11 @@ dependencies = [
330
330
 
331
331
  [[package]]
332
332
  name = "cbindgen"
333
- version = "0.28.0"
333
+ version = "0.29.0"
334
334
  source = "registry+https://github.com/rust-lang/crates.io-index"
335
- checksum = "eadd868a2ce9ca38de7eeafdcec9c7065ef89b42b32f0839278d55f35c54d1ff"
335
+ checksum = "975982cdb7ad6a142be15bdf84aea7ec6a9e5d4d797c004d43185b24cfe4e684"
336
336
  dependencies = [
337
- "heck 0.4.1",
337
+ "heck",
338
338
  "indexmap",
339
339
  "log",
340
340
  "proc-macro2",
@@ -352,6 +352,8 @@ version = "1.2.16"
352
352
  source = "registry+https://github.com/rust-lang/crates.io-index"
353
353
  checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c"
354
354
  dependencies = [
355
+ "jobserver",
356
+ "libc",
355
357
  "shlex",
356
358
  ]
357
359
 
@@ -451,7 +453,7 @@ version = "4.5.5"
451
453
  source = "registry+https://github.com/rust-lang/crates.io-index"
452
454
  checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6"
453
455
  dependencies = [
454
- "heck 0.5.0",
456
+ "heck",
455
457
  "proc-macro2",
456
458
  "quote",
457
459
  "syn",
@@ -951,7 +953,19 @@ checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
951
953
  dependencies = [
952
954
  "cfg-if",
953
955
  "libc",
954
- "wasi",
956
+ "wasi 0.11.0+wasi-snapshot-preview1",
957
+ ]
958
+
959
+ [[package]]
960
+ name = "getrandom"
961
+ version = "0.3.3"
962
+ source = "registry+https://github.com/rust-lang/crates.io-index"
963
+ checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
964
+ dependencies = [
965
+ "cfg-if",
966
+ "libc",
967
+ "r-efi",
968
+ "wasi 0.14.2+wasi-0.2.4",
955
969
  ]
956
970
 
957
971
  [[package]]
@@ -1000,12 +1014,6 @@ version = "0.15.2"
1000
1014
  source = "registry+https://github.com/rust-lang/crates.io-index"
1001
1015
  checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
1002
1016
 
1003
- [[package]]
1004
- name = "heck"
1005
- version = "0.4.1"
1006
- source = "registry+https://github.com/rust-lang/crates.io-index"
1007
- checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
1008
-
1009
1017
  [[package]]
1010
1018
  name = "heck"
1011
1019
  version = "0.5.0"
@@ -1252,6 +1260,16 @@ version = "1.0.11"
1252
1260
  source = "registry+https://github.com/rust-lang/crates.io-index"
1253
1261
  checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
1254
1262
 
1263
+ [[package]]
1264
+ name = "jobserver"
1265
+ version = "0.1.33"
1266
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1267
+ checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a"
1268
+ dependencies = [
1269
+ "getrandom 0.3.3",
1270
+ "libc",
1271
+ ]
1272
+
1255
1273
  [[package]]
1256
1274
  name = "js-sys"
1257
1275
  version = "0.3.73"
@@ -1290,9 +1308,9 @@ dependencies = [
1290
1308
 
1291
1309
  [[package]]
1292
1310
  name = "libc"
1293
- version = "0.2.167"
1311
+ version = "0.2.172"
1294
1312
  source = "registry+https://github.com/rust-lang/crates.io-index"
1295
- checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc"
1313
+ checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
1296
1314
 
1297
1315
  [[package]]
1298
1316
  name = "libmimalloc-sys"
@@ -1358,6 +1376,16 @@ version = "0.4.22"
1358
1376
  source = "registry+https://github.com/rust-lang/crates.io-index"
1359
1377
  checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
1360
1378
 
1379
+ [[package]]
1380
+ name = "lzma-rs"
1381
+ version = "0.3.0"
1382
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1383
+ checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e"
1384
+ dependencies = [
1385
+ "byteorder",
1386
+ "crc",
1387
+ ]
1388
+
1361
1389
  [[package]]
1362
1390
  name = "lzma-sys"
1363
1391
  version = "0.1.20"
@@ -1397,7 +1425,7 @@ dependencies = [
1397
1425
 
1398
1426
  [[package]]
1399
1427
  name = "maturin"
1400
- version = "1.8.4"
1428
+ version = "1.8.7"
1401
1429
  dependencies = [
1402
1430
  "anyhow",
1403
1431
  "base64 0.21.7",
@@ -1899,6 +1927,12 @@ version = "0.5.0"
1899
1927
  source = "registry+https://github.com/rust-lang/crates.io-index"
1900
1928
  checksum = "79ec282e887b434b68c18fe5c121d38e72a5cf35119b59e54ec5b992ea9c8eb0"
1901
1929
 
1930
+ [[package]]
1931
+ name = "r-efi"
1932
+ version = "5.2.0"
1933
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1934
+ checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
1935
+
1902
1936
  [[package]]
1903
1937
  name = "rand"
1904
1938
  version = "0.8.5"
@@ -1926,7 +1960,7 @@ version = "0.6.4"
1926
1960
  source = "registry+https://github.com/rust-lang/crates.io-index"
1927
1961
  checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
1928
1962
  dependencies = [
1929
- "getrandom",
1963
+ "getrandom 0.2.15",
1930
1964
  ]
1931
1965
 
1932
1966
  [[package]]
@@ -1973,7 +2007,7 @@ version = "0.4.5"
1973
2007
  source = "registry+https://github.com/rust-lang/crates.io-index"
1974
2008
  checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891"
1975
2009
  dependencies = [
1976
- "getrandom",
2010
+ "getrandom 0.2.15",
1977
2011
  "libredox",
1978
2012
  "thiserror 1.0.69",
1979
2013
  ]
@@ -2050,7 +2084,7 @@ checksum = "70ac5d832aa16abd7d1def883a8545280c20a60f523a370aa3a9617c2b8550ee"
2050
2084
  dependencies = [
2051
2085
  "cc",
2052
2086
  "cfg-if",
2053
- "getrandom",
2087
+ "getrandom 0.2.15",
2054
2088
  "libc",
2055
2089
  "untrusted",
2056
2090
  "windows-sys 0.52.0",
@@ -2973,6 +3007,15 @@ version = "0.11.0+wasi-snapshot-preview1"
2973
3007
  source = "registry+https://github.com/rust-lang/crates.io-index"
2974
3008
  checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
2975
3009
 
3010
+ [[package]]
3011
+ name = "wasi"
3012
+ version = "0.14.2+wasi-0.2.4"
3013
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3014
+ checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
3015
+ dependencies = [
3016
+ "wit-bindgen-rt",
3017
+ ]
3018
+
2976
3019
  [[package]]
2977
3020
  name = "wasm-bindgen"
2978
3021
  version = "0.2.96"
@@ -3262,6 +3305,15 @@ version = "0.0.19"
3262
3305
  source = "registry+https://github.com/rust-lang/crates.io-index"
3263
3306
  checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904"
3264
3307
 
3308
+ [[package]]
3309
+ name = "wit-bindgen-rt"
3310
+ version = "0.39.0"
3311
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3312
+ checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
3313
+ dependencies = [
3314
+ "bitflags 2.5.0",
3315
+ ]
3316
+
3265
3317
  [[package]]
3266
3318
  name = "write16"
3267
3319
  version = "1.0.0"
@@ -3440,10 +3492,12 @@ dependencies = [
3440
3492
  "displaydoc",
3441
3493
  "flate2",
3442
3494
  "indexmap",
3495
+ "lzma-rs",
3443
3496
  "memchr",
3444
3497
  "thiserror 2.0.3",
3445
3498
  "time",
3446
3499
  "zopfli",
3500
+ "zstd",
3447
3501
  ]
3448
3502
 
3449
3503
  [[package]]
@@ -3459,3 +3513,31 @@ dependencies = [
3459
3513
  "once_cell",
3460
3514
  "simd-adler32",
3461
3515
  ]
3516
+
3517
+ [[package]]
3518
+ name = "zstd"
3519
+ version = "0.13.3"
3520
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3521
+ checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a"
3522
+ dependencies = [
3523
+ "zstd-safe",
3524
+ ]
3525
+
3526
+ [[package]]
3527
+ name = "zstd-safe"
3528
+ version = "7.2.4"
3529
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3530
+ checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d"
3531
+ dependencies = [
3532
+ "zstd-sys",
3533
+ ]
3534
+
3535
+ [[package]]
3536
+ name = "zstd-sys"
3537
+ version = "2.0.15+zstd.1.5.7"
3538
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3539
+ checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237"
3540
+ dependencies = [
3541
+ "cc",
3542
+ "pkg-config",
3543
+ ]
@@ -1,7 +1,7 @@
1
1
  [package]
2
2
  authors = ["konstin <konstin@mailbox.org>", "messense <messense@icloud.com>"]
3
3
  name = "maturin"
4
- version = "1.8.4"
4
+ version = "1.8.7"
5
5
  description = "Build and publish crates with pyo3, cffi and uniffi bindings as well as rust binaries as python packages"
6
6
  exclude = [
7
7
  "test-crates/**/*",
@@ -45,7 +45,7 @@ glob = "0.3.0"
45
45
  cargo-config2 = "0.1.24"
46
46
  cargo_metadata = "0.19.0"
47
47
  cargo-options = "0.7.2"
48
- cbindgen = { version = "0.28.0", default-features = false }
48
+ cbindgen = { version = "0.29.0", default-features = false }
49
49
  flate2 = "1.0.18"
50
50
  goblin = "0.9.0"
51
51
  platform-info = "2.0.2"
@@ -61,6 +61,8 @@ zip = { version = "2.3.0", default-features = false, features = [
61
61
  "bzip2",
62
62
  "deflate",
63
63
  "time",
64
+ "zstd",
65
+ "lzma"
64
66
  ] }
65
67
  thiserror = "2.0.3"
66
68
  fs-err = "3.0.0"
@@ -98,7 +100,7 @@ clap_complete_command = { version = "0.6.1", optional = true }
98
100
 
99
101
  # cross compile
100
102
  cargo-zigbuild = { version = "0.20.0", default-features = false, optional = true }
101
- cargo-xwin = { version = "0.18.4", default-features = false, optional = true }
103
+ cargo-xwin = { version = "0.18.6", default-features = false, optional = true }
102
104
 
103
105
  # log
104
106
  tracing = "0.1.36"
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.8.7]
4
+
5
+ - Allow specifying compression method and level, in both `build` and `develop` modes, in [#2625](https://github.com/PyO3/maturin/pull/2625).
6
+ - Fix Windows free-threaded builds on Python 3.14 in [#2632](https://github.com/PyO3/maturin/pull/2632)
7
+
8
+ ## [1.8.6]
9
+
10
+ * Print a message when overriding platform tag from `_PYTHON_HOST_PLATFORM` in [#2594](https://github.com/PyO3/maturin/pull/2594)
11
+ * Use the current python interpreter's version when the abi3 feature is set with no explicit version in [#2597](https://github.com/PyO3/maturin/pull/2597)
12
+
13
+ ## [1.8.5]
14
+
15
+ * Fix release CI build
16
+
3
17
  ## [1.8.4]
4
18
 
5
19
  * Install a Rust toolchain into a temporary directory when building maturin itself or a package and a Rust toolchain is
@@ -1060,7 +1074,10 @@ points-0.1.0-py2.py3-none-manylinux1_x86_64.whl | 2,8M | 752K | 85K
1060
1074
 
1061
1075
  * Initial Release
1062
1076
 
1063
- [Unreleased]: https://github.com/pyo3/maturin/compare/v1.8.4...HEAD
1077
+ [Unreleased]: https://github.com/pyo3/maturin/compare/v1.8.7...HEAD
1078
+ [1.8.7]: https://github.com/pyo3/maturin/compare/v1.8.6...v1.8.7
1079
+ [1.8.6]: https://github.com/pyo3/maturin/compare/v1.8.5...v1.8.6
1080
+ [1.8.5]: https://github.com/pyo3/maturin/compare/v1.8.4...v1.8.5
1064
1081
  [1.8.4]: https://github.com/pyo3/maturin/compare/v1.8.3...v1.8.4
1065
1082
  [1.8.3]: https://github.com/pyo3/maturin/compare/v1.8.2...v1.8.3
1066
1083
  [1.8.2]: https://github.com/pyo3/maturin/compare/v1.8.1...v1.8.2
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maturin
3
- Version: 1.8.4
3
+ Version: 1.8.7
4
4
  Classifier: Topic :: Software Development :: Build Tools
5
5
  Classifier: Programming Language :: Rust
6
6
  Classifier: Programming Language :: Python :: Implementation :: CPython
@@ -17,15 +17,23 @@ from typing import Any
17
17
 
18
18
  # noinspection PyUnresolvedReferences
19
19
  from setuptools.build_meta import * # noqa:F403
20
+ from setuptools.build_meta import (
21
+ get_requires_for_build_sdist as _orig_get_requires_for_build_sdist,
22
+ )
23
+ from setuptools.build_meta import (
24
+ get_requires_for_build_wheel as _orig_get_requires_for_build_wheel,
25
+ )
20
26
 
21
27
 
22
- def get_requires_for_build_wheel(_config_settings: dict[str, Any] | None = None) -> list[str]:
28
+ def get_requires_for_build_wheel(config_settings: dict[str, Any] | None = None) -> list[str]:
29
+ reqs = _orig_get_requires_for_build_wheel()
23
30
  if not os.environ.get("MATURIN_NO_INSTALL_RUST") and not shutil.which("cargo"):
24
- return ["puccinialin>=0.1,<0.2"]
25
- return []
31
+ reqs.append("puccinialin>=0.1,<0.2")
32
+ return reqs
26
33
 
27
34
 
28
- def get_requires_for_build_sdist(_config_settings: dict[str, Any] | None = None) -> list[str]:
35
+ def get_requires_for_build_sdist(config_settings: dict[str, Any] | None = None) -> list[str]:
36
+ reqs = _orig_get_requires_for_build_sdist()
29
37
  if not os.environ.get("MATURIN_NO_INSTALL_RUST") and not shutil.which("cargo"):
30
- return ["puccinialin>=0.1,<0.2"]
31
- return []
38
+ reqs.append("puccinialin>=0.1,<0.2")
39
+ return reqs
@@ -1,6 +1,10 @@
1
1
  # Workaround to bootstrap maturin on non-manylinux platforms
2
2
  [build-system]
3
- requires = ["setuptools", "tomli>=1.1.0 ; python_version<'3.11'", "setuptools-rust"]
3
+ requires = [
4
+ "setuptools",
5
+ "tomli>=1.1.0 ; python_version<'3.11'",
6
+ "setuptools-rust>=1.11.0",
7
+ ]
4
8
  backend-path = ["maturin"]
5
9
  build-backend = "bootstrap"
6
10
 
@@ -18,17 +22,11 @@ classifiers = [
18
22
  "Programming Language :: Python :: Implementation :: PyPy",
19
23
  ]
20
24
  dependencies = ["tomli>=1.1.0 ; python_version<'3.11'"]
21
- dynamic = [
22
- "version"
23
- ]
25
+ dynamic = ["version"]
24
26
 
25
27
  [project.optional-dependencies]
26
- zig = [
27
- "ziglang>=0.10.0,<0.13.0",
28
- ]
29
- patchelf = [
30
- "patchelf",
31
- ]
28
+ zig = ["ziglang>=0.10.0,<0.13.0"]
29
+ patchelf = ["patchelf"]
32
30
 
33
31
  [project.urls]
34
32
  "Source Code" = "https://github.com/PyO3/maturin"
@@ -110,6 +110,16 @@ impl TryFrom<PyO3MetadataRaw> for PyO3Metadata {
110
110
  }
111
111
  }
112
112
 
113
+ /// Python version to use as the abi3 target.
114
+ #[derive(Clone, Debug, PartialEq, Eq)]
115
+ pub enum Abi3Version {
116
+ /// abi3 wheels will have a minimum Python version matching the version of
117
+ /// the current Python interpreter
118
+ CurrentPython,
119
+ /// abi3 wheels will have a fixed minimum Python version
120
+ Version(u8, u8),
121
+ }
122
+
113
123
  /// The name and version of the pyo3 bindings crate
114
124
  #[derive(Clone, Debug, PartialEq, Eq)]
115
125
  pub struct PyO3 {
@@ -118,7 +128,7 @@ pub struct PyO3 {
118
128
  /// pyo3 bindings crate version
119
129
  pub version: semver::Version,
120
130
  /// abi3 support
121
- pub abi3: Option<(u8, u8)>,
131
+ pub abi3: Option<Abi3Version>,
122
132
  /// pyo3 metadata
123
133
  pub metadata: Option<PyO3Metadata>,
124
134
  }
@@ -136,7 +146,7 @@ impl PyO3 {
136
146
  } else {
137
147
  MINIMUM_PYTHON_MINOR
138
148
  };
139
- if let Some((_, abi3_minor)) = self.abi3.as_ref() {
149
+ if let Some(Abi3Version::Version(_, abi3_minor)) = self.abi3.as_ref() {
140
150
  min_minor.max(*abi3_minor as usize)
141
151
  } else {
142
152
  min_minor
@@ -1,7 +1,9 @@
1
1
  use crate::auditwheel::{get_policy_and_libs, patchelf, relpath, AuditWheelMode};
2
2
  use crate::auditwheel::{PlatformTag, Policy};
3
+ use crate::bridge::Abi3Version;
3
4
  use crate::build_options::CargoOptions;
4
5
  use crate::compile::{warn_missing_py_init, CompileTarget};
6
+ use crate::compression::CompressionOptions;
5
7
  use crate::module_writer::{
6
8
  add_data, write_bin, write_bindings_module, write_cffi_module, write_python_part,
7
9
  write_uniffi_module, write_wasm_launcher, WheelWriter,
@@ -131,8 +133,8 @@ pub struct BuildContext {
131
133
  pub editable: bool,
132
134
  /// Cargo build options
133
135
  pub cargo_options: CargoOptions,
134
- /// Zip compression level
135
- pub compression_level: u16,
136
+ /// Compression options
137
+ pub compression: CompressionOptions,
136
138
  }
137
139
 
138
140
  /// The wheel file location and its Python version tag (e.g. `py3`).
@@ -155,7 +157,7 @@ impl BuildContext {
155
157
  BridgeModel::Bin(None) => self.build_bin_wheel(None)?,
156
158
  BridgeModel::Bin(Some(..)) => self.build_bin_wheels(&self.interpreter)?,
157
159
  BridgeModel::PyO3(crate::PyO3 { abi3, .. }) => match abi3 {
158
- Some((major, minor)) => {
160
+ Some(Abi3Version::Version(major, minor)) => {
159
161
  let abi3_interps: Vec<_> = self
160
162
  .interpreter
161
163
  .iter()
@@ -189,6 +191,41 @@ impl BuildContext {
189
191
  }
190
192
  built_wheels
191
193
  }
194
+ Some(Abi3Version::CurrentPython) => {
195
+ let abi3_interps: Vec<_> = self
196
+ .interpreter
197
+ .iter()
198
+ .filter(|interp| interp.has_stable_api())
199
+ .cloned()
200
+ .collect();
201
+ let non_abi3_interps: Vec<_> = self
202
+ .interpreter
203
+ .iter()
204
+ .filter(|interp| !interp.has_stable_api())
205
+ .cloned()
206
+ .collect();
207
+ let mut built_wheels = Vec::new();
208
+ if !abi3_interps.is_empty() {
209
+ let interp = abi3_interps.first().unwrap();
210
+ built_wheels.extend(self.build_pyo3_wheel_abi3(
211
+ &abi3_interps,
212
+ interp.major as u8,
213
+ interp.minor as u8,
214
+ )?);
215
+ }
216
+ if !non_abi3_interps.is_empty() {
217
+ let interp_names: HashSet<_> = non_abi3_interps
218
+ .iter()
219
+ .map(|interp| interp.to_string())
220
+ .collect();
221
+ eprintln!(
222
+ "⚠️ Warning: {} does not yet support abi3 so the build artifacts will be version-specific.",
223
+ interp_names.iter().join(", ")
224
+ );
225
+ built_wheels.extend(self.build_pyo3_wheels(&non_abi3_interps)?);
226
+ }
227
+ built_wheels
228
+ }
192
229
  None => self.build_pyo3_wheels(&self.interpreter)?,
193
230
  },
194
231
  BridgeModel::Cffi => self.build_cffi_wheel()?,
@@ -485,7 +522,9 @@ impl BuildContext {
485
522
  /// Returns the platform part of the tag for the wheel name
486
523
  pub fn get_platform_tag(&self, platform_tags: &[PlatformTag]) -> Result<String> {
487
524
  if let Ok(host_platform) = env::var("_PYTHON_HOST_PLATFORM") {
488
- return Ok(host_platform.replace(['.', '-'], "_"));
525
+ let override_platform = host_platform.replace(['.', '-'], "_");
526
+ eprintln!("🚉 Overriding platform tag from _PYTHON_HOST_PLATFORM environment variable as {override_platform}.");
527
+ return Ok(override_platform);
489
528
  }
490
529
 
491
530
  let target = &self.target;
@@ -633,7 +672,7 @@ impl BuildContext {
633
672
  &self.metadata24,
634
673
  &[tag.clone()],
635
674
  self.excludes(Format::Wheel)?,
636
- self.compression_level,
675
+ self.compression,
637
676
  )?;
638
677
  self.add_external_libs(&mut writer, &[&artifact], &[ext_libs])?;
639
678
 
@@ -711,7 +750,7 @@ impl BuildContext {
711
750
  &self.metadata24,
712
751
  &[tag.clone()],
713
752
  self.excludes(Format::Wheel)?,
714
- self.compression_level,
753
+ self.compression,
715
754
  )?;
716
755
  self.add_external_libs(&mut writer, &[&artifact], &[ext_libs])?;
717
756
 
@@ -834,7 +873,7 @@ impl BuildContext {
834
873
  &self.metadata24,
835
874
  &tags,
836
875
  self.excludes(Format::Wheel)?,
837
- self.compression_level,
876
+ self.compression,
838
877
  )?;
839
878
  self.add_external_libs(&mut writer, &[&artifact], &[ext_libs])?;
840
879
 
@@ -906,7 +945,7 @@ impl BuildContext {
906
945
  &self.metadata24,
907
946
  &tags,
908
947
  self.excludes(Format::Wheel)?,
909
- self.compression_level,
948
+ self.compression,
910
949
  )?;
911
950
  self.add_external_libs(&mut writer, &[&artifact], &[ext_libs])?;
912
951
 
@@ -1005,7 +1044,7 @@ impl BuildContext {
1005
1044
  &metadata24,
1006
1045
  &tags,
1007
1046
  self.excludes(Format::Wheel)?,
1008
- self.compression_level,
1047
+ self.compression,
1009
1048
  )?;
1010
1049
 
1011
1050
  if self.project_layout.python_module.is_some() && self.target.is_wasi() {
@@ -1,6 +1,7 @@
1
1
  use crate::auditwheel::{AuditWheelMode, PlatformTag};
2
- use crate::bridge::PyO3Crate;
2
+ use crate::bridge::{Abi3Version, PyO3Crate};
3
3
  use crate::compile::{CompileTarget, LIB_CRATE_TYPES};
4
+ use crate::compression::CompressionOptions;
4
5
  use crate::cross_compile::{find_sysconfigdata, parse_sysconfigdata};
5
6
  use crate::project_layout::ProjectResolver;
6
7
  use crate::pyproject_toml::ToolMaturin;
@@ -217,10 +218,9 @@ pub struct BuildOptions {
217
218
  #[command(flatten)]
218
219
  pub cargo: CargoOptions,
219
220
 
220
- /// Zip compresson level to use
221
- #[arg(long, value_parser = clap::value_parser!(u16).range(0..=264), hide = true, default_value="6"
222
- )]
223
- pub compression_level: u16,
221
+ /// Wheel compression options
222
+ #[command(flatten)]
223
+ pub compression: CompressionOptions,
224
224
  }
225
225
 
226
226
  impl Deref for BuildOptions {
@@ -250,7 +250,7 @@ impl BuildOptions {
250
250
  match bridge {
251
251
  BridgeModel::PyO3(PyO3 { abi3, .. }) | BridgeModel::Bin(Some(PyO3 { abi3, .. })) => {
252
252
  match abi3 {
253
- None => {
253
+ None | Some(Abi3Version::CurrentPython) => {
254
254
  let mut interpreters = Vec::new();
255
255
  if let Some(config_file) = env::var_os("PYO3_CONFIG_FILE") {
256
256
  let interpreter_config =
@@ -385,7 +385,7 @@ impl BuildOptions {
385
385
 
386
386
  Ok(interpreters)
387
387
  }
388
- Some((major, minor)) => {
388
+ Some(Abi3Version::Version(major, minor)) => {
389
389
  let found_interpreters =
390
390
  find_interpreter_in_host(bridge, interpreter, target, requires_python)
391
391
  .or_else(|err| {
@@ -587,6 +587,7 @@ impl BuildContextBuilder {
587
587
  editable,
588
588
  sdist_only,
589
589
  } = self;
590
+ build_options.compression.validate();
590
591
  let ProjectResolver {
591
592
  project_layout,
592
593
  cargo_toml_path,
@@ -807,7 +808,7 @@ impl BuildContextBuilder {
807
808
  universal2,
808
809
  editable,
809
810
  cargo_options,
810
- compression_level: build_options.compression_level,
811
+ compression: build_options.compression,
811
812
  })
812
813
  }
813
814
  }
@@ -990,7 +991,7 @@ fn filter_cargo_targets(
990
991
  }
991
992
 
992
993
  /// pyo3 supports building abi3 wheels if the unstable-api feature is not selected
993
- fn has_abi3(deps: &HashMap<&str, &Node>) -> Result<Option<(u8, u8)>> {
994
+ fn has_abi3(deps: &HashMap<&str, &Node>) -> Result<Option<Abi3Version>> {
994
995
  for &lib in PYO3_BINDING_CRATES.iter() {
995
996
  let lib = lib.as_str();
996
997
  if let Some(pyo3_crate) = deps.get(lib) {
@@ -1012,13 +1013,11 @@ fn has_abi3(deps: &HashMap<&str, &Node>) -> Result<Option<(u8, u8)>> {
1012
1013
  .context(format!("Bogus {lib} cargo features"))?
1013
1014
  .into_iter()
1014
1015
  .min();
1015
- if abi3_selected && min_abi3_version.is_none() {
1016
- bail!(
1017
- "You have selected the `abi3` feature but not a minimum version (e.g. the `abi3-py36` feature). \
1018
- maturin needs a minimum version feature to build abi3 wheels."
1019
- )
1016
+ match min_abi3_version {
1017
+ Some((major, minor)) => return Ok(Some(Abi3Version::Version(major, minor))),
1018
+ None if abi3_selected => return Ok(Some(Abi3Version::CurrentPython)),
1019
+ None => {}
1020
1020
  }
1021
- return Ok(min_abi3_version);
1022
1021
  }
1023
1022
  }
1024
1023
  Ok(None)
@@ -1212,13 +1211,13 @@ pub fn find_bridge(cargo_metadata: &Metadata, bridge: Option<&str>) -> Result<Br
1212
1211
  );
1213
1212
  }
1214
1213
 
1215
- return if let Some((major, minor)) = has_abi3(&deps)? {
1216
- eprintln!("🔗 Found {lib} bindings with abi3 support for Python ≥ {major}.{minor}");
1214
+ return if let Some(abi3_version) = has_abi3(&deps)? {
1215
+ eprintln!("🔗 Found {lib} bindings with abi3 support");
1217
1216
  let pyo3 = bridge.pyo3().expect("should be pyo3 bindings");
1218
1217
  let bindings = PyO3 {
1219
1218
  crate_name: lib,
1220
1219
  version: pyo3.version.clone(),
1221
- abi3: Some((major, minor)),
1220
+ abi3: Some(abi3_version),
1222
1221
  metadata: pyo3.metadata.clone(),
1223
1222
  };
1224
1223
  Ok(BridgeModel::PyO3(bindings))
@@ -1270,9 +1269,9 @@ fn find_interpreter(
1270
1269
  if !interpreter.is_empty() {
1271
1270
  let mut missing = Vec::new();
1272
1271
  for interp in interpreter {
1273
- match PythonInterpreter::check_executable(interp.clone(), target, bridge) {
1274
- Ok(Some(interp)) => found_interpreters.push(interp),
1275
- _ => missing.push(interp.clone()),
1272
+ match PythonInterpreter::check_executable(interp.clone(), target, bridge)? {
1273
+ Some(interp) => found_interpreters.push(interp),
1274
+ None => missing.push(interp.clone()),
1276
1275
  }
1277
1276
  }
1278
1277
  if !missing.is_empty() {
@@ -1403,8 +1402,8 @@ fn find_interpreter_in_sysconfig(
1403
1402
  format!("Failed to find a {python_impl} {ver_major}.{ver_minor} interpreter in known sysconfig")
1404
1403
  })?;
1405
1404
  debug!(
1406
- "Found {} {}.{} in bundled sysconfig",
1407
- sysconfig.interpreter_kind, sysconfig.major, sysconfig.minor,
1405
+ "Found {} {}.{}{} in bundled sysconfig",
1406
+ sysconfig.interpreter_kind, sysconfig.major, sysconfig.minor, sysconfig.abiflags
1408
1407
  );
1409
1408
  interpreters.push(PythonInterpreter::from_config(sysconfig.clone()));
1410
1409
  }
@@ -1622,12 +1621,12 @@ mod test {
1622
1621
 
1623
1622
  let bridge = BridgeModel::PyO3(PyO3 {
1624
1623
  crate_name: PyO3Crate::PyO3,
1625
- version: semver::Version::new(0, 24, 1),
1626
- abi3: Some((3, 7)),
1624
+ version: semver::Version::new(0, 25, 0),
1625
+ abi3: Some(Abi3Version::Version(3, 7)),
1627
1626
  metadata: Some(PyO3Metadata {
1628
1627
  cpython: PyO3VersionMetadata {
1629
1628
  min_minor: 7,
1630
- max_minor: 13,
1629
+ max_minor: 14,
1631
1630
  },
1632
1631
  pypy: PyO3VersionMetadata {
1633
1632
  min_minor: 9,
@@ -664,7 +664,7 @@ jobs:\n",
664
664
  #[cfg(test)]
665
665
  mod tests {
666
666
  use super::GenerateCI;
667
- use crate::{bridge::PyO3Crate, BridgeModel, PyO3};
667
+ use crate::{bridge::PyO3Crate, Abi3Version, BridgeModel, PyO3};
668
668
  use expect_test::expect;
669
669
  use semver::Version;
670
670
 
@@ -874,7 +874,7 @@ mod tests {
874
874
  &BridgeModel::PyO3(PyO3 {
875
875
  crate_name: PyO3Crate::PyO3,
876
876
  version: Version::new(0, 23, 0),
877
- abi3: Some((3, 7)),
877
+ abi3: Some(Abi3Version::Version(3, 7)),
878
878
  metadata: None,
879
879
  }),
880
880
  false,
@@ -1086,7 +1086,7 @@ mod tests {
1086
1086
  &BridgeModel::PyO3(PyO3 {
1087
1087
  crate_name: PyO3Crate::PyO3,
1088
1088
  version: Version::new(0, 23, 0),
1089
- abi3: Some((3, 7)),
1089
+ abi3: Some(Abi3Version::Version(3, 7)),
1090
1090
  metadata: None,
1091
1091
  }),
1092
1092
  false,
@@ -0,0 +1,88 @@
1
+ use clap::{CommandFactory, ValueEnum};
2
+ use serde::{Deserialize, Serialize};
3
+
4
+ #[derive(Serialize, Deserialize, Default, Debug, Copy, Clone, PartialEq, Eq, ValueEnum)]
5
+ /// Wheel ZIP compression method. May only be compatible with recent package manager versions.
6
+ // See https://docs.rs/zip/latest/zip/write/struct.FileOptions.html#method.compression_level
7
+ pub enum CompressionMethod {
8
+ #[default]
9
+ /// Deflate compression (levels 0-9, default 6)
10
+ // NOTE: The levels will change if we enable Zopfli!
11
+ Deflated,
12
+ /// No compression
13
+ Stored,
14
+ /// BZIP2 compression (levels 0-9, default 6)
15
+ Bzip2,
16
+ /// Zstandard compression (supported from Python 3.14; levels -7-22, default 3)
17
+ Zstd,
18
+ }
19
+ impl CompressionMethod {
20
+ /// Default level for this compression method
21
+ // NOTE: This should match the default from the `zip` crates.
22
+ pub fn default_level(self) -> i64 {
23
+ match self {
24
+ CompressionMethod::Deflated => 6,
25
+ CompressionMethod::Stored => 0,
26
+ CompressionMethod::Bzip2 => 6,
27
+ CompressionMethod::Zstd => 3,
28
+ }
29
+ }
30
+ /// Allowed levels for the method.
31
+ pub fn level_range(self) -> std::ops::RangeInclusive<i64> {
32
+ match self {
33
+ CompressionMethod::Deflated => 0..=9,
34
+ CompressionMethod::Stored => 0..=0,
35
+ CompressionMethod::Bzip2 => 0..=9,
36
+ CompressionMethod::Zstd => -7..=22,
37
+ }
38
+ }
39
+ }
40
+ impl From<CompressionMethod> for zip::CompressionMethod {
41
+ fn from(source: CompressionMethod) -> Self {
42
+ match source {
43
+ CompressionMethod::Deflated => zip::CompressionMethod::Deflated,
44
+ CompressionMethod::Stored => zip::CompressionMethod::Stored,
45
+ CompressionMethod::Bzip2 => zip::CompressionMethod::Bzip2,
46
+ CompressionMethod::Zstd => zip::CompressionMethod::ZSTD,
47
+ }
48
+ }
49
+ }
50
+ #[derive(Debug, Default, Serialize, Deserialize, clap::Parser, Clone, Copy, Eq, PartialEq)]
51
+ /// Wheel ZIP compression options.
52
+ pub struct CompressionOptions {
53
+ /// Zip compression method. Only Stored and Deflated are currently compatible with all
54
+ /// package managers.
55
+ #[arg(long, value_enum, default_value_t = CompressionMethod::default())]
56
+ pub compression_method: CompressionMethod,
57
+
58
+ /// Zip compression level. Defaults to method default.
59
+ #[arg(long, allow_negative_numbers = true)]
60
+ pub compression_level: Option<i64>,
61
+ }
62
+ impl CompressionOptions {
63
+ /// Validate arguments, exit on error
64
+ pub fn validate(&self) {
65
+ if let Some(level) = self.compression_level {
66
+ let range = self.compression_method.level_range();
67
+ if !range.contains(&level) {
68
+ let mut cmd = Self::command();
69
+ cmd.error(
70
+ clap::error::ErrorKind::ArgumentConflict,
71
+ format!(
72
+ "Invalid level {} for compression method {:?}. Use a level in range {:?}",
73
+ level, self.compression_method, range
74
+ ),
75
+ )
76
+ .exit();
77
+ }
78
+ }
79
+ }
80
+ /// No compression
81
+ pub fn none() -> Self {
82
+ let method = CompressionMethod::Stored;
83
+ Self {
84
+ compression_method: method,
85
+ compression_level: Some(method.default_level()),
86
+ }
87
+ }
88
+ }
@@ -1,5 +1,6 @@
1
1
  use crate::auditwheel::AuditWheelMode;
2
2
  use crate::build_options::CargoOptions;
3
+ use crate::compression::CompressionOptions;
3
4
  use crate::target::detect_arch_from_python;
4
5
  use crate::BuildContext;
5
6
  use crate::BuildOptions;
@@ -229,6 +230,10 @@ pub struct DevelopOptions {
229
230
  /// Use `uv` to install packages instead of `pip`
230
231
  #[arg(long)]
231
232
  pub uv: bool,
233
+
234
+ /// Wheel compression options
235
+ #[command(flatten)]
236
+ pub compression: CompressionOptions,
232
237
  }
233
238
 
234
239
  #[instrument(skip_all)]
@@ -387,7 +392,10 @@ pub fn develop(develop_options: DevelopOptions, venv_dir: &Path) -> Result<()> {
387
392
  pip_path,
388
393
  cargo_options,
389
394
  uv,
395
+ compression,
390
396
  } = develop_options;
397
+ compression.validate();
398
+
391
399
  let mut target_triple = cargo_options.target.clone();
392
400
  let target = Target::from_target_triple(cargo_options.target.as_ref())?;
393
401
  let python = target.get_venv_python(venv_dir);
@@ -416,7 +424,7 @@ pub fn develop(develop_options: DevelopOptions, venv_dir: &Path) -> Result<()> {
416
424
  target: target_triple,
417
425
  ..cargo_options
418
426
  },
419
- compression_level: 6,
427
+ compression,
420
428
  };
421
429
 
422
430
  let build_context = build_options
@@ -23,11 +23,12 @@
23
23
 
24
24
  #![deny(missing_docs)]
25
25
 
26
- pub use crate::bridge::{BridgeModel, PyO3, PyO3Crate};
26
+ pub use crate::bridge::{Abi3Version, BridgeModel, PyO3, PyO3Crate};
27
27
  pub use crate::build_context::{BuildContext, BuiltWheelMetadata};
28
28
  pub use crate::build_options::{BuildOptions, CargoOptions, TargetTriple};
29
29
  pub use crate::cargo_toml::CargoToml;
30
30
  pub use crate::compile::{compile, BuildArtifact};
31
+ pub use crate::compression::{CompressionMethod, CompressionOptions};
31
32
  pub use crate::develop::{develop, DevelopOptions};
32
33
  #[cfg(feature = "schemars")]
33
34
  pub use crate::generate_json_schema::{generate_json_schema, GenerateJsonSchemaOptions, Mode};
@@ -53,6 +54,7 @@ mod cargo_toml;
53
54
  /// Generate CI configuration
54
55
  pub mod ci;
55
56
  mod compile;
57
+ mod compression;
56
58
  mod cross_compile;
57
59
  mod develop;
58
60
  mod generate_json_schema;
@@ -13,8 +13,8 @@ use clap::{Parser, Subcommand};
13
13
  #[cfg(feature = "scaffolding")]
14
14
  use maturin::{ci::GenerateCI, init_project, new_project, GenerateProjectOptions};
15
15
  use maturin::{
16
- develop, write_dist_info, BridgeModel, BuildOptions, CargoOptions, DevelopOptions, PathWriter,
17
- PlatformTag, PythonInterpreter, Target, TargetTriple,
16
+ develop, write_dist_info, Abi3Version, BridgeModel, BuildOptions, CargoOptions, DevelopOptions,
17
+ PathWriter, PlatformTag, PythonInterpreter, Target, TargetTriple,
18
18
  };
19
19
  #[cfg(feature = "schemars")]
20
20
  use maturin::{generate_json_schema, GenerateJsonSchemaOptions};
@@ -284,10 +284,19 @@ fn pep517(subcommand: Pep517Command) -> Result<()> {
284
284
  let tags = match context.bridge() {
285
285
  BridgeModel::PyO3(bindings) | BridgeModel::Bin(Some(bindings)) => {
286
286
  match bindings.abi3 {
287
- Some((major, minor)) => {
287
+ Some(Abi3Version::Version(major, minor)) => {
288
288
  let platform = context.get_platform_tag(&[PlatformTag::Linux])?;
289
289
  vec![format!("cp{major}{minor}-abi3-{platform}")]
290
290
  }
291
+ Some(Abi3Version::CurrentPython) => {
292
+ let interp = &context.interpreter[0];
293
+ let platform = context.get_platform_tag(&[PlatformTag::Linux])?;
294
+ vec![format!(
295
+ "cp{major}{minor}-abi3-{platform}",
296
+ major = interp.major,
297
+ minor = interp.minor
298
+ )]
299
+ }
291
300
  None => {
292
301
  vec![context.interpreter[0].get_tag(&context, &[PlatformTag::Linux])?]
293
302
  }
@@ -416,7 +416,7 @@ impl Metadata24 {
416
416
  let metadata = Metadata24 {
417
417
  // name, version and metadata_version are added through metadata24::new()
418
418
  // Mapped from cargo metadata
419
- summary: package.description.clone(),
419
+ summary: package.description.as_ref().map(|d| d.trim().into()),
420
420
  description,
421
421
  description_content_type,
422
422
  keywords: if package.keywords.is_empty() {
@@ -688,7 +688,9 @@ mod test {
688
688
  authors = ["konstin <konstin@mailbox.org>"]
689
689
  name = "info-project"
690
690
  version = "0.1.0"
691
- description = "A test project"
691
+ description = """
692
+ A test project
693
+ """
692
694
  homepage = "https://example.org"
693
695
  readme = "REPLACE_README_PATH"
694
696
  keywords = ["ffi", "test"]
@@ -1,4 +1,5 @@
1
1
  //! The wheel format is (mostly) specified in PEP 427
2
+ use crate::compression::{CompressionMethod, CompressionOptions};
2
3
  use crate::project_layout::ProjectLayout;
3
4
  use crate::target::Os;
4
5
  use crate::{
@@ -239,7 +240,27 @@ pub struct WheelWriter {
239
240
  wheel_path: PathBuf,
240
241
  file_tracker: FileTracker,
241
242
  excludes: Override,
242
- compression_level: u16,
243
+ compression: CompressionOptions,
244
+ }
245
+ impl CompressionOptions {
246
+ fn get_file_options(&self) -> zip::write::FileOptions<()> {
247
+ let method = if cfg!(feature = "faster-tests") {
248
+ // Unlike users which can use the develop subcommand, the tests have to go through
249
+ // packing a zip which pip than has to unpack. This makes this 2-3 times faster
250
+ CompressionMethod::Stored
251
+ } else {
252
+ self.compression_method
253
+ };
254
+
255
+ let mut options =
256
+ zip::write::SimpleFileOptions::default().compression_method(method.into());
257
+ // `zip` also has default compression levels, which should match our own, but we pass them
258
+ // explicitly to ensure consistency.
259
+ options = options.compression_level(Some(
260
+ self.compression_level.unwrap_or(method.default_level()),
261
+ ));
262
+ options
263
+ }
243
264
  }
244
265
 
245
266
  impl ModuleWriter for WheelWriter {
@@ -267,20 +288,11 @@ impl ModuleWriter for WheelWriter {
267
288
  // The zip standard mandates using unix style paths
268
289
  let target = target.to_str().unwrap().replace('\\', "/");
269
290
 
270
- // Unlike users which can use the develop subcommand, the tests have to go through
271
- // packing a zip which pip than has to unpack. This makes this 2-3 times faster
272
- let compression_method = if cfg!(feature = "faster-tests") || self.compression_level == 0 {
273
- zip::CompressionMethod::Stored
274
- } else {
275
- zip::CompressionMethod::Deflated
276
- };
291
+ let mut options = self
292
+ .compression
293
+ .get_file_options()
294
+ .unix_permissions(permissions);
277
295
 
278
- let mut options = zip::write::SimpleFileOptions::default()
279
- .unix_permissions(permissions)
280
- .compression_method(compression_method);
281
- if self.compression_level != 0 {
282
- options = options.compression_level(Some(self.compression_level as i64));
283
- }
284
296
  let mtime = self.mtime().ok();
285
297
  if let Some(mtime) = mtime {
286
298
  options = options.last_modified_time(mtime);
@@ -306,7 +318,7 @@ impl WheelWriter {
306
318
  metadata24: &Metadata24,
307
319
  tags: &[String],
308
320
  excludes: Override,
309
- compression_level: u16,
321
+ compression: CompressionOptions,
310
322
  ) -> Result<WheelWriter> {
311
323
  let wheel_path = wheel_dir.join(format!(
312
324
  "{}-{}-{}.whl",
@@ -324,7 +336,7 @@ impl WheelWriter {
324
336
  wheel_path,
325
337
  file_tracker: FileTracker::default(),
326
338
  excludes,
327
- compression_level,
339
+ compression,
328
340
  };
329
341
 
330
342
  write_dist_info(&mut builder, metadata24, tags)?;
@@ -383,17 +395,7 @@ impl WheelWriter {
383
395
 
384
396
  /// Creates the record file and finishes the zip
385
397
  pub fn finish(mut self) -> Result<PathBuf, io::Error> {
386
- let compression_method = if cfg!(feature = "faster-tests") || self.compression_level == 0 {
387
- zip::CompressionMethod::Stored
388
- } else {
389
- zip::CompressionMethod::Deflated
390
- };
391
-
392
- let mut options =
393
- zip::write::SimpleFileOptions::default().compression_method(compression_method);
394
- if self.compression_level != 0 {
395
- options = options.compression_level(Some(self.compression_level as i64));
396
- }
398
+ let mut options = self.compression.get_file_options();
397
399
  let mtime = self.mtime().ok();
398
400
  if let Some(mtime) = mtime {
399
401
  options = options.last_modified_time(mtime);
@@ -427,7 +427,7 @@ fn fun_with_abiflags(
427
427
  if message.interpreter == "pypy" || message.interpreter == "graalvm" {
428
428
  // pypy and graalpy do not specify abi flags
429
429
  Ok("".to_string())
430
- } else if message.system == "windows" {
430
+ } else if message.system == "windows" && message.minor < 14 {
431
431
  if matches!(message.abiflags.as_deref(), Some("") | None) {
432
432
  // windows has a few annoying cases, but its abiflags in sysconfig always empty
433
433
  // python <= 3.7 has "m"
@@ -443,7 +443,7 @@ fn fun_with_abiflags(
443
443
  Ok("".to_string())
444
444
  }
445
445
  } else {
446
- bail!("A python 3 interpreter on Windows does not define abiflags in its sysconfig ಠ_ಠ")
446
+ bail!("A python 3 interpreter on Windows does not define abiflags in its sysconfig before Python 3.14 ಠ_ಠ")
447
447
  }
448
448
  } else if let Some(ref abiflags) = message.abiflags {
449
449
  if message.minor >= 8 {
@@ -12,7 +12,7 @@ crate-type = ["cdylib"]
12
12
 
13
13
  [dependencies]
14
14
  {% if bindings == "pyo3" -%}
15
- pyo3 = "0.24.0"
15
+ pyo3 = "0.25.0"
16
16
  {% elif bindings == "uniffi" -%}
17
17
  uniffi = "0.28.0"
18
18
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes