diff --git a/.github/workflows/build-rust-wheels.yml b/.github/workflows/build-rust-wheels.yml index e9b2db7..a3798b7 100644 --- a/.github/workflows/build-rust-wheels.yml +++ b/.github/workflows/build-rust-wheels.yml @@ -97,12 +97,11 @@ jobs: steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - # macos-latest no longer preinstalls 3.10, so make the oldest supported - # interpreter visible to maturin's --find-interpreter discovery. - - name: Add Python 3.10 to the build toolcache + # Make the oldest supported interpreter visible to maturin discovery. + - name: Add Python 3.11 to the build toolcache uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: - python-version: '3.10' + python-version: '3.11' - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: @@ -188,10 +187,10 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] - python-version: ['3.10', '3.11', '3.12', '3.13', '3.14'] + python-version: ['3.11', '3.12', '3.13', '3.14'] include: - os: ubuntu-latest - python-version: '3.15.0-beta.3' + python-version: '3.15.0' steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 1c3e3bf..3cb6e92 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -33,7 +33,7 @@ jobs: matrix: # Pin PyPy 3.11 to the 7.3.23 build so CI keeps exercising the # CPython 3.11.15-compatible runtime documented in BENCHMARKS.md. - python-version: [pypy-3.10, pypy-3.11-v7.3.23, '3.10', '3.11', '3.12', '3.13', '3.14', '3.14t', '3.15.0-rc.1'] + python-version: [pypy-3.11-v7.3.23, '3.11', '3.12', '3.13', '3.14', '3.14t', '3.15.0'] os: [ ubuntu-latest, windows-latest, diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index f0aa41f..bb30dd1 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -62,10 +62,10 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ['3.10', '3.11', '3.12', '3.13', '3.14'] + python-version: ['3.11', '3.12', '3.13', '3.14'] include: - os: ubuntu-latest - python-version: '3.15.0-beta.3' + python-version: '3.15.0' steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 02b4e33..4543bb0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -45,4 +45,4 @@ repos: rev: v3.19.1 hooks: - id: pyupgrade - args: [--py310-plus] + args: [--py311-plus] diff --git a/BENCHMARKS.md b/BENCHMARKS.md index 74f341f..17368ee 100644 --- a/BENCHMARKS.md +++ b/BENCHMARKS.md @@ -304,7 +304,7 @@ below use `uv` because it keeps Python setup reproducible. | Tool | Required for | Notes | |------|--------------|-------| -| Python 3.10+ | Pure Python benchmarks | The published run used Python 3.14.4. | +| Python 3.11+ | Pure Python benchmarks | The published run used Python 3.14.4. | | Rust toolchain | Rust extension benchmarks | Needed only when building `json2xml_rs` locally. | | maturin | Rust extension benchmarks | Builds and installs the PyO3 extension. | | json2xml-go | Go CLI benchmarks | Must be on `PATH` as `json2xml-go`. | diff --git a/docs/installation.rst b/docs/installation.rst index 4f0ffe0..b150f00 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -83,7 +83,7 @@ For contributing to json2xml, set up a development environment: Requirements ------------ -json2xml requires Python 3.10 or later and depends on: +json2xml requires Python 3.11 or later and depends on: * ``defusedxml`` - For secure XML parsing * ``urllib3`` - For fetching JSON from URLs diff --git a/lat.md/architecture.md b/lat.md/architecture.md index 43cd4ea..4fd4799 100644 --- a/lat.md/architecture.md +++ b/lat.md/architecture.md @@ -36,18 +36,22 @@ The Rust extension crate targets the Rust 2024 edition and pins `rust-version` t The Cargo feature layout separates normal Rust/PyO3 tests from extension-module builds. `cargo test` uses the default `python` feature without extension-module linking, while maturin enables the `extension-module` feature for wheel builds. -Release and CI workflows install the pinned Rust toolchain before building wheels or running Rust checks, so hosted runners do not silently use an older default compiler. The macOS release build also provisions Python 3.10 explicitly so maturin emits wheels for the oldest supported interpreter even when runner images omit it. +Release and CI workflows install the pinned Rust toolchain before building wheels or running Rust checks, so hosted runners do not silently use an older default compiler. The macOS release build also provisions Python 3.11 explicitly so maturin emits wheels for the oldest supported interpreter even when runner images omit it. ## Development checks Make-based lint, type-check, and Python test targets run through uv's locked development environment so results do not depend on globally installed tools or optional extensions. +The pre-commit pyupgrade hook uses `--py311-plus` to keep Python source syntax aligned with the minimum supported interpreter. + The shared `UV_RUN` command installs the complete `dev` extra from `uv.lock`. `pyproject.toml` and `uv.lock` are the only dependency declaration, so no pinned requirements files can drift from them. The type-check target overlays `ty`, while pytest configuration has one source in `pyproject.toml` and enforces 100% coverage for bare local runs. Rust extension integration stays in its dedicated workflow. ## Release packaging Package releases keep the Python wrapper and Rust accelerator requirements aligned and use `uv build`/`uv publish` so optional fast installs receive compatible wheels. +Both the Python package and Rust accelerator require Python 3.11 or later. CI covers CPython and PyPy 3.11+; older interpreter jobs are excluded. + The Python package version lives in `pyproject.toml` and `json2xml/__init__.py`. The Rust accelerator version lives in both `rust/Cargo.toml` and `rust/pyproject.toml`, and the Python `fast` extra should require the Rust package version that contains any expected accelerator behavior. Publish and verify the Rust package before updating that Python requirement and lockfile. Release notes live in `HISTORY.rst`, with the current release also summarized in `RELEASE_NOTES.md` for tag and PyPI copy. ## Performance benchmarks @@ -100,7 +104,7 @@ Dependabot checks the root and documentation Python dependency manifests weekly, GitHub Actions workflows run with read-only tokens by default and use full SHA pins so third-party action updates are explicit. -The `.github/workflows/` files declare the minimum `permissions:` scopes needed by each workflow, with CodeQL retaining `security-events: write` for result upload and TestPyPI retaining `id-token: write` for explicit trusted-publishing runs. The Python test job also scopes `id-token: write` and `FLAKINESS_PROJECT` to its pytest matrix so the flakiness reporter can authenticate through GitHub OIDC without exposing that permission to lint. Release-branch pushes build distributions and runs Twine checks; TestPyPI upload is a manual opt-in because that external registry requires separate publisher configuration. Action references are pinned to immutable commits with the upstream tag retained in comments for reviewability, and all CodeQL phases use the same release commit because mixed action versions reject each other's configuration. `.github/dependabot.yml` checks the `github-actions` ecosystem weekly so those pins do not silently age. The Python test matrix pins its PyPy 3.11 job to an explicit PyPy release so CI keeps exercising the intended CPython 3.11.15-compatible runtime instead of silently drifting with runner cache updates. It also exercises regular CPython 3.15.0rc1 while leaving that beta's free-threaded builds out of CI until the runner support is less brittle. +The `.github/workflows/` files declare the minimum `permissions:` scopes needed by each workflow, with CodeQL retaining `security-events: write` for result upload and TestPyPI retaining `id-token: write` for explicit trusted-publishing runs. The Python test job also scopes `id-token: write` and `FLAKINESS_PROJECT` to its pytest matrix so the flakiness reporter can authenticate through GitHub OIDC without exposing that permission to lint. Release-branch pushes build distributions and runs Twine checks; TestPyPI upload is a manual opt-in because that external registry requires separate publisher configuration. Action references are pinned to immutable commits with the upstream tag retained in comments for reviewability, and all CodeQL phases use the same release commit because mixed action versions reject each other's configuration. `.github/dependabot.yml` checks the `github-actions` ecosystem weekly so those pins do not silently age. The Python test matrix pins its PyPy 3.11 job to an explicit PyPy release so CI keeps exercising the intended CPython 3.11.15-compatible runtime instead of silently drifting with runner cache updates. The Python, Rust extension, and Rust wheel test workflows exercise stable CPython 3.15.0; Python 3.15 free-threaded builds remain outside the CI matrix. The native backend is only selected for payloads it renders byte-identically. [[json2xml/backend_selector.py#rust_renders_identically]] is the reference definition of that subset -- dict, list, and exact `str`, `bool`, `int`, `float`, and `None` values, under keys both implementations name the same way -- and `payload_is_supported` in the crate is its native form, used at dispatch so the walk does not cost more than the conversion it guards. Subclasses and non-JSON-native values stay on Python because its isinstance fallbacks classify them in ways the native writer does not reproduce. Tuples also stay on Python: it applies its list-shape rules to them, while the native writer only recognizes lists. diff --git a/pyproject.toml b/pyproject.toml index e63405e..71286e3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ name = "json2xml" version = "7.1.1" description = "Simple Python Library to convert JSON to XML" readme = "README.rst" -requires-python = ">=3.10" +requires-python = ">=3.11" license = { text = "Apache Software License 2.0" } keywords = ["json2xml"] authors = [ @@ -18,7 +18,6 @@ classifiers = [ "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Natural Language :: English", - "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", diff --git a/rust/README.md b/rust/README.md index 08dcec4..1d2160a 100644 --- a/rust/README.md +++ b/rust/README.md @@ -7,7 +7,7 @@ A high-performance Rust implementation of the dicttoxml module using PyO3. ### Prerequisites - Rust (1.96+) -- Python (3.9+) +- Python (3.11+) - maturin (`pip install maturin`) ### Development Build diff --git a/rust/pyproject.toml b/rust/pyproject.toml index da5078d..c5eda0b 100644 --- a/rust/pyproject.toml +++ b/rust/pyproject.toml @@ -7,7 +7,7 @@ name = "json2xml_rs" version = "0.6.0" description = "Fast native JSON to XML conversion - Rust extension for json2xml" readme = "README.md" -requires-python = ">=3.9" +requires-python = ">=3.11" license = {text = "Apache-2.0"} classifiers = [ "Programming Language :: Rust", diff --git a/uv.lock b/uv.lock index 059c3f3..2cfb80b 100644 --- a/uv.lock +++ b/uv.lock @@ -1,6 +1,6 @@ version = 1 revision = 3 -requires-python = ">=3.10" +requires-python = ">=3.11" [[package]] name = "colorama" @@ -17,20 +17,6 @@ version = "7.15.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/be/c3/4f2195f512fb172aa425a8803a874b2baa9ba7f80ff7b6080998761fc701/coverage-7.15.4.tar.gz", hash = "sha256:0548198fff07ccf4faf469520bce1c2eceb1ce3e62891921138dec10907f9d00", size = 936952, upload-time = "2026-08-06T13:50:24.442Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/30/70/b052a519a584663a7bd052841a2debe11c8309ec49a7786340003f9c0a02/coverage-7.15.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d0be6daac4cce6b8c8dc65886bae1b082ddbca4da8e5cbb5e15166acf253e264", size = 222245, upload-time = "2026-08-06T13:46:55.253Z" }, - { url = "https://files.pythonhosted.org/packages/67/39/892fa511aba3d1c3c8f49509a0ff5c71eab9f9f88d08e1a38da395821660/coverage-7.15.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b24e078eabcd6a9caa8b0713f9bc1eeb310bcc960a29d45a3b4fcd4b16d5b11d", size = 222762, upload-time = "2026-08-06T13:46:57.848Z" }, - { url = "https://files.pythonhosted.org/packages/9f/95/b2c724ce1e64bc23cb5b1d7eeffa9548dc3d811f7a6297b2d01607f4e062/coverage-7.15.4-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cfe20cc8cf8821d4fe54f89106cbf06aa27f37b5bbe3535568065a81539b4150", size = 249498, upload-time = "2026-08-06T13:46:59.012Z" }, - { url = "https://files.pythonhosted.org/packages/0b/4f/b1973f67a1382af65b572a31ed692f8e490a6ad707191eab59148376832a/coverage-7.15.4-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:83cf06cdd687677742caff1a9134833b7a8b75f111519d2cb0e0ba1b9a851e15", size = 251328, upload-time = "2026-08-06T13:47:00.764Z" }, - { url = "https://files.pythonhosted.org/packages/a2/09/03efa6722a132abcac91b32a60b64b240dd707c189c64eee697e48992c96/coverage-7.15.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8fa4de68e2a752468ff14b4e15db7def689a71be759e826a31ccecbef69c5fd0", size = 253194, upload-time = "2026-08-06T13:47:01.976Z" }, - { url = "https://files.pythonhosted.org/packages/45/63/8299201d9c80fb65551ce99c966cab83d706ec4066ac999bef08201346de/coverage-7.15.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4dff9daa47d83120c3ec38ce921214242944a832aa04e903e50b5b7ebac8972d", size = 255106, upload-time = "2026-08-06T13:47:03.281Z" }, - { url = "https://files.pythonhosted.org/packages/ee/16/26fd8a691eb8d9a230128685f6d23309d7402cb030aa553001788c8c50fc/coverage-7.15.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a093fd37229918976f602aa07aa59e0973cde82186f220c8e197f721f5be0ce4", size = 250177, upload-time = "2026-08-06T13:47:04.713Z" }, - { url = "https://files.pythonhosted.org/packages/ad/ef/3c7556f33783a0a566e01443ca62bd8eb2cdfe22d271efdc02e08beb5654/coverage-7.15.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:317db01a2cb02552fd67e2b1cca77a4b528a2a277176c5e0bf2cecbb639d3f54", size = 251234, upload-time = "2026-08-06T13:47:06.104Z" }, - { url = "https://files.pythonhosted.org/packages/29/49/640a34043edac950738f36a3567832db5731d4cb2ed84b59cdb89c6bccbf/coverage-7.15.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:8ee3838dcb656602c3b51e16aed9bfb0822f8d8d6d1c5966d32ec8c104be8e20", size = 249237, upload-time = "2026-08-06T13:47:07.467Z" }, - { url = "https://files.pythonhosted.org/packages/48/f5/e80f212669dd1be954ff844f883ef11a437ef4fd0089c6e0effc7b66b15d/coverage-7.15.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:425920379052ff1fe465268f3361d35804a241bbdd5a1b592c8cb60df4c52325", size = 253050, upload-time = "2026-08-06T13:47:08.748Z" }, - { url = "https://files.pythonhosted.org/packages/c7/e9/e5da0fe39f7fde1bca9edc09c60921bb5fdba4cec7db5bbad41ddfd8c230/coverage-7.15.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:69bb2400abef928e365ea7d4d9925169ada78ed2295546780002d4b65de3df88", size = 249508, upload-time = "2026-08-06T13:47:10.072Z" }, - { url = "https://files.pythonhosted.org/packages/7d/38/41bf25774a0c8bba6b467f917cb1c9a0a2605e02dc93aad489fc7050ed59/coverage-7.15.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:81661f82d302484e3119e7c80c519c02fa9bcc2a6b339baf67d67bc89c580f04", size = 250110, upload-time = "2026-08-06T13:47:11.35Z" }, - { url = "https://files.pythonhosted.org/packages/89/6e/26f2e54b79acc29d179ee4272922625aedb69198c4eb61f7ff4f098f3c78/coverage-7.15.4-cp310-cp310-win32.whl", hash = "sha256:cb476b2e828ecb71cb6b6a928d23fd20a7ddb501188022dae1c37499149cc338", size = 224294, upload-time = "2026-08-06T13:47:12.753Z" }, - { url = "https://files.pythonhosted.org/packages/7b/06/9a318fc3ae040d4d6cb2d86101c6aa963fab20899a5c58666adf52cde0ca/coverage-7.15.4-cp310-cp310-win_amd64.whl", hash = "sha256:3fc2130bf37df31852a8384f12601563a45a0024bccc6624f38355cba7a8d360", size = 224919, upload-time = "2026-08-06T13:47:14.17Z" }, { url = "https://files.pythonhosted.org/packages/2a/66/edcec7d7a0b524aa8923e22925fde6fe50ce005a113dca13ae1581455c4c/coverage-7.15.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bbac5abad70df71019988f83f26ac7092ff2642975def4429e98dc7585ef3490", size = 222367, upload-time = "2026-08-06T13:47:15.578Z" }, { url = "https://files.pythonhosted.org/packages/e6/c6/ab8de429e2e8548faf58ec7e1674a4ce00414b4113942d3fe87109cf0f68/coverage-7.15.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:357a173465c7ce028d07a95cc2b63b5bf59f50ecdd5ad75c5cbb78ada984048e", size = 222874, upload-time = "2026-08-06T13:47:16.961Z" }, { url = "https://files.pythonhosted.org/packages/be/c4/3b7b49587e8a6b9af79b3eb468d443d6042b6d65b47aa26586846a0d6566/coverage-7.15.4-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:21b803935e2efc3acebe9697197a294fccf5dc4e5382bd6369542ff7a7d2a1d7", size = 253287, upload-time = "2026-08-06T13:47:18.291Z" }, @@ -153,18 +139,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61", size = 25604, upload-time = "2021-03-08T10:59:24.45Z" }, ] -[[package]] -name = "exceptiongroup" -version = "1.3.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, -] - [[package]] name = "execnet" version = "2.1.2" @@ -229,11 +203,6 @@ version = "0.6.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/49/90/d78c9b92848320f68c6b3bda03140063daeaf6846f4010bc216abb8eed28/json2xml_rs-0.6.0.tar.gz", hash = "sha256:a729703b4134e58ad40de68fc7e357a8bf5871e9a0327e8d906d8f3a87f23fa1", size = 13168, upload-time = "2026-09-02T20:56:19.464Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/24/5a/8341c166ff5083ad826203433c1d0513cf10c32f2e29aa4223b419e4c6e1/json2xml_rs-0.6.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:9a10d73457360ef91596697ff68fa4f545fc6f9a1f09590d2d64b0650000dd7e", size = 227729, upload-time = "2026-09-02T20:55:37.34Z" }, - { url = "https://files.pythonhosted.org/packages/a8/fd/40966aeb9b62b2c14845b6bd1b502aad922b25621da1dc07eaf998f71fe6/json2xml_rs-0.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:17eeacddbdd9a57e0deeb10407faab81ce291884379e95ee6c724b0beda654b8", size = 219530, upload-time = "2026-09-02T20:55:38.87Z" }, - { url = "https://files.pythonhosted.org/packages/a3/74/b03d27e0fe6d5777b5f7bd64ac683d8cf761bf3083c81597003d29efd8af/json2xml_rs-0.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2184a8041f782bbb6b78bba39d7ede181a35052e4cb0a4e9eeea2f115a97924a", size = 235834, upload-time = "2026-09-02T20:55:40.17Z" }, - { url = "https://files.pythonhosted.org/packages/77/31/983b534fb9209a67eab1b1059bd14f39433e5bd8d6cec504ac84acf94628/json2xml_rs-0.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a1917167e8afeb8d62bad5911679f3d2c091ea5d384b0e5b88dd2693d884737", size = 238078, upload-time = "2026-09-02T20:55:41.508Z" }, - { url = "https://files.pythonhosted.org/packages/8e/80/eee9db2f8667520afb1a6251935d8aa4e72d7923dce245991c1975bd9989/json2xml_rs-0.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:017eaf78ee9f3d8d3dbaddd961890477ed7025cd8d9dd20215770258b1dce3f5", size = 124398, upload-time = "2026-09-02T20:55:42.645Z" }, { url = "https://files.pythonhosted.org/packages/21/4c/144858169bd6cd7f314bf3a39df5acc1f2a7ca35b6acbfbe4ece4c02b10f/json2xml_rs-0.6.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6f6b786250bf987fb44cb960a6d84dcf154707e52894bc818853a63d4b13ad07", size = 227566, upload-time = "2026-09-02T20:55:43.944Z" }, { url = "https://files.pythonhosted.org/packages/34/f1/be71562f6276ac6199316da5bf4874a7bfa4a25162dc6e31b761e7deb714/json2xml_rs-0.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fd52a8aecaf18d1be8ac8ea23aba16f18ba495df5f397d9fd21d08be73e1cfe7", size = 219368, upload-time = "2026-09-02T20:55:45.159Z" }, { url = "https://files.pythonhosted.org/packages/e7/35/c09105bf69a5527a673399b6fdbd75c092cd4fb58415bb30c6220a31ea80/json2xml_rs-0.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eabd196d593a5c5e23be3fbbc3d472002a78f3fc3e3e324638f4a23406facc5a", size = 235732, upload-time = "2026-09-02T20:55:46.389Z" }, @@ -295,12 +264,10 @@ version = "9.0.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, { name = "pygments" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/549bd94f1a0a402dc8cf64563a117c0f3765662e2e668477624baeec44d5/pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c", size = 1572165, upload-time = "2026-04-07T17:16:18.027Z" } wheels = [ @@ -417,15 +384,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/77/b8/0135fadc89e73be292b473cb820b4f5a08197779206b33191e801feeae40/tomli-2.3.0-py3-none-any.whl", hash = "sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b", size = 14408, upload-time = "2025-10-08T22:01:46.04Z" }, ] -[[package]] -name = "typing-extensions" -version = "4.15.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, -] - [[package]] name = "urllib3" version = "2.7.0"