From 85ab75104144f5c8b7d3920cdf63d66d5e913e30 Mon Sep 17 00:00:00 2001 From: "TAHRI Ahmed R." Date: Thu, 26 Dec 2024 07:54:11 +0100 Subject: [PATCH] Release 1.1.6 (#11) ## 1.1.6 (2024-12-26) ### Changed - pyo3 updated from 0.22.5 to 0.23.3 ### Fixed - Clippy warnings in our Rust code. ### Added - Initial support for Python 3.13 freethreaded experimental build. --- .github/workflows/CI.yml | 83 +++++++++++++++++++++++++++------------ .pre-commit-config.yaml | 18 ++++++++- CHANGELOG.md | 11 ++++++ Cargo.lock | 85 ++++++++++++++++++++++++++-------------- Cargo.toml | 5 +-- pyproject.toml | 5 ++- src/lib.rs | 15 +++---- tests/test_ctx.py | 68 ++++++++++++++++++++++++-------- wassima/_version.py | 2 +- 9 files changed, 208 insertions(+), 84 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index c0a4e16..7761310 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -21,10 +21,10 @@ jobs: lint: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: '3.11' - run: pip install pre-commit name: Install pre-commit - run: pre-commit run --all @@ -33,17 +33,20 @@ jobs: test: strategy: matrix: - os: [ubuntu-22.04, macos-12, windows-latest ] + os: [ubuntu-22.04, macos-13, windows-latest ] python_version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12', '3.13', 'pypy-3.7', 'pypy-3.8', 'pypy-3.9', 'pypy-3.10'] + exclude: + - python_version: 3.7 + os: macos-13 runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python_version }} allow-prereleases: true - name: Setup dependencies - run: pip install --upgrade pip pytest + run: pip install pytest - name: Install mkcert (Linux) if: matrix.os == 'ubuntu-22.04' run: sudo apt-get install mkcert @@ -59,13 +62,18 @@ jobs: - name: Build wheels (Unix, Linux) if: matrix.os != 'windows-latest' uses: PyO3/maturin-action@v1 + env: + UNSAFE_PYO3_SKIP_VERSION_CHECK: 1 with: args: --release --out dist --interpreter ${{ matrix.python_version }} sccache: 'true' manylinux: auto + docker-options: -e UNSAFE_PYO3_SKIP_VERSION_CHECK=1 - name: Build wheels (NT) if: matrix.os == 'windows-latest' uses: PyO3/maturin-action@v1 + env: + UNSAFE_PYO3_SKIP_VERSION_CHECK: 1 with: args: --release --out dist sccache: 'true' @@ -90,7 +98,7 @@ jobs: fail-fast: false matrix: target: [x86_64, x86, aarch64, armv7, s390x, ppc64le, ppc64, i686] - python_version: ['3.10', 'pypy-3.7', 'pypy-3.8', 'pypy-3.9', 'pypy-3.10'] + python_version: ['3.10', 'pypy-3.7', 'pypy-3.8', 'pypy-3.9', 'pypy-3.10', '3.13t'] manylinux: ['auto', 'musllinux_1_1'] exclude: - manylinux: musllinux_1_1 @@ -101,17 +109,25 @@ jobs: target: ppc64le steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + if: matrix.python_version != '3.13t' with: python-version: ${{ matrix.python_version }} + - uses: Quansight-Labs/setup-python@v5 + if: matrix.python_version == '3.13t' + with: + python-version: '3.13t' - name: Build wheels uses: PyO3/maturin-action@v1 + env: + UNSAFE_PYO3_SKIP_VERSION_CHECK: 1 with: target: ${{ matrix.target }} args: --release --out dist --interpreter ${{ matrix.python_version }} sccache: 'true' manylinux: ${{ matrix.manylinux }} + docker-options: -e UNSAFE_PYO3_SKIP_VERSION_CHECK=1 - name: Upload wheels uses: actions/upload-artifact@v3 with: @@ -127,7 +143,7 @@ jobs: fail-fast: false matrix: target: [x64, aarch64] - python_version: ['3.10', 'pypy-3.7', 'pypy-3.8', 'pypy-3.9', 'pypy-3.10'] + python_version: ['3.10', 'pypy-3.7', 'pypy-3.8', 'pypy-3.9', 'pypy-3.10', '3.13t'] exclude: - target: aarch64 python_version: 'pypy-3.7' @@ -137,18 +153,30 @@ jobs: python_version: 'pypy-3.9' - target: aarch64 python_version: 'pypy-3.10' + # known bug pyo3+maturin fail to produce correct wheel + - target: aarch64 + python_version: 3.13t steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + if: matrix.python_version != '3.13t' with: python-version: ${{ matrix.python_version }} architecture: x64 + - uses: Quansight-Labs/setup-python@v5 + if: matrix.python_version == '3.13t' + with: + python-version: '3.13t' + architecture: x64 - name: Build wheels uses: PyO3/maturin-action@v1 + env: + UNSAFE_PYO3_SKIP_VERSION_CHECK: 1 + PYO3_CROSS: ${{ matrix.target == 'aarch64' && '1' || '' }} with: target: ${{ matrix.target }} args: --release --out dist - sccache: 'true' + sccache: 'false' - name: Upload wheels uses: actions/upload-artifact@v3 with: @@ -159,22 +187,29 @@ jobs: needs: - test - lint - runs-on: macos-12 + runs-on: macos-13 strategy: fail-fast: false matrix: - target: [x86_64, aarch64, universal2] - python_version: ['3.10', 'pypy-3.7', 'pypy-3.8', 'pypy-3.9', 'pypy-3.10'] + target: [universal2] + python_version: ['3.10', 'pypy-3.7', 'pypy-3.8', 'pypy-3.9', 'pypy-3.10', '3.13t'] steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + if: matrix.python_version != '3.13t' with: python-version: ${{ matrix.python_version }} + - uses: Quansight-Labs/setup-python@v5 + if: matrix.python_version == '3.13t' + with: + python-version: '3.13t' - name: Build wheels uses: PyO3/maturin-action@v1 + env: + UNSAFE_PYO3_SKIP_VERSION_CHECK: 1 with: target: ${{ matrix.target }} - args: --release --out dist --interpreter ${{ matrix.python_version }} + args: --release --out dist sccache: 'true' - name: Upload wheels uses: actions/upload-artifact@v3 @@ -188,7 +223,7 @@ jobs: - lint runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Build sdist uses: PyO3/maturin-action@v1 with: @@ -206,8 +241,8 @@ jobs: - lint runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: '3.10' - name: Install dependencies @@ -247,7 +282,7 @@ jobs: provenance: needs: checksum if: "startsWith(github.ref, 'refs/tags/')" - uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.10.0 + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0 permissions: actions: read id-token: write diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ca81f96..3b51bdc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,4 +1,4 @@ -exclude: 'docs/|src/' +exclude: 'docs/|freethreaded.patch' repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.4.0 @@ -29,3 +29,19 @@ repos: - id: mypy args: [--check-untyped-defs] exclude: 'tests/' +- repo: local + hooks: + - id: rust-linting + name: Rust linting + description: Run cargo fmt on files included in the commit. rustfmt should be installed before-hand. + entry: cargo fmt --all -- + pass_filenames: true + types: [file, rust] + language: system + - id: rust-clippy + name: Rust clippy + description: Run cargo clippy on files included in the commit. clippy should be installed before-hand. + entry: cargo clippy --all-targets --all-features -- -Dclippy::all + pass_filenames: false + types: [file, rust] + language: system diff --git a/CHANGELOG.md b/CHANGELOG.md index 80d5820..041a061 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to wassima will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## 1.1.6 (2024-12-26) + +### Changed +- pyo3 updated from 0.22.5 to 0.23.3 + +### Fixed +- Clippy warnings in our Rust code. + +### Added +- Initial support for Python 3.13 freethreaded experimental build. + ## 1.1.5 (2024-10-27) ### Changed diff --git a/Cargo.lock b/Cargo.lock index 7d13633..3de29c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "autocfg" @@ -14,6 +14,15 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +[[package]] +name = "cc" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e" +dependencies = [ + "shlex", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -50,9 +59,9 @@ checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" [[package]] name = "libc" -version = "0.2.161" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "memoffset" @@ -77,24 +86,24 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "portable-atomic" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" +checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" [[package]] name = "proc-macro2" -version = "1.0.89" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] [[package]] name = "pyo3" -version = "0.22.5" +version = "0.23.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d922163ba1f79c04bc49073ba7b32fd5a8d3b76a87c955921234b8e77333c51" +checksum = "e484fd2c8b4cb67ab05a318f1fd6fa8f199fcc30819f08f07d200809dba26c15" dependencies = [ "cfg-if", "indoc", @@ -110,19 +119,20 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.22.5" +version = "0.23.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc38c5feeb496c8321091edf3d63e9a6829eab4b863b4a6a65f26f3e9cc6b179" +checksum = "dc0e0469a84f208e20044b98965e1561028180219e35352a2afaf2b942beff3b" dependencies = [ "once_cell", + "python3-dll-a", "target-lexicon", ] [[package]] name = "pyo3-ffi" -version = "0.22.5" +version = "0.23.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94845622d88ae274d2729fcefc850e63d7a3ddff5e3ce11bd88486db9f1d357d" +checksum = "eb1547a7f9966f6f1a0f0227564a9945fe36b90da5a93b3933fc3dc03fae372d" dependencies = [ "libc", "pyo3-build-config", @@ -130,9 +140,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.22.5" +version = "0.23.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e655aad15e09b94ffdb3ce3d217acf652e26bbc37697ef012f5e5e348c716e5e" +checksum = "fdb6da8ec6fa5cedd1626c886fc8749bdcbb09424a86461eb8cdf096b7c33257" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -142,9 +152,9 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.22.5" +version = "0.23.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1e3f09eecd94618f60a455a23def79f79eba4dc561a97324bf9ac8c6df30ce" +checksum = "38a385202ff5a92791168b1136afae5059d3ac118457bb7bc304c197c2d33e7d" dependencies = [ "heck", "proc-macro2", @@ -153,11 +163,20 @@ dependencies = [ "syn", ] +[[package]] +name = "python3-dll-a" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b66f9171950e674e64bad3456e11bb3cca108e5c34844383cfe277f45c8a7a8" +dependencies = [ + "cc", +] + [[package]] name = "quote" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -186,15 +205,15 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" +checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37" [[package]] name = "schannel" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" dependencies = [ "windows-sys", ] @@ -214,19 +233,25 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.12.0" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" +checksum = "1863fd3768cd83c56a7f60faa4dc0d403f1b6df0a38c3c25f44b7894e45370d5" dependencies = [ "core-foundation-sys", "libc", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "syn" -version = "2.0.85" +version = "2.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" +checksum = "d53cbcb5a243bd33b7858b1d7f4aca2153490815872d86d955d6ea29f743c035" dependencies = [ "proc-macro2", "quote", @@ -241,9 +266,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "unicode-ident" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unindent" @@ -253,7 +278,7 @@ checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce" [[package]] name = "wassima" -version = "1.1.5" +version = "1.1.6" dependencies = [ "pyo3", "rustls-native-certs", diff --git a/Cargo.toml b/Cargo.toml index b6d25aa..d5de885 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,15 +1,14 @@ [package] name = "wassima" -version = "1.1.5" +version = "1.1.6" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] name = "wassima" crate-type = ["cdylib"] [dependencies] -pyo3 = { version = "0.22.5", features = ["abi3-py37", "extension-module"] } +pyo3 = { version = "0.23.3", features = ["abi3-py37", "extension-module", "generate-import-lib"] } rustls-native-certs = "0.7.3" [package.metadata.maturin] diff --git a/pyproject.toml b/pyproject.toml index 524b1b6..57af86d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["maturin>=1.2,<2.0"] +requires = ["maturin>=1.7,<2"] build-backend = "maturin" [project] @@ -38,6 +38,7 @@ classifiers = [ dependencies = [ "certifi; (platform_python_implementation != 'CPython' or python_full_version < '3.7.10') or (platform_system != 'Darwin' and platform_system != 'Windows' and platform_system != 'Linux') or (platform_machine != 'x86_64' and platform_machine != 's390x' and platform_machine != 'aarch64' and platform_machine != 'armv7l' and platform_machine != 'ppc64le' and platform_machine != 'ppc64' and platform_machine != 'AMD64' and platform_machine != 'arm64' and platform_machine != 'ARM64' and platform_machine != 'i686') or (platform_python_implementation == 'PyPy' and python_version >= '3.11')", ] +dynamic = ["version"] [project.urls] "Changelog" = "https://github.com/jawah/wassima/blob/main/CHANGELOG.md" @@ -46,7 +47,7 @@ dependencies = [ "Issue tracker" = "https://github.com/jawah/wassima/issues" [tool.maturin] -features = ["pyo3/extension-module"] +features = ["pyo3/extension-module", "pyo3/abi3-py37", "pyo3/generate-import-lib"] module-name = "wassima._rustls" [tool.pytest.ini_options] diff --git a/src/lib.rs b/src/lib.rs index 4658176..75cdafa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,25 +1,26 @@ -use pyo3::{prelude::*, types::PyBytes}; use pyo3::exceptions::PyRuntimeError; -use rustls_native_certs; +use pyo3::{prelude::*, types::PyBytes}; /// Retrieve a list of system DER root CAs #[pyfunction] -fn root_der_certificates(py: Python) -> PyResult>> { +fn root_der_certificates(py: Python) -> PyResult>> { let mut roots = Vec::new(); let certs = rustls_native_certs::load_native_certs(); if certs.is_err() { - return Err(PyRuntimeError::new_err("unable to extract root certificates")); + return Err(PyRuntimeError::new_err( + "unable to extract root certificates", + )); } for cert in certs.unwrap() { - roots.push(PyBytes::new_bound(py, &cert.as_ref().to_vec())); + roots.push(PyBytes::new(py, cert.as_ref())); } - return Ok(roots); + Ok(roots) } -#[pymodule] +#[pymodule(gil_used = false)] fn _rustls(_py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> { m.add_function(wrap_pyfunction!(root_der_certificates, m)?)?; Ok(()) diff --git a/tests/test_ctx.py b/tests/test_ctx.py index c8ab861..54425ba 100644 --- a/tests/test_ctx.py +++ b/tests/test_ctx.py @@ -4,6 +4,7 @@ import threading from os.path import exists from socket import AF_INET, SOCK_STREAM, socket +from socket import timeout as SocketTimeout from ssl import PROTOCOL_TLS_SERVER, SSLContext, SSLError from time import sleep @@ -48,19 +49,42 @@ def test_ctx_use_system_store(host: str, port: int, expect_failure: bool) -> Non s = socket(AF_INET, SOCK_STREAM) s = ctx.wrap_socket(s, server_hostname=host) + s.settimeout(5) - if expect_failure: - with pytest.raises(SSLError) as exc: - s.connect((host, port)) - ssl_err = exc.value.args[1] - assert ( - "self-signed" in ssl_err - or "self signed" in ssl_err - or "unable to get local issuer certificate" in ssl_err - ) - else: - s.connect((host, port)) - assert s.getpeercert() is not None + i = 0 + + while True: + try: + if expect_failure: + with pytest.raises(SSLError) as exc: + s.connect((host, port)) + ssl_err = exc.value.args[1] + assert ( + "self-signed" in ssl_err + or "self signed" in ssl_err + or "unable to get local issuer certificate" in ssl_err + ) + else: + s.connect((host, port)) + assert s.getpeercert() is not None + + break + except ( + ConnectionResetError, + ConnectionRefusedError, + TimeoutError, + SocketTimeout, + ): + i += 1 + if i >= 15: + assert False + + s.close() + s = socket(AF_INET, SOCK_STREAM) + s = ctx.wrap_socket(s, server_hostname=host) + s.settimeout(1) + + continue s.close() @@ -86,22 +110,34 @@ def test_ctx_access_local_trusted_root() -> None: s = socket(AF_INET, SOCK_STREAM) s = ctx.wrap_socket(s, server_hostname="example.test") + s.settimeout(5) i = 0 while True: sleep(1) - if i >= 5: - break + if i >= 10: + assert False try: s.connect(("127.0.0.1", 47476)) - except ConnectionError: + except (ConnectionError, TimeoutError, SocketTimeout): i += 1 - except SSLError: + s.close() + s = socket(AF_INET, SOCK_STREAM) + s = ctx.wrap_socket(s, server_hostname="example.test") + s.settimeout(5) + except SSLError as e: + if "timeout" in str(e): + s.close() + s = socket(AF_INET, SOCK_STREAM) + s = ctx.wrap_socket(s, server_hostname="example.test") + s.settimeout(5) + continue assert False else: break assert s.getpeercert() is not None + s.close() diff --git a/wassima/_version.py b/wassima/_version.py index 97a7800..30334d2 100644 --- a/wassima/_version.py +++ b/wassima/_version.py @@ -1,4 +1,4 @@ from __future__ import annotations -__version__ = "1.1.5" +__version__ = "1.1.6" VERSION = __version__.split(".")