diff --git a/Cargo.lock b/Cargo.lock index 2a1e4f329..70b2ce50c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -93,12 +93,6 @@ version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" -[[package]] -name = "arc-swap" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" - [[package]] name = "arrayref" version = "0.3.9" @@ -658,7 +652,7 @@ version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "syn", @@ -1455,12 +1449,6 @@ version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "heck" version = "0.5.0" @@ -2076,15 +2064,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "memoffset" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] - [[package]] name = "miette" version = "7.2.0" @@ -2217,7 +2196,7 @@ dependencies = [ "bitflags 1.3.2", "cfg-if", "libc", - "memoffset 0.7.1", + "memoffset", "pin-utils", ] @@ -2411,10 +2390,9 @@ checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" [[package]] name = "pep440_rs" -version = "0.6.0" +version = "0.7.0" dependencies = [ "indoc", - "pyo3", "rkyv", "serde", "tracing", @@ -2433,8 +2411,6 @@ dependencies = [ "log", "pep440_rs", "pubgrub", - "pyo3", - "pyo3-log", "regex", "rustc-hash", "schemars", @@ -2717,80 +2693,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "pyo3" -version = "0.21.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e00b96a521718e08e03b1a622f01c8a8deb50719335de3f60b3b3950f069d8" -dependencies = [ - "cfg-if", - "indoc", - "libc", - "memoffset 0.9.1", - "parking_lot 0.12.3", - "portable-atomic", - "pyo3-build-config", - "pyo3-ffi", - "pyo3-macros", - "unindent", -] - -[[package]] -name = "pyo3-build-config" -version = "0.21.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7883df5835fafdad87c0d888b266c8ec0f4c9ca48a5bed6bbb592e8dedee1b50" -dependencies = [ - "once_cell", - "target-lexicon", -] - -[[package]] -name = "pyo3-ffi" -version = "0.21.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01be5843dc60b916ab4dad1dca6d20b9b4e6ddc8e15f50c47fe6d85f1fb97403" -dependencies = [ - "libc", - "pyo3-build-config", -] - -[[package]] -name = "pyo3-log" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af49834b8d2ecd555177e63b273b708dea75150abc6f5341d0a6e1a9623976c" -dependencies = [ - "arc-swap", - "log", - "pyo3", -] - -[[package]] -name = "pyo3-macros" -version = "0.21.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77b34069fc0682e11b31dbd10321cbf94808394c56fd996796ce45217dfac53c" -dependencies = [ - "proc-macro2", - "pyo3-macros-backend", - "quote", - "syn", -] - -[[package]] -name = "pyo3-macros-backend" -version = "0.21.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08260721f32db5e1a5beae69a55553f56b99bd0e1c3e6e0a5e8851a9d0f5a85c" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "pyo3-build-config", - "quote", - "syn", -] - [[package]] name = "pypi-types" version = "0.0.1" @@ -4167,7 +4069,6 @@ version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -4368,12 +4269,6 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" -[[package]] -name = "unindent" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce" - [[package]] name = "unscanny" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index d2a1e54b0..6988e37b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -123,8 +123,6 @@ petgraph = { version = "0.6.5" } platform-info = { version = "2.0.3" } proc-macro2 = { version = "1.0.86" } pubgrub = { git = "https://github.com/astral-sh/pubgrub", rev = "388685a8711092971930986644cfed152d1a1f6c" } -pyo3 = { version = "0.21.2" } -pyo3-log = { version = "0.10.0" } quote = { version = "1.0.37" } rayon = { version = "1.10.0" } reflink-copy = { version = "0.1.19" } diff --git a/crates/pep440-rs/CHANGELOG.md b/crates/pep440-rs/CHANGELOG.md index 40aaf9c5f..9831df815 100644 --- a/crates/pep440-rs/CHANGELOG.md +++ b/crates/pep440-rs/CHANGELOG.md @@ -1,3 +1,49 @@ +## 0.7 + +* Remove pyo3 bindings + +## 0.6.6 + +* Add `VersionSpecifiers::empty()`, which is present in the uv version of this crate but missing + here. + +## 0.6.2 - 0.6.5 + +* CI fixes + +## 0.6.1 + +* Update pyo3 to 0.22 + +## 0.6 + +* Update pyo3 to 0.21 and a minimum of python 3.8 + +## 0.5 + +The crate has been completely rewritten by [burntsushi](https://github.com/BurntSushi/). + +* Faster version parsing. +* Faster version comparisons. +* `Version` field accessors are now methods. +* `Version` is an [`Arc`](https://doc.rust-lang.org/std/sync/struct.Arc.html) of its internal + representation, so cloning is cheap. +* The internal representation of a version is split into a full representation and an optimized + small variant that can handle 75% of the versions on pypi. +* Parse errors are now opaque. +* [rkyv](https://github.com/rkyv/rkyv) support. + +## 0.4 + +* segments are now `u64` instead of `usize`. This ensures consistency between platforms and `u64` + are required when timestamps are used as patch versions (e.g., `20230628214621`, the ISO 8601 " + basic format") +* Faster version comparison +* Added `VersionSpecifier::equals_version` constructor for `==` +* Added `VersionSpecifier::any_prerelease`: Whether the version marker includes a prerelease +* Updated to pyo3 0.20 +* once_cell instead of lazy_static + ## 0.3.12 - Implement `FromPyObject` for `Version` diff --git a/crates/pep440-rs/Cargo.lock b/crates/pep440-rs/Cargo.lock deleted file mode 100644 index 7427c776d..000000000 --- a/crates/pep440-rs/Cargo.lock +++ /dev/null @@ -1,410 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "aho-corasick" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" -dependencies = [ - "memchr", -] - -[[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 = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "indoc" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" - -[[package]] -name = "indoc" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8" - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.148" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" - -[[package]] -name = "lock_api" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "memchr" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" - -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - -[[package]] -name = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - -[[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.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets", -] - -[[package]] -name = "pep440_rs" -version = "0.3.12" -dependencies = [ - "indoc 2.0.4", - "lazy_static", - "pyo3", - "regex", - "serde", - "tracing", - "unicode-width", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" - -[[package]] -name = "proc-macro2" -version = "1.0.67" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "pyo3" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e681a6cfdc4adcc93b4d3cf993749a4552018ee0a9b65fc0ccfad74352c72a38" -dependencies = [ - "cfg-if", - "indoc 1.0.9", - "libc", - "memoffset", - "parking_lot", - "pyo3-build-config", - "pyo3-ffi", - "pyo3-macros", - "unindent", -] - -[[package]] -name = "pyo3-build-config" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076c73d0bc438f7a4ef6fdd0c3bb4732149136abd952b110ac93e4edb13a6ba5" -dependencies = [ - "once_cell", - "target-lexicon", -] - -[[package]] -name = "pyo3-ffi" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e53cee42e77ebe256066ba8aa77eff722b3bb91f3419177cf4cd0f304d3284d9" -dependencies = [ - "libc", - "pyo3-build-config", -] - -[[package]] -name = "pyo3-macros" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfeb4c99597e136528c6dd7d5e3de5434d1ceaf487436a3f03b2d56b6fc9efd1" -dependencies = [ - "proc-macro2", - "pyo3-macros-backend", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "pyo3-macros-backend" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "947dc12175c254889edc0c02e399476c2f652b4b9ebd123aa655c224de259536" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "quote" -version = "1.0.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags", -] - -[[package]] -name = "regex" -version = "1.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "serde" -version = "1.0.188" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.188" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.37", -] - -[[package]] -name = "smallvec" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "target-lexicon" -version = "0.12.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a" - -[[package]] -name = "tracing" -version = "0.1.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" -dependencies = [ - "cfg-if", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.37", -] - -[[package]] -name = "tracing-core" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" -dependencies = [ - "once_cell", -] - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-width" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" - -[[package]] -name = "unindent" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1766d682d402817b5ac4490b3c3002d91dfa0d22812f341609f97b08757359c" - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -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.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/crates/pep440-rs/Cargo.toml b/crates/pep440-rs/Cargo.toml index c7872df23..18a9895df 100644 --- a/crates/pep440-rs/Cargo.toml +++ b/crates/pep440-rs/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pep440_rs" -version = "0.6.0" +version = "0.7.0" description = "A library for python version numbers and specifiers, implementing PEP 440" license = "Apache-2.0 OR BSD-2-Clause" include = ["/src", "Changelog.md", "License-Apache", "License-BSD", "Readme.md", "pyproject.toml"] @@ -19,7 +19,6 @@ crate-type = ["rlib", "cdylib"] workspace = true [dependencies] -pyo3 = { workspace = true, optional = true, features = ["extension-module", "abi3-py37"] } serde = { workspace = true, features = ["derive"] } rkyv = { workspace = true } tracing = { workspace = true, optional = true } diff --git a/crates/pep440-rs/Readme.md b/crates/pep440-rs/Readme.md index 477f923e0..304dc67cd 100644 --- a/crates/pep440-rs/Readme.md +++ b/crates/pep440-rs/Readme.md @@ -22,21 +22,6 @@ let version_specifiers = parse_version_specifiers(">=1.16, <2.0").unwrap(); assert!(version_specifiers.contains(&version)); ``` -In python (`pip install pep440_rs`): - -```python -from pep440_rs import Version, VersionSpecifier - -assert Version("1.1a1").any_prerelease() -assert Version("1.1.dev2").any_prerelease() -assert not Version("1.1").any_prerelease() -assert VersionSpecifier(">=1.0").contains(Version("1.1a1")) -assert not VersionSpecifier(">=1.1").contains(Version("1.1a1")) -# Note that python comparisons are the version ordering, not the version specifiers operators -assert Version("1.1") >= Version("1.1a1") -assert Version("2.0") in VersionSpecifier("==2") -``` - PEP 440 has a lot of unintuitive features, including: - An epoch that you can prefix the version which, e.g. `1!1.2.3`. Lower epoch always means lower diff --git a/crates/pep440-rs/python/Readme.md b/crates/pep440-rs/python/Readme.md deleted file mode 100644 index 1c6224c6e..000000000 --- a/crates/pep440-rs/python/Readme.md +++ /dev/null @@ -1,44 +0,0 @@ -# PEP440 in rust - -A library for python version numbers and specifiers, implementing -[PEP 440](https://peps.python.org/pep-0440) - -```shell -pip install pep440_rs -``` - -```python -from pep440_rs import Version, VersionSpecifier - -assert Version("1.1a1").any_prerelease() -assert Version("1.1.dev2").any_prerelease() -assert not Version("1.1").any_prerelease() -assert VersionSpecifier(">=1.0").contains(Version("1.1a1")) -assert not VersionSpecifier(">=1.1").contains(Version("1.1a1")) -assert Version("2.0") in VersionSpecifier("==2") -``` - -Unlike [pypa/packaging](https://github.com/pypa/packaging), this library always matches prereleases. -To only match final releases, filter with `.any_prerelease()` beforehand. - -PEP 440 has a lot of unintuitive features, including: - -- An epoch that you can prefix the version which, e.g. `1!1.2.3`. Lower epoch always means lower - version (`1.0 <=2!0.1`) - -* post versions, which can be attached to both stable releases and pre-releases -* dev versions, which can be attached to both table releases and pre-releases. When attached to a - pre-release the dev version is ordered just below the normal pre-release, however when attached to - a stable version, the dev version is sorted before a pre-releases -* pre-release handling is a mess: "Pre-releases of any kind, including developmental releases, are - implicitly excluded from all version specifiers, unless they are already present on the system, - explicitly requested by the user, or if the only available version that satisfies the version - specifier is a pre-release.". This means that we can't say whether a specifier matches without - also looking at the environment -* pre-release vs. pre-release incl. dev is fuzzy -* local versions on top of all the others, which are added with a + and have implicitly typed string - and number segments -* no semver-caret (`^`), but a pseudo-semver tilde (`~=`) -* ordering contradicts matching: We have e.g. `1.0+local > 1.0` when sorting, but `==1.0` matches - `1.0+local`. While the ordering of versions itself is a total order the version matching needs to - catch all sorts of special cases diff --git a/crates/pep440-rs/python/pep440_rs/__init__.py b/crates/pep440-rs/python/pep440_rs/__init__.py deleted file mode 100644 index da3c87604..000000000 --- a/crates/pep440-rs/python/pep440_rs/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -""" -A PEP440 reimplementation in rust - -```python -from pep440_rs import Version, VersionSpecifier - - -assert Version("1.1a1").any_prerelease() -assert Version("1.1.dev2").any_prerelease() -assert not Version("1.1").any_prerelease() -assert VersionSpecifier(">=1.0").contains(Version("1.1a1")) -assert not VersionSpecifier(">=1.1").contains(Version("1.1a1")) -assert Version("2.0") in VersionSpecifier("==2") -``` - -""" - -from ._pep440_rs import * - -__doc__ = _pep440_rs.__doc__ -if hasattr(_pep440_rs, "__all__"): - __all__ = _pep440_rs.__all__ diff --git a/crates/pep440-rs/python/pep440_rs/__init__.pyi b/crates/pep440-rs/python/pep440_rs/__init__.pyi deleted file mode 100644 index 095c65bd1..000000000 --- a/crates/pep440-rs/python/pep440_rs/__init__.pyi +++ /dev/null @@ -1,38 +0,0 @@ -# Generated by `stubgen -p pep440_rs` -from typing import Any, ClassVar - -class Version: - dev: Any - epoch: Any - post: Any - pre: Any - release: Any - major: Any - minor: Any - micro: Any - - @classmethod - def __init__(cls, *args, **kwargs) -> None: ... - def any_prerelease(self, *args, **kwargs) -> Any: ... - def parse_star(self, *args, **kwargs) -> Any: ... - def __eq__(self, other) -> Any: ... - def __ge__(self, other) -> Any: ... - def __gt__(self, other) -> Any: ... - def __hash__(self) -> Any: ... - def __le__(self, other) -> Any: ... - def __lt__(self, other) -> Any: ... - def __ne__(self, other) -> Any: ... - -class VersionSpecifier: - __hash__: ClassVar[None] = ... - - @classmethod - def __init__(cls, *args, **kwargs) -> None: ... - def contains(self, *args, **kwargs) -> Any: ... - def __contains__(self, other) -> Any: ... - def __eq__(self, other) -> Any: ... - def __ge__(self, other) -> Any: ... - def __gt__(self, other) -> Any: ... - def __le__(self, other) -> Any: ... - def __lt__(self, other) -> Any: ... - def __ne__(self, other) -> Any: ... diff --git a/crates/pep440-rs/src/lib.rs b/crates/pep440-rs/src/lib.rs index 8af854047..650fb1843 100644 --- a/crates/pep440-rs/src/lib.rs +++ b/crates/pep440-rs/src/lib.rs @@ -32,10 +32,8 @@ //! * ordering contradicts matching: We have e.g. `1.0+local > 1.0` when sorting, //! but `==1.0` matches `1.0+local`. While the ordering of versions itself is a total order //! the version matching needs to catch all sorts of special cases -#![deny(missing_docs)] +#![warn(missing_docs)] -#[cfg(feature = "pyo3")] -pub use version::PyVersion; pub use { version::{ LocalSegment, Operator, OperatorParseError, Prerelease, PrereleaseKind, Version, @@ -49,18 +47,3 @@ pub use { mod version; mod version_specifier; - -/// Python bindings shipped as `pep440_rs` -#[cfg(feature = "pyo3")] -#[pyo3::pymodule] -#[pyo3(name = "_pep440_rs")] -pub fn python_module( - _py: pyo3::Python, - module: &pyo3::Bound<'_, pyo3::types::PyModule>, -) -> pyo3::PyResult<()> { - module.add_class::()?; - module.add_class::()?; - module.add_class::()?; - module.add_class::()?; - Ok(()) -} diff --git a/crates/pep440-rs/src/version.rs b/crates/pep440-rs/src/version.rs index f1cf98846..b8f42bdc3 100644 --- a/crates/pep440-rs/src/version.rs +++ b/crates/pep440-rs/src/version.rs @@ -1,8 +1,3 @@ -#[cfg(feature = "pyo3")] -use pyo3::{ - basic::CompareOp, exceptions::PyValueError, pyclass, pymethods, FromPyObject, IntoPy, PyAny, - PyObject, PyResult, Python, -}; use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; use std::sync::LazyLock; use std::{ @@ -28,7 +23,6 @@ use std::{ rkyv::Serialize, )] #[rkyv(derive(Debug, Eq, PartialEq, PartialOrd, Ord))] -#[cfg_attr(feature = "pyo3", pyclass)] pub enum Operator { /// `== 1.2.3` Equal, @@ -178,20 +172,6 @@ impl std::fmt::Display for Operator { } } -#[cfg(feature = "pyo3")] -#[pymethods] -impl Operator { - #[allow(clippy::trivially_copy_pass_by_ref)] - fn __str__(&self) -> String { - self.to_string() - } - - #[allow(clippy::trivially_copy_pass_by_ref)] - fn __repr__(&self) -> String { - self.to_string() - } -} - /// An error that occurs when parsing an invalid version specifier operator. #[derive(Clone, Debug, Eq, PartialEq)] pub struct OperatorParseError { @@ -1357,7 +1337,6 @@ impl FromStr for VersionPattern { rkyv::Serialize, )] #[rkyv(derive(Debug, Eq, PartialEq, PartialOrd, Ord))] -#[cfg_attr(feature = "pyo3", pyclass)] pub struct Prerelease { /// The kind of pre-release. pub kind: PrereleaseKind, @@ -1382,7 +1361,6 @@ pub struct Prerelease { rkyv::Serialize, )] #[rkyv(derive(Debug, Eq, PartialEq, PartialOrd, Ord))] -#[cfg_attr(feature = "pyo3", pyclass)] pub enum PrereleaseKind { /// alpha pre-release Alpha, @@ -2280,132 +2258,6 @@ impl From for VersionPatternParseError { } } -/// Workaround for -#[cfg(feature = "pyo3")] -#[derive(Clone, Debug)] -#[pyclass(name = "Version")] -pub struct PyVersion(pub Version); - -#[cfg(feature = "pyo3")] -#[pymethods] -impl PyVersion { - /// The [versioning epoch](https://peps.python.org/pep-0440/#version-epochs). Normally just 0, - /// but you can increment it if you switched the versioning scheme. - #[getter] - pub fn epoch(&self) -> u64 { - self.0.epoch() - } - /// The normal number part of the version - /// (["final release"](https://peps.python.org/pep-0440/#final-releases)), - /// such a `1.2.3` in `4!1.2.3-a8.post9.dev1` - /// - /// Note that we drop the * placeholder by moving it to `Operator` - #[getter] - pub fn release(&self) -> Vec { - self.0.release().to_vec() - } - /// The [pre-release](https://peps.python.org/pep-0440/#pre-releases), i.e. alpha, beta or rc - /// plus a number - /// - /// Note that whether this is Some influences the version - /// range matching since normally we exclude all pre-release versions - #[getter] - pub fn pre(&self) -> Option { - self.0.pre() - } - /// The [Post release version](https://peps.python.org/pep-0440/#post-releases), - /// higher post version are preferred over lower post or none-post versions - #[getter] - pub fn post(&self) -> Option { - self.0.post() - } - /// The [developmental release](https://peps.python.org/pep-0440/#developmental-releases), - /// if any - #[getter] - pub fn dev(&self) -> Option { - self.0.dev() - } - /// The first item of release or 0 if unavailable. - #[getter] - #[allow(clippy::get_first)] - pub fn major(&self) -> u64 { - self.0.release().get(0).copied().unwrap_or_default() - } - /// The second item of release or 0 if unavailable. - #[getter] - pub fn minor(&self) -> u64 { - self.0.release().get(1).copied().unwrap_or_default() - } - /// The third item of release or 0 if unavailable. - #[getter] - pub fn micro(&self) -> u64 { - self.0.release().get(2).copied().unwrap_or_default() - } - - /// Parses a PEP 440 version string - #[cfg(feature = "pyo3")] - #[new] - pub fn parse(version: &str) -> PyResult { - Ok(Self( - Version::from_str(version).map_err(|e| PyValueError::new_err(e.to_string()))?, - )) - } - - // Maps the error type - /// Parse a PEP 440 version optionally ending with `.*` - #[cfg(feature = "pyo3")] - #[staticmethod] - pub fn parse_star(version_specifier: &str) -> PyResult<(Self, bool)> { - version_specifier - .parse::() - .map_err(|e| PyValueError::new_err(e.to_string())) - .map(|VersionPattern { version, wildcard }| (Self(version), wildcard)) - } - - /// Returns the normalized representation - #[cfg(feature = "pyo3")] - pub fn __str__(&self) -> String { - self.0.to_string() - } - - /// Returns the normalized representation - #[cfg(feature = "pyo3")] - pub fn __repr__(&self) -> String { - format!(r#""#, self.0) - } - - /// Returns the normalized representation - #[cfg(feature = "pyo3")] - pub fn __hash__(&self) -> u64 { - let mut hasher = std::collections::hash_map::DefaultHasher::new(); - self.0.hash(&mut hasher); - hasher.finish() - } - - #[cfg(feature = "pyo3")] - fn __richcmp__(&self, other: &Self, op: CompareOp) -> bool { - op.matches(self.0.cmp(&other.0)) - } - - fn any_prerelease(&self) -> bool { - self.0.any_prerelease() - } -} - -#[cfg(feature = "pyo3")] -impl IntoPy for Version { - fn into_py(self, py: Python<'_>) -> PyObject { - PyVersion(self).into_py(py) - } -} - -#[cfg(feature = "pyo3")] -impl<'source> FromPyObject<'source> for Version { - fn extract(ob: &'source PyAny) -> PyResult { - Ok(ob.extract::()?.0) - } -} - /// Compare the release parts of two versions, e.g. `4.3.1` > `4.2`, `1.1.0` == /// `1.1` and `1.16` < `1.19` pub(crate) fn compare_release(this: &[u64], other: &[u64]) -> Ordering { @@ -2549,9 +2401,6 @@ pub static MIN_VERSION: LazyLock = mod tests { use std::str::FromStr; - #[cfg(feature = "pyo3")] - use pyo3::pyfunction; - use crate::VersionSpecifier; use super::*; @@ -3863,12 +3712,6 @@ mod tests { ); } - #[cfg(feature = "pyo3")] - #[pyfunction] - fn _convert_in_and_out(version: Version) -> Version { - version - } - /// Wraps a `Version` and provides a more "bloated" debug but standard /// representation. /// diff --git a/crates/pep440-rs/src/version_specifier.rs b/crates/pep440-rs/src/version_specifier.rs index b043e8df0..fa8572f82 100644 --- a/crates/pep440-rs/src/version_specifier.rs +++ b/crates/pep440-rs/src/version_specifier.rs @@ -1,21 +1,9 @@ -#[cfg(feature = "pyo3")] -use std::hash::{Hash, Hasher}; - use std::cmp::Ordering; use std::ops::Bound; use std::str::FromStr; -#[cfg(feature = "pyo3")] -use pyo3::{ - exceptions::{PyIndexError, PyNotImplementedError, PyValueError}, - pyclass, - pyclass::CompareOp, - pymethods, Py, PyRef, PyRefMut, PyResult, -}; use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; -#[cfg(feature = "pyo3")] -use crate::version::PyVersion; use crate::{ version, Operator, OperatorParseError, Version, VersionPattern, VersionPatternParseError, }; @@ -48,7 +36,6 @@ use crate::{ rkyv::Serialize, )] #[rkyv(derive(Debug))] -#[cfg_attr(feature = "pyo3", pyclass(sequence))] pub struct VersionSpecifiers(Vec); impl std::ops::Deref for VersionSpecifiers { @@ -125,74 +112,6 @@ impl Default for VersionSpecifiers { } } -/// https://pyo3.rs/v0.18.2/class/protocols.html#iterable-objects -#[cfg(feature = "pyo3")] -#[pyclass] -struct VersionSpecifiersIter { - inner: std::vec::IntoIter, -} - -#[cfg(feature = "pyo3")] -#[pymethods] -impl VersionSpecifiersIter { - fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> { - slf - } - - fn __next__(mut slf: PyRefMut<'_, Self>) -> Option { - slf.inner.next() - } -} - -#[cfg(feature = "pyo3")] -#[pymethods] -impl VersionSpecifiers { - /// PEP 440 parsing - #[new] - pub fn __new__(version_specifiers: &str) -> PyResult { - Self::from_str(version_specifiers).map_err(|err| PyValueError::new_err(err.to_string())) - } - - /// PEP 440 serialization - pub fn __str__(&self) -> String { - self.to_string() - } - - /// PEP 440 serialization - pub fn __repr__(&self) -> String { - self.to_string() - } - - /// Get the nth VersionSpecifier - pub fn __getitem__(&self, idx: usize) -> PyResult { - self.0.get(idx).cloned().ok_or_else(|| { - PyIndexError::new_err(format!( - "list index {} our of range for len {}", - idx, - self.0.len() - )) - }) - } - - #[allow(clippy::needless_pass_by_value)] - fn __iter__(slf: PyRef<'_, Self>) -> PyResult> { - let iter = VersionSpecifiersIter { - inner: slf.0.clone().into_iter(), - }; - Py::new(slf.py(), iter) - } - - /// Get the number of VersionSpecifier - pub fn __len__(&self) -> usize { - self.0.len() - } - - /// Whether the version matches all the specifiers - pub fn __contains__(&self, version: &PyVersion) -> bool { - self.contains(&version.0) - } -} - impl<'de> Deserialize<'de> for VersionSpecifiers { fn deserialize(deserializer: D) -> Result where @@ -293,7 +212,6 @@ impl std::error::Error for VersionSpecifiersParseError {} rkyv::Serialize, )] #[rkyv(derive(Debug))] -#[cfg_attr(feature = "pyo3", pyclass(get_all))] pub struct VersionSpecifier { /// ~=|==|!=|<=|>=|<|>|===, plus whether the version ended with a star pub(crate) operator: Operator, @@ -301,55 +219,6 @@ pub struct VersionSpecifier { pub(crate) version: Version, } -#[cfg(feature = "pyo3")] -#[pymethods] -impl VersionSpecifier { - // Since we don't bring FromStr to python - /// Parse a PEP 440 version - #[new] - pub fn parse(version_specifier: &str) -> PyResult { - Self::from_str(version_specifier).map_err(|e| PyValueError::new_err(e.to_string())) - } - - /// See [VersionSpecifier::contains] - #[pyo3(name = "contains")] - pub fn py_contains(&self, version: &PyVersion) -> bool { - self.contains(&version.0) - } - - /// Whether the version fulfills the specifier - pub fn __contains__(&self, version: &PyVersion) -> bool { - self.contains(&version.0) - } - - /// Returns the normalized representation - pub fn __str__(&self) -> String { - self.to_string() - } - - /// Returns the normalized representation - pub fn __repr__(&self) -> String { - format!(r#""#) - } - - fn __richcmp__(&self, other: &Self, op: CompareOp) -> PyResult { - if matches!(op, CompareOp::Eq) { - Ok(self == other) - } else { - Err(PyNotImplementedError::new_err( - "Can only compare VersionSpecifier by equality", - )) - } - } - - /// Returns the normalized representation - pub fn __hash__(&self) -> u64 { - let mut hasher = std::collections::hash_map::DefaultHasher::new(); - self.hash(&mut hasher); - hasher.finish() - } -} - /// impl<'de> Deserialize<'de> for VersionSpecifier { fn deserialize(deserializer: D) -> Result diff --git a/crates/pep440-rs/test/test_python.py b/crates/pep440-rs/test/test_python.py deleted file mode 100644 index d9b9d6556..000000000 --- a/crates/pep440-rs/test/test_python.py +++ /dev/null @@ -1,49 +0,0 @@ -""" -This is implementation has some very rudimentary python bindings -""" - -from pep440_rs import Operator, Version, VersionSpecifier, VersionSpecifiers - - -def test_pep440(): - assert Version("1.1a1").any_prerelease() - assert Version("1.1.dev2").any_prerelease() - assert not Version("1.1").any_prerelease() - assert VersionSpecifier(">=1.0").contains(Version("1.1a1")) - assert not VersionSpecifier(">=1.1").contains(Version("1.1a1")) - assert Version("1.1") >= Version("1.1a1") - assert Version("2.0") in VersionSpecifier("==2") - assert Version("2.1").major == 2 - assert Version("2.1").minor == 1 - assert Version("2.1").micro == 0 - - -def test_version_specifier(): - assert VersionSpecifier(">=1.1").version == Version("1.1") - assert VersionSpecifier(">=1.1").operator == Operator.GreaterThanEqual - assert str(VersionSpecifier(">=1.1").operator) == ">=" - # Note: This removes the star - assert VersionSpecifier("==1.1.*").version == Version("1.1") - assert str(VersionSpecifier("==1.1.*").operator) == "==" - assert { - VersionSpecifier("==1.1.*"), - VersionSpecifier("==1.1"), - VersionSpecifier("==1.1"), - } == {VersionSpecifier("==1.1.*"), VersionSpecifier("==1.1")} - - -def test_version_specifiers(): - assert str(VersionSpecifiers(">=1.1, <2.0")) == ">=1.1, <2.0" - assert list(VersionSpecifiers(">=1.1, <2.0")) == [ - VersionSpecifier(">=1.1"), - VersionSpecifier("<2.0"), - ] - - -def test_normalization(): - assert str(Version("1.19-alpha.1")) == "1.19a1" - assert str(VersionSpecifier(" >=1.19-alpha.1 ")) == ">=1.19a1" - assert repr(Version("1.19-alpha.1")) == '' - assert ( - repr(VersionSpecifier(" >=1.19-alpha.1 ")) == '=1.19a1")>' - ) diff --git a/crates/pep508-rs/Cargo.lock b/crates/pep508-rs/Cargo.lock deleted file mode 100644 index ff39cd9eb..000000000 --- a/crates/pep508-rs/Cargo.lock +++ /dev/null @@ -1,655 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "aho-corasick" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" -dependencies = [ - "memchr", -] - -[[package]] -name = "anyhow" -version = "1.0.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" - -[[package]] -name = "arc-swap" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" - -[[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 = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "form_urlencoded" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "hashbrown" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" - -[[package]] -name = "idna" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "indexmap" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad227c3af19d4914570ad36d30409928b75967c298feb9ea1969db3a610bb14e" -dependencies = [ - "equivalent", - "hashbrown", -] - -[[package]] -name = "indoc" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" - -[[package]] -name = "indoc" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8" - -[[package]] -name = "itoa" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.148" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" - -[[package]] -name = "lock_api" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" - -[[package]] -name = "memchr" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" - -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - -[[package]] -name = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - -[[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.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets", -] - -[[package]] -name = "pep440_rs" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05bf2c44c4cd12f03b2c3ca095f3aa21f44e43c16021c332e511884719705be" -dependencies = [ - "lazy_static", - "pyo3", - "regex", - "serde", - "unicode-width", -] - -[[package]] -name = "pep508_rs" -version = "0.2.3" -dependencies = [ - "anyhow", - "indoc 2.0.4", - "log", - "once_cell", - "pep440_rs", - "pyo3", - "pyo3-log", - "regex", - "serde", - "serde_json", - "testing_logger", - "thiserror", - "toml", - "tracing", - "unicode-width", - "url", -] - -[[package]] -name = "percent-encoding" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" - -[[package]] -name = "pin-project-lite" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" - -[[package]] -name = "proc-macro2" -version = "1.0.67" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "pyo3" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e681a6cfdc4adcc93b4d3cf993749a4552018ee0a9b65fc0ccfad74352c72a38" -dependencies = [ - "cfg-if", - "indoc 1.0.9", - "libc", - "memoffset", - "parking_lot", - "pyo3-build-config", - "pyo3-ffi", - "pyo3-macros", - "unindent", -] - -[[package]] -name = "pyo3-build-config" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076c73d0bc438f7a4ef6fdd0c3bb4732149136abd952b110ac93e4edb13a6ba5" -dependencies = [ - "once_cell", - "target-lexicon", -] - -[[package]] -name = "pyo3-ffi" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e53cee42e77ebe256066ba8aa77eff722b3bb91f3419177cf4cd0f304d3284d9" -dependencies = [ - "libc", - "pyo3-build-config", -] - -[[package]] -name = "pyo3-log" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f47b0777feb17f61eea78667d61103758b243a871edc09a7786500a50467b605" -dependencies = [ - "arc-swap", - "log", - "pyo3", -] - -[[package]] -name = "pyo3-macros" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfeb4c99597e136528c6dd7d5e3de5434d1ceaf487436a3f03b2d56b6fc9efd1" -dependencies = [ - "proc-macro2", - "pyo3-macros-backend", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "pyo3-macros-backend" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "947dc12175c254889edc0c02e399476c2f652b4b9ebd123aa655c224de259536" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "quote" -version = "1.0.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags", -] - -[[package]] -name = "regex" -version = "1.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" - -[[package]] -name = "ryu" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "serde" -version = "1.0.188" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.188" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.37", -] - -[[package]] -name = "serde_json" -version = "1.0.107" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_spanned" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" -dependencies = [ - "serde", -] - -[[package]] -name = "smallvec" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "target-lexicon" -version = "0.12.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a" - -[[package]] -name = "testing_logger" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d92b727cb45d33ae956f7f46b966b25f1bc712092aeef9dba5ac798fc89f720" -dependencies = [ - "log", -] - -[[package]] -name = "thiserror" -version = "1.0.49" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.49" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.37", -] - -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "toml" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc1433177506450fe920e46a4f9812d0c211f5dd556da10e731a0a3dfa151f0" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml_datetime" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca676d9ba1a322c1b64eb8045a5ec5c0cfb0c9d08e15e9ff622589ad5221c8fe" -dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "winnow", -] - -[[package]] -name = "tracing" -version = "0.1.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" -dependencies = [ - "cfg-if", - "log", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.37", -] - -[[package]] -name = "tracing-core" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" -dependencies = [ - "once_cell", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-width" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" - -[[package]] -name = "unindent" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1766d682d402817b5ac4490b3c3002d91dfa0d22812f341609f97b08757359c" - -[[package]] -name = "url" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", - "serde", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -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.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "winnow" -version = "0.5.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" -dependencies = [ - "memchr", -] diff --git a/crates/pep508-rs/Cargo.toml b/crates/pep508-rs/Cargo.toml index 3532dec8e..c86419f7b 100644 --- a/crates/pep508-rs/Cargo.toml +++ b/crates/pep508-rs/Cargo.toml @@ -26,8 +26,6 @@ indexmap = { workspace = true } pubgrub = { workspace = true } rustc-hash = { workspace = true } pep440_rs = { workspace = true } -pyo3 = { workspace = true, optional = true, features = ["abi3", "extension-module"] } -pyo3-log = { workspace = true, optional = true } regex = { workspace = true } schemars = { workspace = true, optional = true } serde = { workspace = true, features = ["derive", "rc"] } @@ -48,7 +46,6 @@ serde_json = { version = "1.0.128" } testing_logger = { version = "0.1.1" } [features] -pyo3 = ["dep:pyo3", "pep440_rs/pyo3", "pyo3-log", "tracing", "tracing/log"] tracing = ["dep:tracing", "pep440_rs/tracing"] schemars = ["dep:schemars"] # PEP 508 allows only URLs such as `foo @ https://example.org/foo` or `foo @ file:///home/ferris/foo`, and diff --git a/crates/pep508-rs/Changelog.md b/crates/pep508-rs/Changelog.md new file mode 100644 index 000000000..fc5b84ebb --- /dev/null +++ b/crates/pep508-rs/Changelog.md @@ -0,0 +1,32 @@ +# 0.7.0 + +* Remove pyo3 bindings +* Update rkyv to 0.8 + +# 0.6.1 + +* Update to pyo3 0.22 + +# 0.6.0 + +* Added `origin` to `Requirement` + +# 0.5.0 + +* Update to pyo3 0.21 +* Update to pyo3-log 0.1.0 + +# v0.4.2 + +* CI fixes, mac os builds are temporarily disabled. + +# v0.4.1 + +* CI fixes, mac os builds are temporarily disabled. + +# v0.4.0 + +* Package and extra names are now validated and normalized. +* Updated `pep440_rs` to 0.5.0. +* [rkyv](https://github.com/rkyv/rkyv) support. +* `tracing` is now a separate feature. diff --git a/crates/pep508-rs/Readme.md b/crates/pep508-rs/Readme.md index cffe1d02e..c7106c186 100644 --- a/crates/pep508-rs/Readme.md +++ b/crates/pep508-rs/Readme.md @@ -9,8 +9,6 @@ better known as [PEP 508](https://peps.python.org/pep-0508/). ## Usage -**In Rust** - ```rust use std::str::FromStr; use pep508_rs::Requirement; @@ -21,25 +19,6 @@ assert_eq!(dependency_specification.name, "requests"); assert_eq!(dependency_specification.extras, Some(vec!["security".to_string(), "tests".to_string()])); ``` -**In Python** - -```python -from pep508_rs import Requirement - -requests = Requirement( - 'requests [security,tests] >= 2.8.1, == 2.8.* ; python_version > "3.8"' -) -assert requests.name == "requests" -assert requests.extras == ["security", "tests"] -assert [str(i) for i in requests.version_or_url] == [">= 2.8.1", "== 2.8.*"] -``` - -Python bindings are built with [maturin](https://github.com/PyO3/maturin), but you can also use the -normal `pip install .` - -`Version` and `VersionSpecifier` from [pep440_rs](https://github.com/konstin/pep440-rs) are -reexported to avoid type mismatches. - ## Markers Markers allow you to install dependencies only in specific environments (python version, operating @@ -50,29 +29,3 @@ Unfortunately, the marker grammar has some oversights (e.g. comparisons with lexicographic fallback) leads to confusing outcomes. This implementation tries to carefully validate everything and emit warnings whenever bogus comparisons with unintended semantics are made. - -In python, warnings are by default sent to the normal python logging infrastructure: - -```python -from pep508_rs import Requirement, MarkerEnvironment - -env = MarkerEnvironment.current() -assert not Requirement("numpy; extra == 'science'").evaluate_markers(env, []) -assert Requirement("numpy; extra == 'science'").evaluate_markers(env, ["science"]) -assert not Requirement( - "numpy; extra == 'science' and extra == 'arrays'" -).evaluate_markers(env, ["science"]) -assert Requirement( - "numpy; extra == 'science' or extra == 'arrays'" -).evaluate_markers(env, ["science"]) -``` - -```python -from pep508_rs import Requirement, MarkerEnvironment - -env = MarkerEnvironment.current() -Requirement("numpy; python_version >= '3.9.'").evaluate_markers(env, []) -# This will log: -# "Expected PEP 440 version to compare with python_version, found `3.9.`, " -# "evaluating to false: Version `3.9.` doesn't match PEP 440 rules" -``` diff --git a/crates/pep508-rs/src/lib.rs b/crates/pep508-rs/src/lib.rs index 799cceb38..e0f83f6a3 100644 --- a/crates/pep508-rs/src/lib.rs +++ b/crates/pep508-rs/src/lib.rs @@ -16,23 +16,12 @@ #![warn(missing_docs)] -#[cfg(feature = "pyo3")] -use std::collections::hash_map::DefaultHasher; use std::collections::HashSet; use std::error::Error; use std::fmt::{Debug, Display, Formatter}; -#[cfg(feature = "pyo3")] -use std::hash::{Hash, Hasher}; -#[cfg(feature = "pyo3")] -use std::ops::Deref; use std::path::Path; use std::str::FromStr; -#[cfg(feature = "pyo3")] -use pyo3::{ - create_exception, exceptions::PyNotImplementedError, pyclass, pyclass::CompareOp, pymethods, - pymodule, types::PyModule, IntoPy, PyObject, PyResult, Python, -}; use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; use thiserror::Error; use url::Url; @@ -46,8 +35,6 @@ pub use marker::{ StringMarkerTree, StringVersion, VersionMarkerTree, }; pub use origin::RequirementOrigin; -#[cfg(feature = "pyo3")] -use pep440_rs::PyVersion; use pep440_rs::{Version, VersionSpecifier, VersionSpecifiers}; #[cfg(feature = "non-pep508-extensions")] pub use unnamed::{UnnamedRequirement, UnnamedRequirementUrl}; @@ -126,14 +113,6 @@ impl Display for Pep508Error { /// We need this to allow anyhow's `.context()` and `AsDynError`. impl> std::error::Error for Pep508Error {} -#[cfg(feature = "pyo3")] -create_exception!( - pep508, - PyPep508Error, - pyo3::exceptions::PyValueError, - "A PEP 508 parser error with span information" -); - /// A PEP 508 dependency specifier. #[derive(Hash, Debug, Clone, Eq, PartialEq, Ord, PartialOrd)] pub struct Requirement { @@ -221,155 +200,6 @@ impl Serialize for Requirement { type MarkerWarning = (MarkerWarningKind, String); -#[cfg(feature = "pyo3")] -#[pyclass(module = "pep508", name = "Requirement")] -#[derive(Hash, Debug, Clone, Eq, PartialEq)] -/// A PEP 508 dependency specifier. -pub struct PyRequirement(Requirement); - -#[cfg(feature = "pyo3")] -impl Deref for PyRequirement { - type Target = Requirement; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -#[cfg(feature = "pyo3")] -#[pymethods] -impl PyRequirement { - /// The distribution name such as `requests` in - /// `requests [security,tests] >= 2.8.1, == 2.8.* ; python_version > "3.8"` - #[getter] - pub fn name(&self) -> String { - self.name.to_string() - } - - /// The list of extras such as `security`, `tests` in - /// `requests [security,tests] >= 2.8.1, == 2.8.* ; python_version > "3.8"` - #[getter] - pub fn extras(&self) -> Vec { - self.extras.iter().map(ToString::to_string).collect() - } - - /// The marker expression such as `python_version > "3.8"` in - /// `requests [security,tests] >= 2.8.1, == 2.8.* ; python_version > "3.8"` - #[getter] - pub fn marker(&self) -> Option { - self.marker.try_to_string() - } - - /// Parses a PEP 440 string - #[new] - pub fn py_new(requirement: &str) -> PyResult { - Ok(Self( - Requirement::from_str(requirement) - .map_err(|err| PyPep508Error::new_err(err.to_string()))?, - )) - } - - #[getter] - fn version_or_url(&self, py: Python<'_>) -> PyObject { - match &self.version_or_url { - None => py.None(), - Some(VersionOrUrl::VersionSpecifier(version_specifier)) => version_specifier - .iter() - .map(|x| x.clone().into_py(py)) - .collect::>() - .into_py(py), - Some(VersionOrUrl::Url(url)) => url.to_string().into_py(py), - } - } - - fn __str__(&self) -> String { - self.to_string() - } - - fn __repr__(&self) -> String { - self.to_string() - } - - fn __richcmp__(&self, other: &Self, op: CompareOp) -> PyResult { - let err = PyNotImplementedError::new_err("Requirement only supports equality comparisons"); - match op { - CompareOp::Lt => Err(err), - CompareOp::Le => Err(err), - CompareOp::Eq => Ok(self == other), - CompareOp::Ne => Ok(self != other), - CompareOp::Gt => Err(err), - CompareOp::Ge => Err(err), - } - } - - fn __hash__(&self) -> u64 { - let mut hasher = DefaultHasher::new(); - self.hash(&mut hasher); - hasher.finish() - } - - /// Returns whether the markers apply for the given environment - #[allow(clippy::needless_pass_by_value)] - #[pyo3(name = "evaluate_markers")] - pub fn py_evaluate_markers( - &self, - env: &MarkerEnvironment, - extras: Vec, - ) -> PyResult { - let extras = extras - .into_iter() - .map(|extra| ExtraName::from_str(&extra)) - .collect::, InvalidNameError>>() - .map_err(|err| PyPep508Error::new_err(err.to_string()))?; - - Ok(self.evaluate_markers(env, &extras)) - } - - /// Returns whether the requirement would be satisfied, independent of environment markers, i.e. - /// if there is potentially an environment that could activate this requirement. - /// - /// Note that unlike [Self::evaluate_markers] this does not perform any checks for bogus - /// expressions but will simply return true. As caller you should separately perform a check - /// with an environment and forward all warnings. - #[allow(clippy::needless_pass_by_value)] - #[pyo3(name = "evaluate_extras_and_python_version")] - pub fn py_evaluate_extras_and_python_version( - &self, - extras: HashSet, - python_versions: Vec, - ) -> PyResult { - let extras = extras - .into_iter() - .map(|extra| ExtraName::from_str(&extra)) - .collect::, InvalidNameError>>() - .map_err(|err| PyPep508Error::new_err(err.to_string()))?; - - let python_versions = python_versions - .into_iter() - .map(|py_version| py_version.0) - .collect::>(); - - Ok(self.evaluate_extras_and_python_version(&extras, &python_versions)) - } - - /// Returns whether the markers apply for the given environment - #[allow(clippy::needless_pass_by_value)] - #[pyo3(name = "evaluate_markers_and_report")] - pub fn py_evaluate_markers_and_report( - &self, - env: &MarkerEnvironment, - extras: Vec, - ) -> PyResult<(bool, Vec)> { - let extras = extras - .into_iter() - .map(|extra| ExtraName::from_str(&extra)) - .collect::, InvalidNameError>>() - .map_err(|err| PyPep508Error::new_err(err.to_string()))?; - - Ok(self.evaluate_markers_and_report(env, &extras)) - } -} - impl Requirement { /// Returns whether the markers apply for the given environment pub fn evaluate_markers(&self, env: &MarkerEnvironment, extras: &[ExtraName]) -> bool { @@ -1167,32 +997,6 @@ fn parse_pep508_requirement( }) } -/// A library for [dependency specifiers](https://packaging.python.org/en/latest/specifications/dependency-specifiers/) -/// as originally specified in [PEP 508](https://peps.python.org/pep-0508/) -/// -/// This has `Version` and `VersionSpecifier` included. That is because -/// `pep440_rs.Version("1.2.3") != pep508_rs.Requirement("numpy==1.2.3").version_or_url` as the -/// `Version`s come from two different binaries and can therefore never be equal. -#[cfg(feature = "pyo3")] -#[pymodule] -#[pyo3(name = "pep508_rs")] -pub fn python_module(py: Python<'_>, m: &pyo3::Bound<'_, PyModule>) -> PyResult<()> { - // Allowed to fail if we embed this module in another - - #[allow(unused_must_use)] - { - pyo3_log::try_init(); - } - - m.add_class::()?; - m.add_class::()?; - - m.add_class::()?; - m.add_class::()?; - m.add("Pep508Error", py.get_type_bound::())?; - Ok(()) -} - /// Half of these tests are copied from #[cfg(test)] mod tests { diff --git a/crates/pep508-rs/src/marker/environment.rs b/crates/pep508-rs/src/marker/environment.rs index 54f80b394..7fa056952 100644 --- a/crates/pep508-rs/src/marker/environment.rs +++ b/crates/pep508-rs/src/marker/environment.rs @@ -1,10 +1,6 @@ -#[cfg(feature = "pyo3")] -use std::str::FromStr; use std::sync::Arc; use pep440_rs::{Version, VersionParseError}; -#[cfg(feature = "pyo3")] -use pyo3::{exceptions::PyValueError, pyclass, pymethods, types::PyAnyMethods, PyResult, Python}; use crate::{MarkerValueString, MarkerValueVersion, StringVersion}; @@ -15,7 +11,6 @@ use crate::{MarkerValueString, MarkerValueVersion, StringVersion}; /// Some are `(String, Version)` because we have to support version comparison #[allow(missing_docs, clippy::unsafe_derive_deserialize)] #[derive(Clone, Debug, Eq, Hash, PartialEq, serde::Deserialize, serde::Serialize)] -#[cfg_attr(feature = "pyo3", pyclass(module = "pep508"))] pub struct MarkerEnvironment { #[serde(flatten)] inner: Arc, @@ -317,205 +312,6 @@ impl MarkerEnvironment { } } -#[cfg(feature = "pyo3")] -#[pymethods] -impl MarkerEnvironment { - /// Construct your own marker environment - #[new] - #[pyo3(signature = (*, - implementation_name, - implementation_version, - os_name, - platform_machine, - platform_python_implementation, - platform_release, - platform_system, - platform_version, - python_full_version, - python_version, - sys_platform - ))] - fn py_new( - implementation_name: &str, - implementation_version: &str, - os_name: &str, - platform_machine: &str, - platform_python_implementation: &str, - platform_release: &str, - platform_system: &str, - platform_version: &str, - python_full_version: &str, - python_version: &str, - sys_platform: &str, - ) -> PyResult { - let implementation_version = - StringVersion::from_str(implementation_version).map_err(|err| { - PyValueError::new_err(format!( - "implementation_version is not a valid PEP440 version: {err}" - )) - })?; - let python_full_version = StringVersion::from_str(python_full_version).map_err(|err| { - PyValueError::new_err(format!( - "python_full_version is not a valid PEP440 version: {err}" - )) - })?; - let python_version = StringVersion::from_str(python_version).map_err(|err| { - PyValueError::new_err(format!( - "python_version is not a valid PEP440 version: {err}" - )) - })?; - Ok(Self { - inner: Arc::new(MarkerEnvironmentInner { - implementation_name: implementation_name.to_string(), - implementation_version, - os_name: os_name.to_string(), - platform_machine: platform_machine.to_string(), - platform_python_implementation: platform_python_implementation.to_string(), - platform_release: platform_release.to_string(), - platform_system: platform_system.to_string(), - platform_version: platform_version.to_string(), - python_full_version, - python_version, - sys_platform: sys_platform.to_string(), - }), - }) - } - - /// Query the current python interpreter to get the correct marker value - #[staticmethod] - fn current(py: Python<'_>) -> PyResult { - let os = py.import_bound("os")?; - let platform = py.import_bound("platform")?; - let sys = py.import_bound("sys")?; - let python_version_tuple: (String, String, String) = platform - .getattr("python_version_tuple")? - .call0()? - .extract()?; - - // See pseudocode at - // https://packaging.python.org/en/latest/specifications/dependency-specifiers/#environment-markers - let name = sys.getattr("implementation")?.getattr("name")?.extract()?; - let info = sys.getattr("implementation")?.getattr("version")?; - let kind = info.getattr("releaselevel")?.extract::()?; - let implementation_version: String = format!( - "{}.{}.{}{}", - info.getattr("major")?.extract::()?, - info.getattr("minor")?.extract::()?, - info.getattr("micro")?.extract::()?, - if kind == "final" { - String::new() - } else { - format!("{}{}", kind, info.getattr("serial")?.extract::()?) - } - ); - let python_full_version: String = platform.getattr("python_version")?.call0()?.extract()?; - let python_version = format!("{}.{}", python_version_tuple.0, python_version_tuple.1); - - // This is not written down in PEP 508, but it's the only reasonable assumption to make - let implementation_version = - StringVersion::from_str(&implementation_version).map_err(|err| { - PyValueError::new_err(format!( - "Broken python implementation, implementation_version is not a valid PEP440 version: {err}" - )) - })?; - let python_full_version = StringVersion::from_str(&python_full_version).map_err(|err| { - PyValueError::new_err(format!( - "Broken python implementation, python_full_version is not a valid PEP440 version: {err}" - )) - })?; - let python_version = StringVersion::from_str(&python_version).map_err(|err| { - PyValueError::new_err(format!( - "Broken python implementation, python_version is not a valid PEP440 version: {err}" - )) - })?; - Ok(Self { - inner: Arc::new(MarkerEnvironmentInner { - implementation_name: name, - implementation_version, - os_name: os.getattr("name")?.extract()?, - platform_machine: platform.getattr("machine")?.call0()?.extract()?, - platform_python_implementation: platform - .getattr("python_implementation")? - .call0()? - .extract()?, - platform_release: platform.getattr("release")?.call0()?.extract()?, - platform_system: platform.getattr("system")?.call0()?.extract()?, - platform_version: platform.getattr("version")?.call0()?.extract()?, - python_full_version, - python_version, - sys_platform: sys.getattr("platform")?.extract()?, - }), - }) - } - - /// Returns the name of the Python implementation for this environment. - #[getter] - pub fn py_implementation_name(&self) -> String { - self.implementation_name().to_string() - } - - /// Returns the Python implementation version for this environment. - #[getter] - pub fn py_implementation_version(&self) -> StringVersion { - self.implementation_version().clone() - } - - /// Returns the name of the operating system for this environment. - #[getter] - pub fn py_os_name(&self) -> String { - self.os_name().to_string() - } - - /// Returns the name of the machine for this environment's platform. - #[getter] - pub fn py_platform_machine(&self) -> String { - self.platform_machine().to_string() - } - - /// Returns the name of the Python implementation for this environment's - /// platform. - #[getter] - pub fn py_platform_python_implementation(&self) -> String { - self.platform_python_implementation().to_string() - } - - /// Returns the release for this environment's platform. - #[getter] - pub fn py_platform_release(&self) -> String { - self.platform_release().to_string() - } - - /// Returns the system for this environment's platform. - #[getter] - pub fn py_platform_system(&self) -> String { - self.platform_system().to_string() - } - - /// Returns the version for this environment's platform. - #[getter] - pub fn py_platform_version(&self) -> String { - self.platform_version().to_string() - } - - /// Returns the full version of Python for this environment. - #[getter] - pub fn py_python_full_version(&self) -> StringVersion { - self.python_full_version().clone() - } - - /// Returns the version of Python for this environment. - #[getter] - pub fn py_python_version(&self) -> StringVersion { - self.python_version().clone() - } - - /// Returns the name of the system platform for this environment. - #[getter] - pub fn py_sys_platform(&self) -> String { - self.sys_platform().to_string() - } -} - /// A builder for constructing a marker environment. /// /// A value of this type can be fallibly converted to a full diff --git a/crates/pep508-rs/src/marker/tree.rs b/crates/pep508-rs/src/marker/tree.rs index b6fc58df0..4d17cdff3 100644 --- a/crates/pep508-rs/src/marker/tree.rs +++ b/crates/pep508-rs/src/marker/tree.rs @@ -7,8 +7,6 @@ use std::str::FromStr; use itertools::Itertools; use pep440_rs::{Version, VersionParseError, VersionSpecifier}; use pubgrub::Range; -#[cfg(feature = "pyo3")] -use pyo3::{basic::CompareOp, pyclass, pymethods}; use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; use uv_normalize::ExtraName; @@ -23,7 +21,6 @@ use super::simplify; /// Ways in which marker evaluation can fail #[derive(Debug, Eq, Hash, Ord, PartialOrd, PartialEq, Clone, Copy)] -#[cfg_attr(feature = "pyo3", pyclass(module = "pep508"))] pub enum MarkerWarningKind { /// Using an old name from PEP 345 instead of the modern equivalent /// @@ -41,20 +38,6 @@ pub enum MarkerWarningKind { StringStringComparison, } -#[cfg(feature = "pyo3")] -#[pymethods] -impl MarkerWarningKind { - #[allow(clippy::trivially_copy_pass_by_ref)] - fn __hash__(&self) -> u8 { - *self as u8 - } - - #[allow(clippy::trivially_copy_pass_by_ref)] - fn __richcmp__(&self, other: Self, op: CompareOp) -> bool { - op.matches(self.cmp(&other)) - } -} - /// Those environment markers with a PEP 440 version as value such as `python_version` #[derive(Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)] #[allow(clippy::enum_variant_names)] @@ -373,7 +356,6 @@ impl Display for MarkerOperator { /// Helper type with a [Version] and its original text #[derive(Clone, Debug, Eq, Hash, PartialEq)] -#[cfg_attr(feature = "pyo3", pyclass(get_all, module = "pep508"))] pub struct StringVersion { /// Original unchanged string pub string: String,