diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index c6d8bc5..adbeb1b 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -19,6 +19,24 @@ permissions: contents: read jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-python@v6 + with: + python-version: '3.12' + - uses: astral-sh/setup-uv@v7 + with: + version: "0.6.x" + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + - name: Run tests + run: | + uv sync + uv run maturin develop --uv + uv run python test.py + linux: runs-on: ${{ matrix.platform.runner }} strategy: @@ -162,7 +180,7 @@ jobs: name: Release runs-on: ubuntu-latest if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }} - needs: [linux, musllinux, windows, macos, sdist] + needs: [test, linux, musllinux, windows, macos, sdist] permissions: # Use to sign the release artifacts id-token: write diff --git a/Cargo.lock b/Cargo.lock index 81978df..3d74704 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,59 +2,35 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - [[package]] name = "heck" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "indoc" -version = "2.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706" -dependencies = [ - "rustversion", -] - [[package]] name = "libc" -version = "0.2.180" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "matchit" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3eede3bdf92f3b4f9dc04072a9ce5ab557d5ec9038773bf9ffcd5588b3cc05b" - -[[package]] -name = "memoffset" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] +checksum = "8863b587001c1b9a8a4e36008cebc6b3612cb1226fe2de94858e06092687b608" [[package]] name = "once_cell" -version = "1.21.3" +version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "portable-atomic" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "proc-macro2" @@ -67,35 +43,32 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.27.2" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab53c047fcd1a1d2a8820fe84f05d6be69e9526be40cb03b73f86b6b03e6d87d" +checksum = "cd274650b21d4bfc26a0a47587962c1edb425f69287324355cd040c3ea66071c" dependencies = [ - "indoc", "libc", - "memoffset", "once_cell", "portable-atomic", "pyo3-build-config", "pyo3-ffi", "pyo3-macros", - "unindent", ] [[package]] name = "pyo3-build-config" -version = "0.27.2" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b455933107de8642b4487ed26d912c2d899dec6114884214a0b3bb3be9261ea6" +checksum = "c5e2a7d2f0d013342f295c048ad19237add5154a55b1c5a254c0ec93d4109078" dependencies = [ "target-lexicon", ] [[package]] name = "pyo3-ffi" -version = "0.27.2" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c85c9cbfaddf651b1221594209aed57e9e5cff63c4d11d1feead529b872a089" +checksum = "ca85c467da1bbc8d866eea5deff9cf29ea5f7785054a17da36e65bda9c05845b" dependencies = [ "libc", "pyo3-build-config", @@ -103,9 +76,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.27.2" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a5b10c9bf9888125d917fb4d2ca2d25c8df94c7ab5a52e13313a07e050a3b02" +checksum = "9ac53762fd065daa3194dd09337a38bd793a188100fd1a9304c4ab312d901771" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -115,20 +88,19 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.27.2" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03b51720d314836e53327f5871d4c0cfb4fb37cc2c4a11cc71907a86342c40f9" +checksum = "4ca3a1557399783172dc5bf39cfca835157732532cba56b71d2292161e53b362" dependencies = [ "heck", "proc-macro2", - "pyo3-build-config", "quote", "syn", ] [[package]] name = "python-matchit" -version = "0.3.0" +version = "0.4.0" dependencies = [ "matchit", "pyo3", @@ -136,24 +108,18 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.44" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" dependencies = [ "proc-macro2", ] -[[package]] -name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - [[package]] name = "syn" -version = "2.0.114" +version = "2.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" dependencies = [ "proc-macro2", "quote", @@ -162,18 +128,12 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.13.4" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1dd07eb858a2067e2f3c7155d54e929265c264e6f37efe3ee7a8d1b5a1dd0ba" +checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" [[package]] name = "unicode-ident" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" - -[[package]] -name = "unindent" -version = "0.2.4" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" diff --git a/Cargo.toml b/Cargo.toml index 267518c..4fd4530 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "python-matchit" -version = "0.3.0" +version = "0.4.0" edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -9,9 +9,9 @@ name = "matchit" crate-type = ["cdylib"] [dependencies] -matchit = "0.9.1" +matchit = "0.9.2" [dependencies.pyo3] -version = "0.27.0" +version = "0.29.0" # "abi3-py38" tells pyo3 (and maturin) to build using the stable ABI with minimum Python version 3.8 features = ["abi3-py38"] \ No newline at end of file diff --git a/README.md b/README.md index 1ad51c4..7f7a1ec 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -**python-matchit** package contains binding for [matchit](https://docs.rs/matchit/latest/matchit/) rust library. +**python-matchit** is a Python binding for the [matchit](https://docs.rs/matchit/latest/matchit/) Rust library. + +`matchit` is a high-performance URL/path routing library. It builds a radix tree (compressed trie) from route patterns and finds the best match for a given path in logarithmic time. This makes **python-matchit** a very fast choice for HTTP routers, URL dispatchers, or any task where you need to match many patterns against paths. # Installation @@ -10,7 +12,8 @@ pip install python-matchit ```python from matchit import Router -router = Router() + +router = Router[str]() router.insert("/users/{id}", "test_id") res = router.at("/users/123") @@ -19,24 +22,62 @@ assert res.value == "test_id" assert res.params == {"id": "123"} try: - assert r.at("/noway") + router.at("/noway") except LookupError: print("Not found as expected") ``` -# Development +`Router()` without type argument also works. -## Updating matchit +# Development -To update `matchit`: +## Setup ```shell -cargo update -p matchit +uv sync ``` ## Testing +Build and install the package in editable mode, then run tests: + ```shell maturin develop --uv -uv run test.py +uv run python test.py ``` + +> **Note:** use `maturin develop --uv`, not `uv run maturin develop`. The latter runs maturin without telling it to use `uv` for installation, which may result in a non-editable install. + +## Updating matchit + +To update the underlying Rust `matchit` library: + +1. Check [matchit release notes](https://github.com/ibraheemdev/matchit/releases) for breaking changes. +2. Update the version in `Cargo.toml`: + + ```toml + [dependencies] + matchit = "0.10.0" + ``` + +3. Update `Cargo.lock`: + + ```shell + cargo update -p matchit + ``` + +4. Adapt `src/lib.rs` if the `matchit` API changed. +5. Rebuild and test: + + ```shell + maturin develop --uv + uv run python test.py + ``` + +## Building a release + +```shell +maturin build --release +``` + +The built wheel will be placed in `dist/`.