Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-python-bidi for 
openSUSE:Factory checked in at 2026-09-17 15:24:33
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-python-bidi (Old)
 and      /work/SRC/openSUSE:Factory/.python-python-bidi.new.383539 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-python-bidi"

Thu Sep 17 15:24:33 2026 rev:8 rq:1378494 version:0.6.11

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-python-bidi/python-python-bidi.changes    
2026-01-06 17:47:18.640355978 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-python-bidi.new.383539/python-python-bidi.changes
        2026-09-17 15:24:40.598209101 +0200
@@ -1,0 +2,10 @@
+Thu Sep 17 02:58:09 UTC 2026 - Steve Kowalik <[email protected]>
+
+- Update to 0.6.11:
+  * Bump pyo3 to 0.29.0, drop unsupported 3.13t
+  * Rust extension declares gil_used = false so it runs under free-threaded
+    (no-GIL) Python
+  * Added concurrent stress test for get_display under free-threaded builds
+  * Set requires-python = ">=3.9" explicitly in pyproject.toml
+
+-------------------------------------------------------------------

Old:
----
  python_bidi-0.6.7.tar.gz

New:
----
  python_bidi-0.6.11.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-python-bidi.spec ++++++
--- /var/tmp/diff_new_pack.9Jh7m2/_old  2026-09-17 15:24:42.965308373 +0200
+++ /var/tmp/diff_new_pack.9Jh7m2/_new  2026-09-17 15:24:42.968308498 +0200
@@ -18,18 +18,17 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-python-bidi
-Version:        0.6.7
+Version:        0.6.11
 Release:        0
 Summary:        BiDi layout algorithm
 License:        LGPL-3.0-only
 URL:            https://github.com/MeirKriheli/python-bidi
 Source:         
https://files.pythonhosted.org/packages/source/p/python_bidi/python_bidi-%{version}.tar.gz
 Source1:        vendor.tar.xz
+BuildRequires:  %{python_module base >= 3.9}
 BuildRequires:  %{python_module maturin > 1}
 BuildRequires:  %{python_module pip}
 BuildRequires:  %{python_module pytest}
-BuildRequires:  %{python_module setuptools}
-BuildRequires:  %{python_module wheel}
 BuildRequires:  cargo-packaging
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros

++++++ python_bidi-0.6.7.tar.gz -> python_bidi-0.6.11.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python_bidi-0.6.7/.github/workflows/CI.yml 
new/python_bidi-0.6.11/.github/workflows/CI.yml
--- old/python_bidi-0.6.7/.github/workflows/CI.yml      2025-10-22 
11:45:34.000000000 +0200
+++ new/python_bidi-0.6.11/.github/workflows/CI.yml     2006-07-24 
03:21:28.000000000 +0200
@@ -1,7 +1,6 @@
-# This file is autogenerated by maturin v1.7.0
-# To update, run
-#
-#    maturin generate-ci github
+# This file was originally generated by maturin v1.7.0 (`maturin generate-ci 
github`).
+# It has been customized for free-threaded wheels and resilience when 
setup-python /
+# actions/python-versions temporarily lacks builds for a given OS/arch/version.
 #
 name: CI
 
@@ -40,13 +39,27 @@
       - uses: actions/checkout@v4
       - uses: actions/setup-python@v5
         with:
-          python-version: 3.x
-          check-latest: true
+          python-version: '3.x'
+      - uses: actions/setup-python@v5
+        id: setup_freethreaded
+        continue-on-error: true
+        with:
+          python-version: 3.14t
+      - name: Configure maturin interpreters
+        shell: bash
+        run: |
+          INTERP='3.8 3.9 3.10 3.11 3.12 3.13 3.14'
+          if [[ '${{ steps.setup_freethreaded.outcome }}' == 'success' ]]; then
+            INTERP="$INTERP 3.14t"
+          else
+            echo '::warning::Free-threaded Python (3.14t) unavailable from 
setup-python; skipping cp314t wheels this run.'
+          fi
+          echo "MATURIN_INTERPRETERS=$INTERP pypy3.11" >> "$GITHUB_ENV"
       - name: Build wheels
         uses: PyO3/maturin-action@v1
         with:
           target: ${{ matrix.platform.target }}
-          args: --release --out dist -i 3.8 3.9 3.10 3.11 3.12 3.13 pypy3.11
+          args: --release --out dist -i ${{ env.MATURIN_INTERPRETERS }}
           sccache: 'true'
           manylinux: auto
       - name: Upload wheels
@@ -72,13 +85,27 @@
       - uses: actions/checkout@v4
       - uses: actions/setup-python@v5
         with:
-          python-version: 3.x
-          check-latest: true
+          python-version: '3.x'
+      - uses: actions/setup-python@v5
+        id: setup_freethreaded
+        continue-on-error: true
+        with:
+          python-version: 3.14t
+      - name: Configure maturin interpreters
+        shell: bash
+        run: |
+          INTERP='3.8 3.9 3.10 3.11 3.12 3.13 3.14'
+          if [[ '${{ steps.setup_freethreaded.outcome }}' == 'success' ]]; then
+            INTERP="$INTERP 3.14t"
+          else
+            echo '::warning::Free-threaded Python (3.14t) unavailable from 
setup-python; skipping cp314t wheels this run.'
+          fi
+          echo "MATURIN_INTERPRETERS=$INTERP pypy3.11" >> "$GITHUB_ENV"
       - name: Build wheels
         uses: PyO3/maturin-action@v1
         with:
           target: ${{ matrix.platform.target }}
-          args: --release --out dist -i 3.8 3.9 3.10 3.11 3.12 3.13 3.14 
pypy3.11
+          args: --release --out dist -i ${{ env.MATURIN_INTERPRETERS }}
           sccache: 'true'
           manylinux: musllinux_1_2
       - name: Upload wheels
@@ -98,16 +125,44 @@
             target: x86
     steps:
       - uses: actions/checkout@v4
+      # Windows: install standard CPython only first, run maturin, then add 
3.14t and maturin again.  
+      # 3.13t is not supported by recent PyO3
       - uses: actions/setup-python@v5
         with:
-          python-version: 3.x
+          python-version: |
+            3.8
+            3.9
+            3.10
+            3.11
+            3.12
+            3.13
+            3.14
           architecture: ${{ matrix.platform.target }}
-          check-latest: true
-      - name: Build wheels
+      - name: Configure maturin interpreters (standard CPython)
+        shell: bash
+        run: echo "MATURIN_INTERPRETERS_STD=3.8 3.9 3.10 3.11 3.12 3.13 3.14" 
>> "$GITHUB_ENV"
+      - name: Build wheels (standard CPython)
+        uses: PyO3/maturin-action@v1
+        with:
+          target: ${{ matrix.platform.target }}
+          args: --release --out dist -i ${{ env.MATURIN_INTERPRETERS_STD }}
+          sccache: 'true'
+      - uses: actions/setup-python@v5
+        id: setup_freethreaded
+        continue-on-error: true
+        with:
+          python-version: 3.14t
+          architecture: ${{ matrix.platform.target }}
+      - name: Warn if free-threaded Python unavailable
+        if: steps.setup_freethreaded.outcome != 'success'
+        run: |
+          echo '::warning::Free-threaded Python (3.14t) unavailable from 
setup-python; skipping cp314t wheels this run.'
+      - name: Build wheels (free-threaded)
+        if: steps.setup_freethreaded.outcome == 'success'
         uses: PyO3/maturin-action@v1
         with:
           target: ${{ matrix.platform.target }}
-          args: --release --out dist -i 3.8 3.9 3.10 3.11 3.12 3.13 3.14
+          args: --release --out dist -i  3.14t
           sccache: 'true'
       - name: Upload wheels
         uses: actions/upload-artifact@v4
@@ -120,7 +175,7 @@
     strategy:
       matrix:
         platform:
-          - runner: macos-13
+          - runner: macos-15-intel
             target: x86_64
           - runner: macos-14
             target: aarch64
@@ -129,18 +184,32 @@
       - uses: actions/setup-python@v5
         with:
           python-version: |
-                3.9
-                3.10
-                3.11
-                3.12
-                3.13
-                3.14
-          check-latest: true
+            3.9
+            3.10
+            3.11
+            3.12
+            3.13
+            3.14
+      - uses: actions/setup-python@v5
+        id: setup_freethreaded
+        continue-on-error: true
+        with:
+          python-version: 3.14t
+      - name: Configure maturin interpreters
+        shell: bash
+        run: |
+          INTERP='3.8 3.9 3.10 3.11 3.12 3.13 3.14'
+          if [[ '${{ steps.setup_freethreaded.outcome }}' == 'success' ]]; then
+            INTERP="$INTERP  3.14t"
+          else
+            echo '::warning::Free-threaded Python (3.14t) unavailable from 
setup-python; skipping cp314t wheels this run.'
+          fi
+          echo "MATURIN_INTERPRETERS=$INTERP pypy3.11" >> "$GITHUB_ENV"
       - name: Build wheels
         uses: PyO3/maturin-action@v1
         with:
           target: ${{ matrix.platform.target }}
-          args: --release --out dist -i 3.8 3.9 3.10 3.11 3.12 3.13 3.14 
pypy3.11
+          args: --release --out dist -i ${{ env.MATURIN_INTERPRETERS }}
           sccache: 'true'
       - name: Upload wheels
         uses: actions/upload-artifact@v4
@@ -148,6 +217,42 @@
           name: wheels-macos-${{ matrix.platform.target }}
           path: dist
 
+  free-threaded:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+      # Try 3.14t first. Use outcome (not conclusion) - 3.13t isn't supported: 
continue-on-error leaves conclusion "success"
+      # even when setup fails, but outcome stays "failure" so we can chain 
fallbacks reliably.
+      - uses: actions/setup-python@v5
+        id: py314t
+        continue-on-error: true
+        with:
+          python-version: '3.14t'
+      - name: Resolve free-threaded interpreter
+        id: ft_py
+        run: |
+          ready=false
+          if [[ '${{ steps.py314t.outcome }}' == 'success' ]]; then
+            ready=true
+          fi
+          echo "ready=${ready}" >> "$GITHUB_OUTPUT"
+      - uses: dtolnay/rust-toolchain@stable
+        if: steps.ft_py.outputs.ready == 'true'
+      - uses: astral-sh/setup-uv@v5
+        if: steps.ft_py.outputs.ready == 'true'
+      - name: Install dependencies (uv) and run tests
+        if: steps.ft_py.outputs.ready == 'true'
+        shell: bash
+        run: |
+          set -euo pipefail
+          export UV_PYTHON='${{ steps.py314t.outputs.python-path }}'
+          uv sync --extra dev --locked
+          uv run pytest tests/
+      - name: Free-threaded Python unavailable
+        if: steps.ft_py.outputs.ready != 'true'
+        run: |
+          echo '::notice::No free-threaded Python (3.14t) available from 
setup-python for this runner; skipping extension tests.'
+
   sdist:
     runs-on: ubuntu-latest
     steps:
@@ -167,7 +272,7 @@
     name: Release
     runs-on: ubuntu-latest
     if: "startsWith(github.ref, 'refs/tags/')"
-    needs: [linux, musllinux, windows, macos, sdist]
+    needs: [linux, musllinux, windows, macos, free-threaded, sdist]
     steps:
       - uses: actions/download-artifact@v4
       - name: Publish to PyPI
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python_bidi-0.6.7/AUTHORS.rst 
new/python_bidi-0.6.11/AUTHORS.rst
--- old/python_bidi-0.6.7/AUTHORS.rst   2025-10-22 11:45:34.000000000 +0200
+++ new/python_bidi-0.6.11/AUTHORS.rst  2006-07-24 03:21:28.000000000 +0200
@@ -20,3 +20,4 @@
 * Just van Rossum - https://github.com/justvanrossum
 * Jakub Wilk <[email protected]>
 * Christian Clauss <[email protected]>
+* Jonathan Duncan <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python_bidi-0.6.7/CHANGELOG.rst 
new/python_bidi-0.6.11/CHANGELOG.rst
--- old/python_bidi-0.6.7/CHANGELOG.rst 2025-10-22 11:45:34.000000000 +0200
+++ new/python_bidi-0.6.11/CHANGELOG.rst        2006-07-24 03:21:28.000000000 
+0200
@@ -3,6 +3,31 @@
 
 .. :changelog:
 
+0.6.11
+------
+
+* Bump pyo3 to 0.29.0, drop unsupported 3.13t [Damian Dimmich]
+
+0.6.10
+------
+
+* CI: Windows wheel job builds standard cp313/cp314 wheels reliably by running 
maturin twice (standard Python first, then 3.13t/3.14t), working around 
``win_amd64`` picking only free-threaded 3.13/3.14 when all interpreters share 
``PATH`` [Meir Kriheli]
+
+0.6.9
+-----
+
+* Rust extension declares ``gil_used = false`` so it runs under free-threaded 
(no-GIL) Python [Meir Kriheli]
+* Added concurrent stress test for ``get_display`` under free-threaded builds 
[Meir Kriheli]
+* CI: optional cp313t/cp314t wheel builds when setup-python provides those 
interpreters; free-threaded test job prefers 3.14t with 3.13t fallback [Meir 
Kriheli]
+* CI: Intel macOS wheels now built on macOS 15 (replacing macOS 13) [Meir 
Kriheli]
+* Use ``uv`` for nox virtualenvs; add ``uv.lock`` and document uv-based dev 
setup in README and CONTRIBUTING [Meir Kriheli]
+* Set ``requires-python = ">=3.9"`` explicitly in ``pyproject.toml`` [Meir 
Kriheli]
+
+0.6.8
+-----
+
+* Added missing 3.14 build for Linux (Jonathan Duncan)
+
 0.6.7
 -----
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python_bidi-0.6.7/CONTRIBUTING.rst 
new/python_bidi-0.6.11/CONTRIBUTING.rst
--- old/python_bidi-0.6.7/CONTRIBUTING.rst      2025-10-22 11:45:34.000000000 
+0200
+++ new/python_bidi-0.6.11/CONTRIBUTING.rst     2006-07-24 03:21:28.000000000 
+0200
@@ -57,38 +57,43 @@
 
 Ready to contribute? Here's how to set up `python-bidi` for local development.
 
-1. Fork the `python-bidi` repo on GitHub.
+1. Fork the ``python-bidi`` repo on GitHub.
 2. Clone your fork locally::
 
     $ git clone [email protected]:your_name_here/python-bidi.git
 
-3. Install your local copy into a virtualenv. Assuming you have 
virtualenvwrapper installed, this is how you set up your fork for local 
development::
+3. Install prerequisites:
+
+   * `Rust <https://www.rust-lang.org/tools/install>`_ (the extension is built 
with PyO3 / maturin).
+   * `uv <https://docs.astral.sh/uv/installation/>`_ (Python envs, dependency 
lockfile, and nox’s ``venv_backend="uv"``).
+
+4. In the repo, sync the dev environment and run tests::
 
-    $ mkvirtualenv python-bidi
     $ cd python-bidi/
-    $ python setup.py develop
+    $ uv sync --extra dev
+    $ uv run pytest
 
-4. Create a branch for local development::
+   This uses ``uv.lock`` when present for reproducible installs. To match 
CI-style checks via nox (also using uv under the hood)::
 
-    $ git switch -c name-of-your-bugfix-or-feature
+    $ uv run nox
 
-   Now you can make your changes locally.
+   Alternatively, install nox globally (``uv tool install nox``, ``pipx 
install nox``, etc.) and run ``nox`` from the repo root.
 
-5. When you're done making changes, check that your changes pass flake8 and 
the tests::
+5. Create a branch for local development::
 
-    $ flake8 python-bidi tests
-    $ python setup.py test
-    $ nox
+    $ git switch -c name-of-your-bugfix-or-feature
+
+   Now you can make your changes locally.
 
-   To get ``flake8`` and ``nox``, just pip install them into your virtualenv.
+6. When you're ready, ensure tests still pass (see step 4).
 
-6. Commit your changes and push your branch to GitHub::
+7. Commit your changes and push your branch to GitHub::
 
     $ git add .
     $ git commit -m "Your detailed description of your changes."
     $ git push origin name-of-your-bugfix-or-feature
 
-7. Submit a pull request through the GitHub website.
+8. Submit a pull request through the GitHub website.
 
 Pull Request Guidelines
 -----------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python_bidi-0.6.7/Cargo.lock 
new/python_bidi-0.6.11/Cargo.lock
--- old/python_bidi-0.6.7/Cargo.lock    2025-10-22 11:45:34.000000000 +0200
+++ new/python_bidi-0.6.11/Cargo.lock   2006-07-24 03:21:28.000000000 +0200
@@ -3,55 +3,18 @@
 version = 4
 
 [[package]]
-name = "autocfg"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
-
-[[package]]
-name = "cc"
-version = "1.2.39"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "e1354349954c6fc9cb0deab020f27f783cf0b604e8bb754dc4658ecf0d29c35f"
-dependencies = [
- "find-msvc-tools",
- "shlex",
-]
-
-[[package]]
-name = "find-msvc-tools"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959"
-
-[[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.5"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5"
-
-[[package]]
 name = "libc"
 version = "0.2.155"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
 
 [[package]]
-name = "memoffset"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
 name = "once_cell"
 version = "1.21.3"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -74,36 +37,32 @@
 
 [[package]]
 name = "pyo3"
-version = "0.27.1"
+version = "0.29.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "37a6df7eab65fc7bee654a421404947e10a0f7085b6951bf2ea395f4659fb0cf"
+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.1"
+version = "0.29.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "f77d387774f6f6eec64a004eac0ed525aab7fa1966d94b42f743797b3e395afb"
+checksum = "c5e2a7d2f0d013342f295c048ad19237add5154a55b1c5a254c0ec93d4109078"
 dependencies = [
- "python3-dll-a",
  "target-lexicon",
 ]
 
 [[package]]
 name = "pyo3-ffi"
-version = "0.27.1"
+version = "0.29.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "2dd13844a4242793e02df3e2ec093f540d948299a6a77ea9ce7afd8623f542be"
+checksum = "ca85c467da1bbc8d866eea5deff9cf29ea5f7785054a17da36e65bda9c05845b"
 dependencies = [
  "libc",
  "pyo3-build-config",
@@ -111,9 +70,9 @@
 
 [[package]]
 name = "pyo3-macros"
-version = "0.27.1"
+version = "0.29.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "eaf8f9f1108270b90d3676b8679586385430e5c0bb78bb5f043f95499c821a71"
+checksum = "9ac53762fd065daa3194dd09337a38bd793a188100fd1a9304c4ab312d901771"
 dependencies = [
  "proc-macro2",
  "pyo3-macros-backend",
@@ -123,50 +82,34 @@
 
 [[package]]
 name = "pyo3-macros-backend"
-version = "0.27.1"
+version = "0.29.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "70a3b2274450ba5288bc9b8c1b69ff569d1d61189d4bff38f8d22e03d17f932b"
+checksum = "4ca3a1557399783172dc5bf39cfca835157732532cba56b71d2292161e53b362"
 dependencies = [
  "heck",
  "proc-macro2",
- "pyo3-build-config",
  "quote",
  "syn",
 ]
 
 [[package]]
 name = "python-bidi"
-version = "0.6.7"
+version = "0.6.11"
 dependencies = [
  "pyo3",
  "unicode-bidi",
 ]
 
 [[package]]
-name = "python3-dll-a"
-version = "0.2.14"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "d381ef313ae70b4da5f95f8a4de773c6aa5cd28f73adec4b4a31df70b66780d8"
-dependencies = [
- "cc",
-]
-
-[[package]]
 name = "quote"
-version = "1.0.36"
+version = "1.0.45"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
+checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
 dependencies = [
  "proc-macro2",
 ]
 
 [[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.70"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -194,9 +137,3 @@
 version = "1.0.12"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
-
-[[package]]
-name = "unindent"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python_bidi-0.6.7/Cargo.toml 
new/python_bidi-0.6.11/Cargo.toml
--- old/python_bidi-0.6.7/Cargo.toml    1970-01-01 01:00:00.000000000 +0100
+++ new/python_bidi-0.6.11/Cargo.toml   2006-07-24 03:21:28.000000000 +0200
@@ -1,7 +1,7 @@
 [package]
 authors = ["Meir Kriheli <[email protected]>"]
 name = "python-bidi"
-version = "0.6.7"
+version = "0.6.11"
 edition = "2021"
 
 [lib]
@@ -9,7 +9,7 @@
 crate-type = ["cdylib"]
 
 [dependencies]
-pyo3 = { version = "0.27.1", features = [
+pyo3 = { version = "0.29.0", features = [
     "extension-module",
     "generate-import-lib",
 ] }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python_bidi-0.6.7/PKG-INFO 
new/python_bidi-0.6.11/PKG-INFO
--- old/python_bidi-0.6.7/PKG-INFO      1970-01-01 01:00:00.000000000 +0100
+++ new/python_bidi-0.6.11/PKG-INFO     2006-07-24 03:21:28.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: python-bidi
-Version: 0.6.7
+Version: 0.6.11
 Classifier: Development Status :: 4 - Beta
 Classifier: Intended Audience :: Developers
 Classifier: Operating System :: OS Independent
@@ -13,6 +13,7 @@
 Classifier: Programming Language :: Python :: 3.12
 Classifier: Programming Language :: Python :: 3.13
 Classifier: Programming Language :: Python :: 3.14
+Requires-Dist: nox ; extra == 'dev'
 Requires-Dist: pytest ; extra == 'dev'
 Provides-Extra: dev
 License-File: LICENSE-THIRD-PARTY.yml
@@ -22,12 +23,13 @@
 Summary: Python Bidi layout wrapping the Rust crate unicode-bidi
 Keywords: bidi,unicode,layout
 Author-email: Meir Kriheli <[email protected]>
+Requires-Python: >=3.9
 Description-Content-Type: text/x-rst; charset=UTF-8
-Project-URL: Homepage, https://github.com/MeirKriheli/python-bidi
-Project-URL: Repository, https://github.com/MeirKriheli/python-bidi
+Project-URL: Changelog, 
https://github.com/MeirKriheli/python-bidi/blob/master/CHANGELOG.rst
 Project-URL: Documentation, https://python-bidi.readthedocs.io/en/latest/
+Project-URL: Homepage, https://github.com/MeirKriheli/python-bidi
 Project-URL: Issues, https://github.com/MeirKriheli/python-bidi/issues
-Project-URL: Changelog, 
https://github.com/MeirKriheli/python-bidi/blob/master/CHANGELOG.rst
+Project-URL: Repository, https://github.com/MeirKriheli/python-bidi
 
 ===============================
 Python BiDi
@@ -145,16 +147,26 @@
 Installation
 -------------
 
-At the command line (assuming you're using some virtualenv)::
+From PyPI::
 
     pip install python-bidi
 
+Or with uv::
+
+    uv pip install python-bidi
+
+
+Development / running tests
+-----------------------------
+
+You need Rust (for ``maturin``), `uv <https://docs.astral.sh/uv/>`_, and a 
``nox`` session backend of ``uv`` (nox reads this from ``noxfile.py``).
+
+From a clone, create the environment and run the test suite::
 
-Running tests
---------------
+    uv sync --extra dev
+    uv run pytest
 
-To run the tests::
+Or use nox (after ``uv sync --extra dev``, or install nox with ``uv tool 
install nox`` / ``pipx install nox``)::
 
-    pip install nox
     nox
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python_bidi-0.6.7/README.rst 
new/python_bidi-0.6.11/README.rst
--- old/python_bidi-0.6.7/README.rst    2025-10-22 11:45:34.000000000 +0200
+++ new/python_bidi-0.6.11/README.rst   2006-07-24 03:21:28.000000000 +0200
@@ -114,15 +114,25 @@
 Installation
 -------------
 
-At the command line (assuming you're using some virtualenv)::
+From PyPI::
 
     pip install python-bidi
 
+Or with uv::
 
-Running tests
---------------
+    uv pip install python-bidi
 
-To run the tests::
 
-    pip install nox
+Development / running tests
+-----------------------------
+
+You need Rust (for ``maturin``), `uv <https://docs.astral.sh/uv/>`_, and a 
``nox`` session backend of ``uv`` (nox reads this from ``noxfile.py``).
+
+From a clone, create the environment and run the test suite::
+
+    uv sync --extra dev
+    uv run pytest
+
+Or use nox (after ``uv sync --extra dev``, or install nox with ``uv tool 
install nox`` / ``pipx install nox``)::
+
     nox
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python_bidi-0.6.7/bidi/__init__.py 
new/python_bidi-0.6.11/bidi/__init__.py
--- old/python_bidi-0.6.7/bidi/__init__.py      2025-10-22 11:45:34.000000000 
+0200
+++ new/python_bidi-0.6.11/bidi/__init__.py     2006-07-24 03:21:28.000000000 
+0200
@@ -22,7 +22,7 @@
 
 __all__ = ["get_base_level", "get_display"]
 
-VERSION_TUPLE = (0, 6, 0)
+VERSION_TUPLE = (0, 6, 11)
 VERSION = ".".join(str(x) for x in VERSION_TUPLE)
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python_bidi-0.6.7/noxfile.py 
new/python_bidi-0.6.11/noxfile.py
--- old/python_bidi-0.6.7/noxfile.py    2025-10-22 11:45:34.000000000 +0200
+++ new/python_bidi-0.6.11/noxfile.py   2006-07-24 03:21:28.000000000 +0200
@@ -1,7 +1,7 @@
 import nox
 
 
[email protected]
[email protected](venv_backend="uv")
 def python(session):
     session.env["MATURIN_PEP517_ARGS"] = "--profile=dev"
     session.install(".[dev]")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python_bidi-0.6.7/pyproject.toml 
new/python_bidi-0.6.11/pyproject.toml
--- old/python_bidi-0.6.7/pyproject.toml        2025-10-22 11:45:34.000000000 
+0200
+++ new/python_bidi-0.6.11/pyproject.toml       2006-07-24 03:21:28.000000000 
+0200
@@ -4,7 +4,8 @@
 
 [project]
 name = "python-bidi"
-version = "0.6.7"
+version = "0.6.11"
+requires-python = ">=3.9"
 readme = "README.rst"
 keywords = ["bidi", "unicode", "layout"]
 description = "Python Bidi layout wrapping the Rust crate unicode-bidi"
@@ -35,4 +36,4 @@
 pybidi = "bidi:main"
 
 [project.optional-dependencies]
-dev = ["pytest"]
+dev = ["nox", "pytest"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python_bidi-0.6.7/src/lib.rs 
new/python_bidi-0.6.11/src/lib.rs
--- old/python_bidi-0.6.7/src/lib.rs    2025-10-22 11:45:34.000000000 +0200
+++ new/python_bidi-0.6.11/src/lib.rs   2006-07-24 03:21:28.000000000 +0200
@@ -38,7 +38,7 @@
     Ok(bidi_info.paragraphs[0].level.number())
 }
 
-#[pymodule]
+#[pymodule(gil_used = false)]
 fn bidi(m: &Bound<'_, PyModule>) -> PyResult<()> {
     m.add_function(wrap_pyfunction!(get_display_inner, m)?)?;
     m.add_function(wrap_pyfunction!(get_base_level_inner, m)?)?;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python_bidi-0.6.7/tests/test_free_threaded.py 
new/python_bidi-0.6.11/tests/test_free_threaded.py
--- old/python_bidi-0.6.7/tests/test_free_threaded.py   1970-01-01 
01:00:00.000000000 +0100
+++ new/python_bidi-0.6.11/tests/test_free_threaded.py  2006-07-24 
03:21:28.000000000 +0200
@@ -0,0 +1,40 @@
+# This file is part of python-bidi
+#
+# python-bidi is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""Stress the Rust extension from multiple threads (free-threaded / GIL 
builds)."""
+
+from concurrent.futures import ThreadPoolExecutor, as_completed
+import unittest
+
+from bidi import get_display
+
+HELLO_HEB_LOGICAL = "".join(["ש", "ל", "ו", "ם"])
+HELLO_HEB_DISPLAY = "".join(["ם", "ו", "ל", "ש"])
+
+
+class TestConcurrentRustBidi(unittest.TestCase):
+    """Concurrent calls into the native module."""
+
+    def test_concurrent_get_display(self):
+        text = HELLO_HEB_LOGICAL + " \U0001d7f612"
+        expected = "\U0001d7f612 " + HELLO_HEB_DISPLAY
+
+        def work():
+            return get_display(text)
+
+        with ThreadPoolExecutor(max_workers=8) as pool:
+            futures = [pool.submit(work) for _ in range(64)]
+            for f in as_completed(futures):
+                self.assertEqual(f.result(), expected)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python_bidi-0.6.7/uv.lock 
new/python_bidi-0.6.11/uv.lock
--- old/python_bidi-0.6.7/uv.lock       1970-01-01 01:00:00.000000000 +0100
+++ new/python_bidi-0.6.11/uv.lock      2006-07-24 03:21:28.000000000 +0200
@@ -0,0 +1,356 @@
+version = 1
+revision = 3
+requires-python = ">=3.9"
+resolution-markers = [
+    "python_full_version >= '3.10'",
+    "python_full_version < '3.10'",
+]
+
+[[package]]
+name = "argcomplete"
+version = "3.6.3"
+source = { registry = "https://pypi.org/simple"; }
+sdist = { url = 
"https://files.pythonhosted.org/packages/38/61/0b9ae6399dd4a58d8c1b1dc5a27d6f2808023d0b5dd3104bb99f45a33ff6/argcomplete-3.6.3.tar.gz";,
 hash = 
"sha256:62e8ed4fd6a45864acc8235409461b72c9a28ee785a2011cc5eb78318786c89c", size 
= 73754, upload-time = "2025-10-20T03:33:34.741Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/74/f5/9373290775639cb67a2fce7f629a1c240dce9f12fe927bc32b2736e16dfc/argcomplete-3.6.3-py3-none-any.whl";,
 hash = 
"sha256:f5007b3a600ccac5d25bbce33089211dfd49eab4a7718da3f10e3082525a92ce", size 
= 43846, upload-time = "2025-10-20T03:33:33.021Z" },
+]
+
+[[package]]
+name = "attrs"
+version = "26.1.0"
+source = { registry = "https://pypi.org/simple"; }
+sdist = { url = 
"https://files.pythonhosted.org/packages/9a/8e/82a0fe20a541c03148528be8cac2408564a6c9a0cc7e9171802bc1d26985/attrs-26.1.0.tar.gz";,
 hash = 
"sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32", size 
= 952055, upload-time = "2026-03-19T14:22:25.026Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl";,
 hash = 
"sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309", size 
= 67548, upload-time = "2026-03-19T14:22:23.645Z" },
+]
+
+[[package]]
+name = "colorama"
+version = "0.4.6"
+source = { registry = "https://pypi.org/simple"; }
+sdist = { url = 
"https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz";,
 hash = 
"sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size 
= 27697, upload-time = "2022-10-25T02:36:22.414Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl";,
 hash = 
"sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size 
= 25335, upload-time = "2022-10-25T02:36:20.889Z" },
+]
+
+[[package]]
+name = "colorlog"
+version = "6.10.1"
+source = { registry = "https://pypi.org/simple"; }
+dependencies = [
+    { name = "colorama", marker = "sys_platform == 'win32'" },
+]
+sdist = { url = 
"https://files.pythonhosted.org/packages/a2/61/f083b5ac52e505dfc1c624eafbf8c7589a0d7f32daa398d2e7590efa5fda/colorlog-6.10.1.tar.gz";,
 hash = 
"sha256:eb4ae5cb65fe7fec7773c2306061a8e63e02efc2c72eba9d27b0fa23c94f1321", size 
= 17162, upload-time = "2025-10-16T16:14:11.978Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/6d/c1/e419ef3723a074172b68aaa89c9f3de486ed4c2399e2dbd8113a4fdcaf9e/colorlog-6.10.1-py3-none-any.whl";,
 hash = 
"sha256:2d7e8348291948af66122cff006c9f8da6255d224e7cf8e37d8de2df3bad8c9c", size 
= 11743, upload-time = "2025-10-16T16:14:10.512Z" },
+]
+
+[[package]]
+name = "dependency-groups"
+version = "1.3.1"
+source = { registry = "https://pypi.org/simple"; }
+dependencies = [
+    { name = "packaging" },
+    { name = "tomli", marker = "python_full_version < '3.11'" },
+]
+sdist = { url = 
"https://files.pythonhosted.org/packages/62/55/f054de99871e7beb81935dea8a10b90cd5ce42122b1c3081d5282fdb3621/dependency_groups-1.3.1.tar.gz";,
 hash = 
"sha256:78078301090517fd938c19f64a53ce98c32834dfe0dee6b88004a569a6adfefd", size 
= 10093, upload-time = "2025-05-02T00:34:29.452Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/99/c7/d1ec24fb280caa5a79b6b950db565dab30210a66259d17d5bb2b3a9f878d/dependency_groups-1.3.1-py3-none-any.whl";,
 hash = 
"sha256:51aeaa0dfad72430fcfb7bcdbefbd75f3792e5919563077f30bc0d73f4493030", size 
= 8664, upload-time = "2025-05-02T00:34:27.085Z" },
+]
+
+[[package]]
+name = "distlib"
+version = "0.4.0"
+source = { registry = "https://pypi.org/simple"; }
+sdist = { url = 
"https://files.pythonhosted.org/packages/96/8e/709914eb2b5749865801041647dc7f4e6d00b549cfe88b65ca192995f07c/distlib-0.4.0.tar.gz";,
 hash = 
"sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d", size 
= 614605, upload-time = "2025-07-17T16:52:00.465Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl";,
 hash = 
"sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", size 
= 469047, upload-time = "2025-07-17T16:51:58.613Z" },
+]
+
+[[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 = "filelock"
+version = "3.19.1"
+source = { registry = "https://pypi.org/simple"; }
+resolution-markers = [
+    "python_full_version < '3.10'",
+]
+sdist = { url = 
"https://files.pythonhosted.org/packages/40/bb/0ab3e58d22305b6f5440629d20683af28959bf793d98d11950e305c1c326/filelock-3.19.1.tar.gz";,
 hash = 
"sha256:66eda1888b0171c998b35be2bcc0f6d75c388a7ce20c3f3f37aa8e96c2dddf58", size 
= 17687, upload-time = "2025-08-14T16:56:03.016Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/42/14/42b2651a2f46b022ccd948bca9f2d5af0fd8929c4eec235b8d6d844fbe67/filelock-3.19.1-py3-none-any.whl";,
 hash = 
"sha256:d38e30481def20772f5baf097c122c3babc4fcdb7e14e57049eb9d88c6dc017d", size 
= 15988, upload-time = "2025-08-14T16:56:01.633Z" },
+]
+
+[[package]]
+name = "filelock"
+version = "3.29.0"
+source = { registry = "https://pypi.org/simple"; }
+resolution-markers = [
+    "python_full_version >= '3.10'",
+]
+sdist = { url = 
"https://files.pythonhosted.org/packages/b5/fe/997687a931ab51049acce6fa1f23e8f01216374ea81374ddee763c493db5/filelock-3.29.0.tar.gz";,
 hash = 
"sha256:69974355e960702e789734cb4871f884ea6fe50bd8404051a3530bc07809cf90", size 
= 57571, upload-time = "2026-04-19T15:39:10.068Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl";,
 hash = 
"sha256:96f5f6344709aa1572bbf631c640e4ebeeb519e08da902c39a001882f30ac258", size 
= 39812, upload-time = "2026-04-19T15:39:08.752Z" },
+]
+
+[[package]]
+name = "humanize"
+version = "4.13.0"
+source = { registry = "https://pypi.org/simple"; }
+resolution-markers = [
+    "python_full_version < '3.10'",
+]
+sdist = { url = 
"https://files.pythonhosted.org/packages/98/1d/3062fcc89ee05a715c0b9bfe6490c00c576314f27ffee3a704122c6fd259/humanize-4.13.0.tar.gz";,
 hash = 
"sha256:78f79e68f76f0b04d711c4e55d32bebef5be387148862cb1ef83d2b58e7935a0", size 
= 81884, upload-time = "2025-08-25T09:39:20.04Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/1e/c7/316e7ca04d26695ef0635dc81683d628350810eb8e9b2299fc08ba49f366/humanize-4.13.0-py3-none-any.whl";,
 hash = 
"sha256:b810820b31891813b1673e8fec7f1ed3312061eab2f26e3fa192c393d11ed25f", size 
= 128869, upload-time = "2025-08-25T09:39:18.54Z" },
+]
+
+[[package]]
+name = "humanize"
+version = "4.15.0"
+source = { registry = "https://pypi.org/simple"; }
+resolution-markers = [
+    "python_full_version >= '3.10'",
+]
+sdist = { url = 
"https://files.pythonhosted.org/packages/ba/66/a3921783d54be8a6870ac4ccffcd15c4dc0dd7fcce51c6d63b8c63935276/humanize-4.15.0.tar.gz";,
 hash = 
"sha256:1dd098483eb1c7ee8e32eb2e99ad1910baefa4b75c3aff3a82f4d78688993b10", size 
= 83599, upload-time = "2025-12-20T20:16:13.19Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/c5/7b/bca5613a0c3b542420cf92bd5e5fb8ebd5435ce1011a091f66bb7693285e/humanize-4.15.0-py3-none-any.whl";,
 hash = 
"sha256:b1186eb9f5a9749cd9cb8565aee77919dd7c8d076161cf44d70e59e3301e1769", size 
= 132203, upload-time = "2025-12-20T20:16:11.67Z" },
+]
+
+[[package]]
+name = "iniconfig"
+version = "2.1.0"
+source = { registry = "https://pypi.org/simple"; }
+resolution-markers = [
+    "python_full_version < '3.10'",
+]
+sdist = { url = 
"https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz";,
 hash = 
"sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size 
= 4793, upload-time = "2025-03-19T20:09:59.721Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl";,
 hash = 
"sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size 
= 6050, upload-time = "2025-03-19T20:10:01.071Z" },
+]
+
+[[package]]
+name = "iniconfig"
+version = "2.3.0"
+source = { registry = "https://pypi.org/simple"; }
+resolution-markers = [
+    "python_full_version >= '3.10'",
+]
+sdist = { url = 
"https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz";,
 hash = 
"sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size 
= 20503, upload-time = "2025-10-18T21:55:43.219Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl";,
 hash = 
"sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size 
= 7484, upload-time = "2025-10-18T21:55:41.639Z" },
+]
+
+[[package]]
+name = "nox"
+version = "2026.4.10"
+source = { registry = "https://pypi.org/simple"; }
+dependencies = [
+    { name = "argcomplete" },
+    { name = "attrs" },
+    { name = "colorlog" },
+    { name = "dependency-groups" },
+    { name = "humanize", version = "4.13.0", source = { registry = 
"https://pypi.org/simple"; }, marker = "python_full_version < '3.10'" },
+    { name = "humanize", version = "4.15.0", source = { registry = 
"https://pypi.org/simple"; }, marker = "python_full_version >= '3.10'" },
+    { name = "packaging" },
+    { name = "tomli", marker = "python_full_version < '3.11'" },
+    { name = "virtualenv" },
+]
+sdist = { url = 
"https://files.pythonhosted.org/packages/e7/6b/e672c862a43cfca704d32359221fa3780226daa1e5db5dfc401bcc8be9c9/nox-2026.4.10.tar.gz";,
 hash = 
"sha256:2d0af5374f3f37a295428c927d1b04a8182aa01762897d172446dda2f1ce9692", size 
= 4034839, upload-time = "2026-04-10T17:42:42.209Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/7f/95/4df134a100b5a9a12378d5301b934366686ef6fbdaffcd21211d5654970e/nox-2026.4.10-py3-none-any.whl";,
 hash = 
"sha256:082c117627590d9b90aa21f86df89b310b07c5842539524203bcb3c719f116c1", size 
= 75536, upload-time = "2026-04-10T17:42:40.664Z" },
+]
+
+[[package]]
+name = "packaging"
+version = "25.0"
+source = { registry = "https://pypi.org/simple"; }
+sdist = { url = 
"https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz";,
 hash = 
"sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size 
= 165727, upload-time = "2025-04-19T11:48:59.673Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl";,
 hash = 
"sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size 
= 66469, upload-time = "2025-04-19T11:48:57.875Z" },
+]
+
+[[package]]
+name = "platformdirs"
+version = "4.4.0"
+source = { registry = "https://pypi.org/simple"; }
+resolution-markers = [
+    "python_full_version < '3.10'",
+]
+sdist = { url = 
"https://files.pythonhosted.org/packages/23/e8/21db9c9987b0e728855bd57bff6984f67952bea55d6f75e055c46b5383e8/platformdirs-4.4.0.tar.gz";,
 hash = 
"sha256:ca753cf4d81dc309bc67b0ea38fd15dc97bc30ce419a7f58d13eb3bf14c4febf", size 
= 21634, upload-time = "2025-08-26T14:32:04.268Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/40/4b/2028861e724d3bd36227adfa20d3fd24c3fc6d52032f4a93c133be5d17ce/platformdirs-4.4.0-py3-none-any.whl";,
 hash = 
"sha256:abd01743f24e5287cd7a5db3752faf1a2d65353f38ec26d98e25a6db65958c85", size 
= 18654, upload-time = "2025-08-26T14:32:02.735Z" },
+]
+
+[[package]]
+name = "platformdirs"
+version = "4.9.6"
+source = { registry = "https://pypi.org/simple"; }
+resolution-markers = [
+    "python_full_version >= '3.10'",
+]
+sdist = { url = 
"https://files.pythonhosted.org/packages/9f/4a/0883b8e3802965322523f0b200ecf33d31f10991d0401162f4b23c698b42/platformdirs-4.9.6.tar.gz";,
 hash = 
"sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a", size 
= 29400, upload-time = "2026-04-09T00:04:10.812Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/75/a6/a0a304dc33b49145b21f4808d763822111e67d1c3a32b524a1baf947b6e1/platformdirs-4.9.6-py3-none-any.whl";,
 hash = 
"sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917", size 
= 21348, upload-time = "2026-04-09T00:04:09.463Z" },
+]
+
+[[package]]
+name = "pluggy"
+version = "1.6.0"
+source = { registry = "https://pypi.org/simple"; }
+sdist = { url = 
"https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz";,
 hash = 
"sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size 
= 69412, upload-time = "2025-05-15T12:30:07.975Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl";,
 hash = 
"sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size 
= 20538, upload-time = "2025-05-15T12:30:06.134Z" },
+]
+
+[[package]]
+name = "pygments"
+version = "2.19.2"
+source = { registry = "https://pypi.org/simple"; }
+sdist = { url = 
"https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz";,
 hash = 
"sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size 
= 4968631, upload-time = "2025-06-21T13:39:12.283Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl";,
 hash = 
"sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size 
= 1225217, upload-time = "2025-06-21T13:39:07.939Z" },
+]
+
+[[package]]
+name = "pytest"
+version = "8.4.2"
+source = { registry = "https://pypi.org/simple"; }
+dependencies = [
+    { name = "colorama", marker = "sys_platform == 'win32'" },
+    { name = "exceptiongroup", marker = "python_full_version < '3.11'" },
+    { name = "iniconfig", version = "2.1.0", source = { registry = 
"https://pypi.org/simple"; }, marker = "python_full_version < '3.10'" },
+    { name = "iniconfig", version = "2.3.0", source = { registry = 
"https://pypi.org/simple"; }, marker = "python_full_version >= '3.10'" },
+    { name = "packaging" },
+    { name = "pluggy" },
+    { name = "pygments" },
+    { name = "tomli", marker = "python_full_version < '3.11'" },
+]
+sdist = { url = 
"https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz";,
 hash = 
"sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size 
= 1519618, upload-time = "2025-09-04T14:34:22.711Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl";,
 hash = 
"sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size 
= 365750, upload-time = "2025-09-04T14:34:20.226Z" },
+]
+
+[[package]]
+name = "python-bidi"
+version = "0.6.11"
+source = { editable = "." }
+
+[package.optional-dependencies]
+dev = [
+    { name = "nox" },
+    { name = "pytest" },
+]
+
+[package.metadata]
+requires-dist = [
+    { name = "nox", marker = "extra == 'dev'" },
+    { name = "pytest", marker = "extra == 'dev'" },
+]
+provides-extras = ["dev"]
+
+[[package]]
+name = "python-discovery"
+version = "1.2.2"
+source = { registry = "https://pypi.org/simple"; }
+dependencies = [
+    { name = "filelock", version = "3.19.1", source = { registry = 
"https://pypi.org/simple"; }, marker = "python_full_version < '3.10'" },
+    { name = "filelock", version = "3.29.0", source = { registry = 
"https://pypi.org/simple"; }, marker = "python_full_version >= '3.10'" },
+    { name = "platformdirs", version = "4.4.0", source = { registry = 
"https://pypi.org/simple"; }, marker = "python_full_version < '3.10'" },
+    { name = "platformdirs", version = "4.9.6", source = { registry = 
"https://pypi.org/simple"; }, marker = "python_full_version >= '3.10'" },
+]
+sdist = { url = 
"https://files.pythonhosted.org/packages/de/ef/3bae0e537cfe91e8431efcba4434463d2c5a65f5a89edd47c6cf2f03c55f/python_discovery-1.2.2.tar.gz";,
 hash = 
"sha256:876e9c57139eb757cb5878cbdd9ae5379e5d96266c99ef731119e04fffe533bb", size 
= 58872, upload-time = "2026-04-07T17:28:49.249Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/d8/db/795879cc3ddfe338599bddea6388cc5100b088db0a4caf6e6c1af1c27e04/python_discovery-1.2.2-py3-none-any.whl";,
 hash = 
"sha256:e1ae95d9af875e78f15e19aed0c6137ab1bb49c200f21f5061786490c9585c7a", size 
= 31894, upload-time = "2026-04-07T17:28:48.09Z" },
+]
+
+[[package]]
+name = "tomli"
+version = "2.4.1"
+source = { registry = "https://pypi.org/simple"; }
+sdist = { url = 
"https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz";,
 hash = 
"sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size 
= 17543, upload-time = "2026-03-25T20:22:03.828Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/f4/11/db3d5885d8528263d8adc260bb2d28ebf1270b96e98f0e0268d32b8d9900/tomli-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl";,
 hash = 
"sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30", size 
= 154704, upload-time = "2026-03-25T20:21:10.473Z" },
+    { url = 
"https://files.pythonhosted.org/packages/6d/f7/675db52c7e46064a9aa928885a9b20f4124ecb9bc2e1ce74c9106648d202/tomli-2.4.1-cp311-cp311-macosx_11_0_arm64.whl";,
 hash = 
"sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a", size 
= 149454, upload-time = "2026-03-25T20:21:12.036Z" },
+    { url = 
"https://files.pythonhosted.org/packages/61/71/81c50943cf953efa35bce7646caab3cf457a7d8c030b27cfb40d7235f9ee/tomli-2.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076", size 
= 237561, upload-time = "2026-03-25T20:21:13.098Z" },
+    { url = 
"https://files.pythonhosted.org/packages/48/c1/f41d9cb618acccca7df82aaf682f9b49013c9397212cb9f53219e3abac37/tomli-2.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9", size 
= 243824, upload-time = "2026-03-25T20:21:14.569Z" },
+    { url = 
"https://files.pythonhosted.org/packages/22/e4/5a816ecdd1f8ca51fb756ef684b90f2780afc52fc67f987e3c61d800a46d/tomli-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl";,
 hash = 
"sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c", size 
= 242227, upload-time = "2026-03-25T20:21:15.712Z" },
+    { url = 
"https://files.pythonhosted.org/packages/6b/49/2b2a0ef529aa6eec245d25f0c703e020a73955ad7edf73e7f54ddc608aa5/tomli-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc", size 
= 247859, upload-time = "2026-03-25T20:21:17.001Z" },
+    { url = 
"https://files.pythonhosted.org/packages/83/bd/6c1a630eaca337e1e78c5903104f831bda934c426f9231429396ce3c3467/tomli-2.4.1-cp311-cp311-win32.whl";,
 hash = 
"sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049", size 
= 97204, upload-time = "2026-03-25T20:21:18.079Z" },
+    { url = 
"https://files.pythonhosted.org/packages/42/59/71461df1a885647e10b6bb7802d0b8e66480c61f3f43079e0dcd315b3954/tomli-2.4.1-cp311-cp311-win_amd64.whl";,
 hash = 
"sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e", size 
= 108084, upload-time = "2026-03-25T20:21:18.978Z" },
+    { url = 
"https://files.pythonhosted.org/packages/b8/83/dceca96142499c069475b790e7913b1044c1a4337e700751f48ed723f883/tomli-2.4.1-cp311-cp311-win_arm64.whl";,
 hash = 
"sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece", size 
= 95285, upload-time = "2026-03-25T20:21:20.309Z" },
+    { url = 
"https://files.pythonhosted.org/packages/c1/ba/42f134a3fe2b370f555f44b1d72feebb94debcab01676bf918d0cb70e9aa/tomli-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl";,
 hash = 
"sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a", size 
= 155924, upload-time = "2026-03-25T20:21:21.626Z" },
+    { url = 
"https://files.pythonhosted.org/packages/dc/c7/62d7a17c26487ade21c5422b646110f2162f1fcc95980ef7f63e73c68f14/tomli-2.4.1-cp312-cp312-macosx_11_0_arm64.whl";,
 hash = 
"sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085", size 
= 150018, upload-time = "2026-03-25T20:21:23.002Z" },
+    { url = 
"https://files.pythonhosted.org/packages/5c/05/79d13d7c15f13bdef410bdd49a6485b1c37d28968314eabee452c22a7fda/tomli-2.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9", size 
= 244948, upload-time = "2026-03-25T20:21:24.04Z" },
+    { url = 
"https://files.pythonhosted.org/packages/10/90/d62ce007a1c80d0b2c93e02cab211224756240884751b94ca72df8a875ca/tomli-2.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5", size 
= 253341, upload-time = "2026-03-25T20:21:25.177Z" },
+    { url = 
"https://files.pythonhosted.org/packages/1a/7e/caf6496d60152ad4ed09282c1885cca4eea150bfd007da84aea07bcc0a3e/tomli-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl";,
 hash = 
"sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585", size 
= 248159, upload-time = "2026-03-25T20:21:26.364Z" },
+    { url = 
"https://files.pythonhosted.org/packages/99/e7/c6f69c3120de34bbd882c6fba7975f3d7a746e9218e56ab46a1bc4b42552/tomli-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1", size 
= 253290, upload-time = "2026-03-25T20:21:27.46Z" },
+    { url = 
"https://files.pythonhosted.org/packages/d6/2f/4a3c322f22c5c66c4b836ec58211641a4067364f5dcdd7b974b4c5da300c/tomli-2.4.1-cp312-cp312-win32.whl";,
 hash = 
"sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917", size 
= 98141, upload-time = "2026-03-25T20:21:28.492Z" },
+    { url = 
"https://files.pythonhosted.org/packages/24/22/4daacd05391b92c55759d55eaee21e1dfaea86ce5c571f10083360adf534/tomli-2.4.1-cp312-cp312-win_amd64.whl";,
 hash = 
"sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9", size 
= 108847, upload-time = "2026-03-25T20:21:29.386Z" },
+    { url = 
"https://files.pythonhosted.org/packages/68/fd/70e768887666ddd9e9f5d85129e84910f2db2796f9096aa02b721a53098d/tomli-2.4.1-cp312-cp312-win_arm64.whl";,
 hash = 
"sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257", size 
= 95088, upload-time = "2026-03-25T20:21:30.677Z" },
+    { url = 
"https://files.pythonhosted.org/packages/07/06/b823a7e818c756d9a7123ba2cda7d07bc2dd32835648d1a7b7b7a05d848d/tomli-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl";,
 hash = 
"sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54", size 
= 155866, upload-time = "2026-03-25T20:21:31.65Z" },
+    { url = 
"https://files.pythonhosted.org/packages/14/6f/12645cf7f08e1a20c7eb8c297c6f11d31c1b50f316a7e7e1e1de6e2e7b7e/tomli-2.4.1-cp313-cp313-macosx_11_0_arm64.whl";,
 hash = 
"sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a", size 
= 149887, upload-time = "2026-03-25T20:21:33.028Z" },
+    { url = 
"https://files.pythonhosted.org/packages/5c/e0/90637574e5e7212c09099c67ad349b04ec4d6020324539297b634a0192b0/tomli-2.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897", size 
= 243704, upload-time = "2026-03-25T20:21:34.51Z" },
+    { url = 
"https://files.pythonhosted.org/packages/10/8f/d3ddb16c5a4befdf31a23307f72828686ab2096f068eaf56631e136c1fdd/tomli-2.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f", size 
= 251628, upload-time = "2026-03-25T20:21:36.012Z" },
+    { url = 
"https://files.pythonhosted.org/packages/e3/f1/dbeeb9116715abee2485bf0a12d07a8f31af94d71608c171c45f64c0469d/tomli-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl";,
 hash = 
"sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d", size 
= 247180, upload-time = "2026-03-25T20:21:37.136Z" },
+    { url = 
"https://files.pythonhosted.org/packages/d3/74/16336ffd19ed4da28a70959f92f506233bd7cfc2332b20bdb01591e8b1d1/tomli-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5", size 
= 251674, upload-time = "2026-03-25T20:21:38.298Z" },
+    { url = 
"https://files.pythonhosted.org/packages/16/f9/229fa3434c590ddf6c0aa9af64d3af4b752540686cace29e6281e3458469/tomli-2.4.1-cp313-cp313-win32.whl";,
 hash = 
"sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd", size 
= 97976, upload-time = "2026-03-25T20:21:39.316Z" },
+    { url = 
"https://files.pythonhosted.org/packages/6a/1e/71dfd96bcc1c775420cb8befe7a9d35f2e5b1309798f009dca17b7708c1e/tomli-2.4.1-cp313-cp313-win_amd64.whl";,
 hash = 
"sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36", size 
= 108755, upload-time = "2026-03-25T20:21:40.248Z" },
+    { url = 
"https://files.pythonhosted.org/packages/83/7a/d34f422a021d62420b78f5c538e5b102f62bea616d1d75a13f0a88acb04a/tomli-2.4.1-cp313-cp313-win_arm64.whl";,
 hash = 
"sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd", size 
= 95265, upload-time = "2026-03-25T20:21:41.219Z" },
+    { url = 
"https://files.pythonhosted.org/packages/3c/fb/9a5c8d27dbab540869f7c1f8eb0abb3244189ce780ba9cd73f3770662072/tomli-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl";,
 hash = 
"sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf", size 
= 155726, upload-time = "2026-03-25T20:21:42.23Z" },
+    { url = 
"https://files.pythonhosted.org/packages/62/05/d2f816630cc771ad836af54f5001f47a6f611d2d39535364f148b6a92d6b/tomli-2.4.1-cp314-cp314-macosx_11_0_arm64.whl";,
 hash = 
"sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac", size 
= 149859, upload-time = "2026-03-25T20:21:43.386Z" },
+    { url = 
"https://files.pythonhosted.org/packages/ce/48/66341bdb858ad9bd0ceab5a86f90eddab127cf8b046418009f2125630ecb/tomli-2.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662", size 
= 244713, upload-time = "2026-03-25T20:21:44.474Z" },
+    { url = 
"https://files.pythonhosted.org/packages/df/6d/c5fad00d82b3c7a3ab6189bd4b10e60466f22cfe8a08a9394185c8a8111c/tomli-2.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853", size 
= 252084, upload-time = "2026-03-25T20:21:45.62Z" },
+    { url = 
"https://files.pythonhosted.org/packages/00/71/3a69e86f3eafe8c7a59d008d245888051005bd657760e96d5fbfb0b740c2/tomli-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl";,
 hash = 
"sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15", size 
= 247973, upload-time = "2026-03-25T20:21:46.937Z" },
+    { url = 
"https://files.pythonhosted.org/packages/67/50/361e986652847fec4bd5e4a0208752fbe64689c603c7ae5ea7cb16b1c0ca/tomli-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba", size 
= 256223, upload-time = "2026-03-25T20:21:48.467Z" },
+    { url = 
"https://files.pythonhosted.org/packages/8c/9a/b4173689a9203472e5467217e0154b00e260621caa227b6fa01feab16998/tomli-2.4.1-cp314-cp314-win32.whl";,
 hash = 
"sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6", size 
= 98973, upload-time = "2026-03-25T20:21:49.526Z" },
+    { url = 
"https://files.pythonhosted.org/packages/14/58/640ac93bf230cd27d002462c9af0d837779f8773bc03dee06b5835208214/tomli-2.4.1-cp314-cp314-win_amd64.whl";,
 hash = 
"sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7", size 
= 109082, upload-time = "2026-03-25T20:21:50.506Z" },
+    { url = 
"https://files.pythonhosted.org/packages/d5/2f/702d5e05b227401c1068f0d386d79a589bb12bf64c3d2c72ce0631e3bc49/tomli-2.4.1-cp314-cp314-win_arm64.whl";,
 hash = 
"sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232", size 
= 96490, upload-time = "2026-03-25T20:21:51.474Z" },
+    { url = 
"https://files.pythonhosted.org/packages/45/4b/b877b05c8ba62927d9865dd980e34a755de541eb65fffba52b4cc495d4d2/tomli-2.4.1-cp314-cp314t-macosx_10_15_x86_64.whl";,
 hash = 
"sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4", size 
= 164263, upload-time = "2026-03-25T20:21:52.543Z" },
+    { url = 
"https://files.pythonhosted.org/packages/24/79/6ab420d37a270b89f7195dec5448f79400d9e9c1826df982f3f8e97b24fd/tomli-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl";,
 hash = 
"sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c", size 
= 160736, upload-time = "2026-03-25T20:21:53.674Z" },
+    { url = 
"https://files.pythonhosted.org/packages/02/e0/3630057d8eb170310785723ed5adcdfb7d50cb7e6455f85ba8a3deed642b/tomli-2.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d", size 
= 270717, upload-time = "2026-03-25T20:21:55.129Z" },
+    { url = 
"https://files.pythonhosted.org/packages/7a/b4/1613716072e544d1a7891f548d8f9ec6ce2faf42ca65acae01d76ea06bb0/tomli-2.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41", size 
= 278461, upload-time = "2026-03-25T20:21:56.228Z" },
+    { url = 
"https://files.pythonhosted.org/packages/05/38/30f541baf6a3f6df77b3df16b01ba319221389e2da59427e221ef417ac0c/tomli-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl";,
 hash = 
"sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c", size 
= 274855, upload-time = "2026-03-25T20:21:57.653Z" },
+    { url = 
"https://files.pythonhosted.org/packages/77/a3/ec9dd4fd2c38e98de34223b995a3b34813e6bdadf86c75314c928350ed14/tomli-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f", size 
= 283144, upload-time = "2026-03-25T20:21:59.089Z" },
+    { url = 
"https://files.pythonhosted.org/packages/ef/be/605a6261cac79fba2ec0c9827e986e00323a1945700969b8ee0b30d85453/tomli-2.4.1-cp314-cp314t-win32.whl";,
 hash = 
"sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8", size 
= 108683, upload-time = "2026-03-25T20:22:00.214Z" },
+    { url = 
"https://files.pythonhosted.org/packages/12/64/da524626d3b9cc40c168a13da8335fe1c51be12c0a63685cc6db7308daae/tomli-2.4.1-cp314-cp314t-win_amd64.whl";,
 hash = 
"sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26", size 
= 121196, upload-time = "2026-03-25T20:22:01.169Z" },
+    { url = 
"https://files.pythonhosted.org/packages/5a/cd/e80b62269fc78fc36c9af5a6b89c835baa8af28ff5ad28c7028d60860320/tomli-2.4.1-cp314-cp314t-win_arm64.whl";,
 hash = 
"sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396", size 
= 100393, upload-time = "2026-03-25T20:22:02.137Z" },
+    { url = 
"https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl";,
 hash = 
"sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size 
= 14583, upload-time = "2026-03-25T20:22:03.012Z" },
+]
+
+[[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 = "virtualenv"
+version = "21.3.1"
+source = { registry = "https://pypi.org/simple"; }
+dependencies = [
+    { name = "distlib" },
+    { name = "filelock", version = "3.19.1", source = { registry = 
"https://pypi.org/simple"; }, marker = "python_full_version < '3.10'" },
+    { name = "filelock", version = "3.29.0", source = { registry = 
"https://pypi.org/simple"; }, marker = "python_full_version >= '3.10'" },
+    { name = "platformdirs", version = "4.4.0", source = { registry = 
"https://pypi.org/simple"; }, marker = "python_full_version < '3.10'" },
+    { name = "platformdirs", version = "4.9.6", source = { registry = 
"https://pypi.org/simple"; }, marker = "python_full_version >= '3.10'" },
+    { name = "python-discovery" },
+    { name = "typing-extensions", marker = "python_full_version < '3.11'" },
+]
+sdist = { url = 
"https://files.pythonhosted.org/packages/ec/0d/915c02c94d207b85580eb09bffab54438a709e7288524094fe781da526c2/virtualenv-21.3.1.tar.gz";,
 hash = 
"sha256:c2305bc1fddeec40699b8370d13f8d431b0701f00ce895061ce493aeded4426b", size 
= 7613791, upload-time = "2026-05-05T01:34:31.402Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/b1/4f/f71e641e504111a5a74e3a20bc52d01bd86788b22699dd3fee1c63253cf6/virtualenv-21.3.1-py3-none-any.whl";,
 hash = 
"sha256:d1a71cf58f2f9228fff23a1f6ec15d39785c6b32e03658d104974247145edd35", size 
= 7594539, upload-time = "2026-05-05T01:34:28.98Z" },
+]

++++++ vendor.tar.xz ++++++
++++ 815754 lines of diff (skipped)

Reply via email to