This is an automated email from the ASF dual-hosted git repository.

tison pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/libcloud.git


The following commit(s) were added to refs/heads/trunk by this push:
     new bf6b29b86 Move dev deps from extras to uv dependency groups (#2102)
bf6b29b86 is described below

commit bf6b29b864c5f6f35b9e8d45d27f0b407ad84c2c
Author: Chojan Shang <[email protected]>
AuthorDate: Tue Jan 27 19:06:51 2026 +0800

    Move dev deps from extras to uv dependency groups (#2102)
---
 .github/workflows/integration-tests.yml     |   4 +-
 .github/workflows/main.yml                  |  31 +++--
 .github/workflows/publish_dev_artifact.yml  |   2 +-
 .github/workflows/publish_pricing_to_s3.yml |   2 +-
 .readthedocs.yml                            |  16 ++-
 docs/committer_guide.rst                    |   4 +-
 docs/development.rst                        |  21 ++--
 docs/testing.rst                            |   6 +-
 integration/compute/README.rst              |   2 +-
 integration/storage/README.rst              |   2 +-
 pyproject.toml                              |  20 +--
 tox.ini                                     |  74 ++++++-----
 uv.lock                                     | 182 +++++++++++++++++++---------
 13 files changed, 225 insertions(+), 141 deletions(-)

diff --git a/.github/workflows/integration-tests.yml 
b/.github/workflows/integration-tests.yml
index 5fce85cb4..09a7f3f14 100644
--- a/.github/workflows/integration-tests.yml
+++ b/.github/workflows/integration-tests.yml
@@ -44,7 +44,7 @@ jobs:
       - name: Install OS / deb dependencies
         run: |
           sudo DEBIAN_FRONTEND=noninteractive apt-get update
-          sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq gcc 
libvirt-dev
+          sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq gcc 
libvirt-dev pkg-config
 
       - name: Cache uv
         uses: actions/cache@v5
@@ -56,7 +56,7 @@ jobs:
 
       - name: Install Python Dependencies
         run: |
-          uv sync --extra ci
+          uv sync --group ci --no-dev
           echo "${GITHUB_WORKSPACE}/.venv/bin" >> "$GITHUB_PATH"
 
       - name: Run tox target
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 87a55e084..468a9b310 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -53,7 +53,7 @@ jobs:
       - name: Install OS / deb dependencies
         run: |
           sudo DEBIAN_FRONTEND=noninteractive apt-get update
-          sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq gcc 
libvirt-dev
+          sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq gcc 
libvirt-dev pkg-config
 
       - name: Cache uv
         uses: actions/cache@v5
@@ -64,7 +64,7 @@ jobs:
             ${{ runner.os }}-uv-
 
       - name: Install Python Dependencies
-        run: uv sync --extra ci
+        run: uv sync --group ci --no-dev
 
       - name: Add .venv to PATH
         run: echo "${GITHUB_WORKSPACE}/.venv/bin" >> "$GITHUB_PATH"
@@ -96,7 +96,7 @@ jobs:
       - name: Install OS / deb dependencies
         run: |
           sudo DEBIAN_FRONTEND=noninteractive apt-get update
-          sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq graphviz gcc 
libvirt-dev
+          sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq graphviz gcc 
libvirt-dev pkg-config
 
       - name: Cache uv
         uses: actions/cache@v5
@@ -107,7 +107,7 @@ jobs:
             ${{ runner.os }}-uv-
 
       - name: Install Python Dependencies
-        run: uv sync --extra ci
+        run: uv sync --group ci --no-dev
 
       - name: Add .venv to PATH
         run: echo "${GITHUB_WORKSPACE}/.venv/bin" >> "$GITHUB_PATH"
@@ -144,7 +144,7 @@ jobs:
       - name: Install OS / deb dependencies
         run: |
           sudo DEBIAN_FRONTEND=noninteractive apt-get update
-          sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq graphviz gcc 
libvirt-dev
+          sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq graphviz gcc 
libvirt-dev pkg-config
 
       - name: Cache uv
         uses: actions/cache@v5
@@ -155,7 +155,7 @@ jobs:
             ${{ runner.os }}-uv-
 
       - name: Install Python Dependencies
-        run: uv sync --extra ci
+        run: uv sync --group ci --no-dev
 
       - name: Add .venv to PATH
         run: echo "${GITHUB_WORKSPACE}/.venv/bin" >> "$GITHUB_PATH"
@@ -203,7 +203,7 @@ jobs:
 
       - name: Install Python Dependencies
         run: |
-          uv sync --extra ci --extra build
+          uv sync --group ci --group build --no-dev
           echo "${GITHUB_WORKSPACE}/.venv/bin" >> "$GITHUB_PATH"
 
       - name: Build Release Artifact
@@ -291,7 +291,7 @@ jobs:
       - name: Install OS / deb dependencies
         run: |
           sudo DEBIAN_FRONTEND=noninteractive apt-get update
-          sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq gcc 
libvirt-dev
+          sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq gcc 
libvirt-dev pkg-config
 
       - name: Cache uv
         uses: actions/cache@v5
@@ -302,7 +302,7 @@ jobs:
             ${{ runner.os }}-uv-
 
       - name: Install Python Dependencies
-        run: uv sync --extra ci
+        run: uv sync --group dev --group docs
 
       - name: Add .venv to PATH
         run: echo "${GITHUB_WORKSPACE}/.venv/bin" >> "$GITHUB_PATH"
@@ -333,13 +333,10 @@ jobs:
       - name: Cleanup
         run: rm -rf venv/ || true
 
-      - name: Export Development Requirements
-        run: uv export --extra test --extra lint --extra mypy --extra docs 
--format requirements.txt --no-hashes --no-emit-project --output-file 
requirements-dev.txt
-
       - name: Run Pip Audit Check On All Development And Test Dependencies
         uses: 
pypa/gh-action-pip-audit@1220774d901786e6f652ae159f7b6bc8fea6d266 # v1.1.0
         with:
-          inputs: requirements-dev.txt
+          virtual-environment: .venv
           # setuptools which we don't install or depend on directly
           ignore-vulns: |
             GHSA-r9hx-vwmv-q579
@@ -367,7 +364,7 @@ jobs:
       - name: Install OS / deb dependencies
         run: |
           sudo DEBIAN_FRONTEND=noninteractive apt-get update
-          sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq graphviz gcc 
libvirt-dev
+          sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq graphviz gcc 
libvirt-dev pkg-config
 
       - name: Cache uv
         uses: actions/cache@v5
@@ -378,7 +375,7 @@ jobs:
             ${{ runner.os }}-uv-
 
       - name: Install Python Dependencies
-        run: uv sync --extra ci
+        run: uv sync --group ci --no-dev
 
       - name: Add .venv to PATH
         run: echo "${GITHUB_WORKSPACE}/.venv/bin" >> "$GITHUB_PATH"
@@ -409,7 +406,7 @@ jobs:
       - name: Install OS / deb dependencies
         run: |
           sudo DEBIAN_FRONTEND=noninteractive apt-get update
-          sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq graphviz gcc 
libvirt-dev
+          sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq graphviz gcc 
libvirt-dev pkg-config
 
       - name: Cache uv
         uses: actions/cache@v5
@@ -420,7 +417,7 @@ jobs:
             ${{ runner.os }}-uv-
 
       - name: Install Python Dependencies
-        run: uv sync --extra ci
+        run: uv sync --group ci --no-dev
 
       - name: Add .venv to PATH
         run: echo "${GITHUB_WORKSPACE}/.venv/bin" >> "$GITHUB_PATH"
diff --git a/.github/workflows/publish_dev_artifact.yml 
b/.github/workflows/publish_dev_artifact.yml
index 76bf2e763..375db882a 100644
--- a/.github/workflows/publish_dev_artifact.yml
+++ b/.github/workflows/publish_dev_artifact.yml
@@ -35,7 +35,7 @@ jobs:
         run: printenv | sort
       - name: Install Dependencies
         run: |
-          uv sync --extra build
+          uv sync --group build --no-dev
           echo "${GITHUB_WORKSPACE}/.venv/bin" >> "$GITHUB_PATH"
 
       - name: Create Dev Artifacts
diff --git a/.github/workflows/publish_pricing_to_s3.yml 
b/.github/workflows/publish_pricing_to_s3.yml
index 93b52b6ce..c45e513ad 100644
--- a/.github/workflows/publish_pricing_to_s3.yml
+++ b/.github/workflows/publish_pricing_to_s3.yml
@@ -33,7 +33,7 @@ jobs:
 
       - name: Install Python Dependencies
         run: |
-          uv sync --extra ci
+          uv sync --group ci --no-dev
           echo "${GITHUB_WORKSPACE}/.venv/bin" >> "$GITHUB_PATH"
 
       - name: Generate and publish pricing data
diff --git a/.readthedocs.yml b/.readthedocs.yml
index 1272aa6c3..d4db84c41 100644
--- a/.readthedocs.yml
+++ b/.readthedocs.yml
@@ -9,6 +9,13 @@ build:
   os: ubuntu-22.04
   tools:
     python: "3.10"
+  jobs:
+    pre_create_environment:
+      - python -m pip install --upgrade pip uv
+    create_environment:
+      - python -m uv venv "${READTHEDOCS_VIRTUALENV_PATH}"
+    install:
+      - UV_PROJECT_ENVIRONMENT="${READTHEDOCS_VIRTUALENV_PATH}" python -m uv 
sync --frozen --group docs --no-dev
 
 # Build documentation in the "docs/" directory with Sphinx
 sphinx:
@@ -20,12 +27,3 @@ formats:
 
 # NOTE: We need to use older version of sphinx otherwise bullet points won't 
be rendered correctly
 # on RTD using rtd theme.
-# Optional but recommended, declare the Python requirements required
-# to build your documentation
-# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
-python:
-  install:
-    - method: pip
-      path: .
-      extra_requirements:
-        - rtd
diff --git a/docs/committer_guide.rst b/docs/committer_guide.rst
index 5c2cbab7c..6faf0fb00 100644
--- a/docs/committer_guide.rst
+++ b/docs/committer_guide.rst
@@ -108,7 +108,7 @@ To run it:
 .. sourcecode:: bash
 
     # Install build dependencies
-    pip install -e ".[build]"
+    uv sync --group build --no-dev
 
     cd dist
     ./release.sh -u <yourusername>@apache.org
@@ -193,7 +193,7 @@ use this token, see:
 .. sourcecode:: bash
 
     # Install publish dependencies
-    pip install -e ".[publish]"
+    uv sync --group publish --no-dev
 
     cd dist
     ./deploy.sh
diff --git a/docs/development.rst b/docs/development.rst
index d9d5c77a0..f21d80313 100644
--- a/docs/development.rst
+++ b/docs/development.rst
@@ -18,8 +18,8 @@ Getting started with contributing to Libcloud
 ---------------------------------------------
 
 We use ``uv`` to lock and manage development dependencies. Dependency groups 
are
-defined as extras in ``pyproject.toml`` and the ``uv.lock`` file replaces the
-legacy ``requirements-*.txt`` files.
+defined under ``[dependency-groups]`` in ``pyproject.toml`` and ``uv.lock`` is
+the source of truth for local development and documentation tooling.
 
 To create or update the lockfile, run:
 
@@ -30,17 +30,24 @@ To create or update the lockfile, run:
 If ``uv lock`` fails while building ``libvirt-python``, install the system
 dependencies (``pkg-config`` and ``libvirt-dev``).
 
-To set up a local development environment with common tooling:
+To set up a local development environment with common tooling (tests, linting,
+type checking, tox):
 
 .. sourcecode:: bash
 
-    uv sync --extra test --extra lint --extra docs --extra mypy --extra ci
+    uv sync --group dev
 
-If you only need a subset, sync just those extras (for example, tests only):
+If you only need a subset, sync just those groups (for example, tests only):
 
 .. sourcecode:: bash
 
-    uv sync --extra test
+    uv sync --group test --no-dev
+
+If you also work on documentation, add the docs group:
+
+.. sourcecode:: bash
+
+    uv sync --group dev --group docs
 
 Commit ``uv.lock`` whenever dependency versions change.
 
@@ -447,7 +454,7 @@ Some examples which show how to handle those cases are 
described below.
 Type annotation for unions
 ~~~~~~~~~~~~~~~~
 
-In Python 3.9 and below, the pipe character (``|``) cannot be used for union 
+In Python 3.9 and below, the pipe character (``|``) cannot be used for union
 types in type annotations. Instead, you should use ``Union`` from the 
``typing``
 module:
 
diff --git a/docs/testing.rst b/docs/testing.rst
index 5c00bfce8..12ae32435 100644
--- a/docs/testing.rst
+++ b/docs/testing.rst
@@ -16,12 +16,12 @@ If you use ``uv``, you can install all test dependencies in 
one step:
 
 .. sourcecode:: bash
 
-    uv sync --extra test --extra ci
+    uv sync --group test --group ci --no-dev
 
-Drop ``--extra ci`` if you don't plan to run ``tox``.
+Drop ``--group ci`` if you don't plan to run ``tox``.
 If ``uv.lock`` is missing or out of date, run ``uv lock`` first.
 
-If you don't use ``uv``, you need to have the following extra dependencies
+If you don't use ``uv``, you need to have the following additional dependencies
 installed:
 
 * ``tox`` (``pip install tox``) - you only need this library if you want to
diff --git a/integration/compute/README.rst b/integration/compute/README.rst
index b524d5bd7..0dbd209f9 100644
--- a/integration/compute/README.rst
+++ b/integration/compute/README.rst
@@ -8,7 +8,7 @@ Running the API service
 
 .. code-block:: bash
 
-  uv sync --extra integration-compute
+  uv sync --group integration-compute
   python -m integration.compute.api
 
 Running the tests
diff --git a/integration/storage/README.rst b/integration/storage/README.rst
index 1dccf67a0..b80fc8a4b 100644
--- a/integration/storage/README.rst
+++ b/integration/storage/README.rst
@@ -8,7 +8,7 @@ Setting up the test suite
 
 .. code-block:: bash
 
-  uv sync --extra integration-storage
+  uv sync --group integration-storage
 
 Running the tests
 -----------------
diff --git a/pyproject.toml b/pyproject.toml
index 2e152c1bc..c73df7c74 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -71,12 +71,12 @@ Distribution = "https://pypi.org/project/apache-libcloud";
 Changelog = "https://github.com/apache/libcloud/blob/trunk/CHANGES.rst";
 
 
-[project.optional-dependencies]
+[dependency-groups]
 build = [
-    "build==1.2.2"
+    "build==1.2.2",
 ]
 publish = [
-    "twine==5.1.1"
+    "twine==5.1.1",
 ]
 test = [
     "coverage[toml]==7.2.7; python_version >= '3.10'",
@@ -121,14 +121,10 @@ mypy = [
     "types-urllib3",
 ]
 ci = [
-    "tox==4.24.1"
-]
-rtd = [
-    "sphinx==6.2.1",
-    "sphinx_rtd_theme==2.0.0",
+    "tox==4.24.1",
 ]
 integration-compute = [
-    "bottle"
+    "bottle",
 ]
 integration-storage = [
     "azure-identity",
@@ -138,6 +134,12 @@ integration-storage = [
     "docker",
     "requests",
 ]
+dev = [
+    {include-group = "test"},
+    {include-group = "lint"},
+    {include-group = "mypy"},
+    {include-group = "ci"},
+]
 
 [tool.setuptools.packages.find]
 where = ["./"]
diff --git a/tox.ini b/tox.ini
index 368bfac77..1cd443e75 100644
--- a/tox.ini
+++ b/tox.ini
@@ -12,8 +12,8 @@ passenv =
     DOCKER_*
     FORCE_COLOR
     NO_COLOR
-deps =
-    .[test]
+dependency_groups =
+    test
 allowlist_externals =
     cp
     echo
@@ -49,6 +49,7 @@ skipdist = True
 recreate = True
 # NOTE: We intentionally set empty deps to ensure it works on a clean
 # environment without any dependencies
+dependency_groups =
 deps =
 commands = bash -c "./scripts/dist_install_check.sh"
 
@@ -58,6 +59,7 @@ skipdist = True
 recreate = True
 # NOTE: We intentionally set empty deps to ensure it works on a clean
 # environment without any dependencies
+dependency_groups =
 deps =
 commands = bash -c "./scripts/dist_wheel_install_check.sh"
 
@@ -68,6 +70,7 @@ skipdist = True
 recreate = True
 # NOTE: We intentionally set empty deps to ensure it works on a clean
 # environment without any dependencies
+dependency_groups =
 deps =
 commands = bash -c "./scripts/dist_install_check.sh"
 
@@ -77,6 +80,7 @@ skipdist = True
 recreate = True
 # NOTE: We intentionally set empty deps to ensure it works on a clean
 # environment without any dependencies
+dependency_groups =
 deps =
 commands = bash -c "./scripts/dist_wheel_install_check.sh"
 
@@ -87,6 +91,7 @@ skipdist = True
 recreate = True
 # NOTE: We intentionally set empty deps to ensure it works on a clean
 # environment without any dependencies
+dependency_groups =
 deps =
 commands = bash -c "./scripts/dist_install_check.sh"
 
@@ -96,6 +101,7 @@ skipdist = True
 recreate = True
 # NOTE: We intentionally set empty deps to ensure it works on a clean
 # environment without any dependencies
+dependency_groups =
 deps =
 commands = bash -c "./scripts/dist_wheel_install_check.sh"
 
@@ -106,6 +112,7 @@ skipdist = True
 recreate = True
 # NOTE: We intentionally set empty deps to ensure it works on a clean
 # environment without any dependencies
+dependency_groups =
 deps =
 commands = bash -c "./scripts/dist_install_check.sh"
 
@@ -115,12 +122,13 @@ skipdist = True
 recreate = True
 # NOTE: We intentionally set empty deps to ensure it works on a clean
 # environment without any dependencies
+dependency_groups =
 deps =
 commands = bash -c "./scripts/dist_wheel_install_check.sh"
 
 [testenv:docs]
-deps =
-    .[docs]
+dependency_groups =
+    docs
 changedir = docs
 commands = rstcheck --report-level warning ../README.rst
            rstcheck --report-level warning ../CHANGES.rst
@@ -137,6 +145,7 @@ commands = python 
./contrib/generate_provider_feature_matrix_table.py
 basepython: python3.10
 # Needed to avoid urllib3 errors related to old openssl version
 # https://github.com/urllib3/urllib3/issues/2168
+dependency_groups =
 deps = urllib3==1.26.6
        requests
        jsonnet
@@ -171,6 +180,7 @@ commands =
 basepython: python3.10
 # Needed to avoid urllib3 errors related to old openssl version
 # https://github.com/urllib3/urllib3/issues/2168
+dependency_groups =
 deps = urllib3==1.26.6
        requests
        jsonnet
@@ -194,6 +204,7 @@ commands =
 basepython: python3.10
 # Needed to avoid urllib3 errors related to old openssl version
 # https://github.com/urllib3/urllib3/issues/2168
+dependency_groups =
 deps = urllib3==1.26.6
        requests
        jsonnet
@@ -205,6 +216,7 @@ commands = python contrib/scrape-ec2-prices.py
 basepython: python3.10
 # Needed to avoid urllib3 errors related to old openssl version
 # https://github.com/urllib3/urllib3/issues/2168
+dependency_groups =
 deps = urllib3==1.26.6
        requests
        ijson
@@ -216,8 +228,8 @@ commands =
 [testenv:pylint]
 setenv =
     PYTHONPATH={toxinidir}
-deps =
-    .[lint]
+dependency_groups =
+    lint
 commands = pylint -E --load-plugins=pylint_plugins.driver_class 
--rcfile=./pyproject.toml libcloud/common/
            pylint -E --load-plugins=pylint_plugins.driver_class 
--rcfile=./pyproject.toml libcloud/compute/
            pylint -E --load-plugins=pylint_plugins.driver_class 
--rcfile=./pyproject.toml libcloud/container/
@@ -230,8 +242,8 @@ commands = pylint -E 
--load-plugins=pylint_plugins.driver_class --rcfile=./pypro
            pylint -E --load-plugins=pylint_plugins.driver_class 
--rcfile=./pyproject.toml pylint_plugins/
 
 [testenv:lint]
-deps =
-    .[lint]
+dependency_groups =
+    lint
 commands = flake8 --config ./.flake8 libcloud/
            flake8 --config ./.flake8 libcloud/test/
            flake8 --config ./.flake8 demos/
@@ -246,13 +258,13 @@ commands = flake8 --config ./.flake8 libcloud/
            codespell libcloud/
 
 [testenv:bandit]
-deps =
-    .[lint]
+dependency_groups =
+    lint
 commands = bandit --configfile pyproject.toml -lll -r libcloud/
 
 [testenv:black]
-deps =
-    .[lint]
+dependency_groups =
+    lint
 # NOTE: We need to use bash -c otherwise black will quote the argument and it
 # won't expand to the list of files when the command runs
 commands =
@@ -266,8 +278,8 @@ commands =
            black --config pyproject.toml integration/
 
 [testenv:black-check]
-deps =
-    .[lint]
+dependency_groups =
+    lint
 # NOTE: We need to use bash -c otherwise black will quote the argument and it
 # won't expand to the list of files when the command runs
 commands =
@@ -286,7 +298,8 @@ commands =
     python ./scripts/check_asf_license_headers.py .
 
 [testenv:integration-compute]
-deps = .[integration-compute]
+dependency_groups =
+    integration-compute
 
 commands = python -m integration.compute
 
@@ -302,14 +315,14 @@ setenv =
   AZURE_TENANT_ID=982317c6-fb7e-4e92-abcd-196557e41c5b
   AZURE_SUBSCRIPTION_ID=d6d608a6-e0c8-42ae-a548-2f41793709d2
   # Actual secret token is defined as part of Github repo secret
-deps =
-    .[test]
-    .[integration-storage]
+dependency_groups =
+    test
+    integration-storage
 commands = pytest --color=yes -rsx -vvv --capture=tee-sys -o log_cli=True 
--durations=10 integration/storage
 
 [testenv:coverage]
-deps =
-    .[test]
+dependency_groups =
+    test
 setenv =
   CRYPTOGRAPHY_ALLOW_OPENSSL_102=1
 commands = cp libcloud/test/secrets.py-dist libcloud/test/secrets.py
@@ -321,8 +334,8 @@ passenv =
     TOXENV
     CI
     GITHUB_*
-deps =
-    .[test]
+dependency_groups =
+    test
 setenv =
   CRYPTOGRAPHY_ALLOW_OPENSSL_102=1
 commands = cp libcloud/test/secrets.py-dist libcloud/test/secrets.py
@@ -330,20 +343,20 @@ commands = cp libcloud/test/secrets.py-dist 
libcloud/test/secrets.py
            coverage xml
 
 [testenv:isort]
-deps =
-    .[lint]
+dependency_groups =
+    lint
 commands =
     isort {toxinidir}
 
 [testenv:isort-check]
-deps =
-    .[lint]
+dependency_groups =
+    lint
 commands =
     isort --check {toxinidir}
 
 [testenv:pyupgrade]
-deps =
-    .[lint]
+dependency_groups =
+    lint
 commands =
     bash -c "find libcloud/ -name '*.py' -print0 | xargs -0 pyupgrade 
--py310-plus --py3-only"
     bash -c "find contrib/ -name '*.py' -print0 | xargs -0 pyupgrade 
--py310-plus --py3-only"
@@ -356,8 +369,8 @@ commands =
     isort {toxinidir}
 
 [testenv:mypy]
-deps =
-    .[mypy]
+dependency_groups =
+    mypy
 commands =
     mypy --no-incremental libcloud/common/
     mypy --no-incremental libcloud/compute/
@@ -378,6 +391,7 @@ commands =
 [testenv:import-timings]
 setenv =
     PYTHONPATH={toxinidir}
+dependency_groups =
 deps = requests
        profimp==0.1.0
 commands =
diff --git a/uv.lock b/uv.lock
index 4d798f80c..b2932bed6 100644
--- a/uv.lock
+++ b/uv.lock
@@ -32,13 +32,44 @@ dependencies = [
     { name = "requests" },
 ]
 
-[package.optional-dependencies]
+[package.dev-dependencies]
 build = [
     { name = "build" },
 ]
 ci = [
     { name = "tox" },
 ]
+dev = [
+    { name = "astroid" },
+    { name = "bandit", extra = ["toml"] },
+    { name = "black", marker = "implementation_name == 'cpython'" },
+    { name = "codespell" },
+    { name = "coverage", extra = ["toml"] },
+    { name = "cryptography" },
+    { name = "fasteners" },
+    { name = "flake8" },
+    { name = "isort" },
+    { name = "libvirt-python" },
+    { name = "mypy", marker = "implementation_name == 'cpython'" },
+    { name = "paramiko", marker = "platform_python_implementation != 'PyPy'" },
+    { name = "pep8" },
+    { name = "prek" },
+    { name = "pylint" },
+    { name = "pyopenssl" },
+    { name = "pytest" },
+    { name = "pytest-benchmark", extra = ["histogram"] },
+    { name = "pytest-timeout" },
+    { name = "pytest-xdist" },
+    { name = "pyupgrade" },
+    { name = "requests" },
+    { name = "requests-mock" },
+    { name = "rstcheck" },
+    { name = "tox" },
+    { name = "types-certifi" },
+    { name = "types-requests" },
+    { name = "types-simplejson" },
+    { name = "types-urllib3" },
+]
 docs = [
     { name = "fasteners" },
     { name = "rstcheck" },
@@ -81,10 +112,6 @@ mypy = [
 publish = [
     { name = "twine" },
 ]
-rtd = [
-    { name = "sphinx" },
-    { name = "sphinx-rtd-theme" },
-]
 test = [
     { name = "coverage", extra = ["toml"] },
     { name = "cryptography" },
@@ -101,56 +128,95 @@ test = [
 ]
 
 [package.metadata]
-requires-dist = [
-    { name = "astroid", marker = "python_full_version >= '3.10' and extra == 
'lint'", specifier = "==3.3.8" },
-    { name = "azure-identity", marker = "extra == 'integration-storage'" },
-    { name = "azure-mgmt-resource", marker = "extra == 'integration-storage'" 
},
-    { name = "azure-mgmt-storage", marker = "extra == 'integration-storage'" },
-    { name = "bandit", extras = ["toml"], marker = "python_full_version >= 
'3.10' and extra == 'lint'", specifier = "==1.7.8" },
-    { name = "black", marker = "python_full_version >= '3.10' and 
implementation_name == 'cpython' and extra == 'lint'", specifier = "==25.1.0" },
-    { name = "boto3", marker = "extra == 'integration-storage'" },
-    { name = "bottle", marker = "extra == 'integration-compute'" },
-    { name = "build", marker = "extra == 'build'", specifier = "==1.2.2" },
-    { name = "codespell", marker = "extra == 'lint'", specifier = "==2.4.1" },
-    { name = "coverage", extras = ["toml"], marker = "python_full_version >= 
'3.10' and extra == 'test'", specifier = "==7.2.7" },
-    { name = "cryptography", marker = "extra == 'test'", specifier = 
"==44.0.2" },
-    { name = "docker", marker = "extra == 'integration-storage'" },
-    { name = "fasteners", marker = "extra == 'docs'" },
-    { name = "fasteners", marker = "extra == 'test'" },
-    { name = "flake8", marker = "extra == 'lint'", specifier = "==5.0.4" },
-    { name = "isort", marker = "python_full_version >= '3.10' and extra == 
'lint'", specifier = "==6.0.1" },
-    { name = "libvirt-python", marker = "extra == 'test'", specifier = 
"==10.2.0" },
-    { name = "mypy", marker = "python_full_version >= '3.10' and 
implementation_name == 'cpython' and extra == 'mypy'", specifier = "==1.15.0" },
-    { name = "paramiko", marker = "platform_python_implementation != 'PyPy' 
and extra == 'lint'", specifier = "==3.5.1" },
-    { name = "paramiko", marker = "platform_python_implementation != 'PyPy' 
and extra == 'test'", specifier = "==3.5.1" },
-    { name = "pep8", marker = "extra == 'lint'", specifier = "==1.7.1" },
-    { name = "prek", marker = "extra == 'lint'", specifier = ">=0.2.17" },
-    { name = "pylint", marker = "python_full_version >= '3.10' and extra == 
'lint'", specifier = "==3.3.4" },
-    { name = "pyopenssl", marker = "extra == 'test'", specifier = "==25.0.0" },
-    { name = "pytest", marker = "extra == 'test'", specifier = "==8.3.5" },
-    { name = "pytest-benchmark", extras = ["histogram"], marker = 
"python_full_version >= '3.10' and extra == 'test'", specifier = "==5.1.0" },
-    { name = "pytest-timeout", marker = "extra == 'test'", specifier = 
"==2.3.1" },
-    { name = "pytest-xdist", marker = "extra == 'test'", specifier = "==3.6.1" 
},
-    { name = "pyupgrade", marker = "extra == 'lint'", specifier = "==3.3.1" },
-    { name = "requests", specifier = ">=2.26.0" },
-    { name = "requests", marker = "extra == 'integration-storage'" },
-    { name = "requests", marker = "extra == 'lint'", specifier = ">=2.27.1" },
-    { name = "requests", marker = "extra == 'test'", specifier = ">=2.31.0" },
-    { name = "requests-mock", marker = "extra == 'test'", specifier = 
"==1.11.0" },
-    { name = "rstcheck", marker = "python_full_version >= '3.10' and extra == 
'docs'", specifier = "==6.2.4" },
-    { name = "rstcheck", marker = "python_full_version >= '3.10' and extra == 
'lint'", specifier = "==6.2.4" },
-    { name = "sphinx", marker = "extra == 'docs'", specifier = "==6.2.1" },
-    { name = "sphinx", marker = "extra == 'rtd'", specifier = "==6.2.1" },
-    { name = "sphinx-rtd-theme", marker = "extra == 'docs'", specifier = 
"==2.0.0" },
-    { name = "sphinx-rtd-theme", marker = "extra == 'rtd'", specifier = 
"==2.0.0" },
-    { name = "tox", marker = "extra == 'ci'", specifier = "==4.24.1" },
-    { name = "twine", marker = "extra == 'publish'", specifier = "==5.1.1" },
-    { name = "types-certifi", marker = "extra == 'mypy'" },
-    { name = "types-requests", marker = "extra == 'mypy'" },
-    { name = "types-simplejson", marker = "extra == 'mypy'" },
-    { name = "types-urllib3", marker = "extra == 'mypy'" },
-]
-provides-extras = ["build", "ci", "docs", "integration-compute", 
"integration-storage", "lint", "mypy", "publish", "rtd", "test"]
+requires-dist = [{ name = "requests", specifier = ">=2.26.0" }]
+
+[package.metadata.requires-dev]
+build = [{ name = "build", specifier = "==1.2.2" }]
+ci = [{ name = "tox", specifier = "==4.24.1" }]
+dev = [
+    { name = "astroid", marker = "python_full_version >= '3.10'", specifier = 
"==3.3.8" },
+    { name = "bandit", extras = ["toml"], marker = "python_full_version >= 
'3.10'", specifier = "==1.9.3" },
+    { name = "black", marker = "python_full_version >= '3.10' and 
implementation_name == 'cpython'", specifier = "==25.1.0" },
+    { name = "codespell", specifier = "==2.4.1" },
+    { name = "coverage", extras = ["toml"], marker = "python_full_version >= 
'3.10'", specifier = "==7.2.7" },
+    { name = "cryptography", specifier = "==44.0.2" },
+    { name = "fasteners" },
+    { name = "flake8", specifier = "==5.0.4" },
+    { name = "isort", marker = "python_full_version >= '3.10'", specifier = 
"==6.0.1" },
+    { name = "libvirt-python", specifier = "==10.2.0" },
+    { name = "mypy", marker = "python_full_version >= '3.10' and 
implementation_name == 'cpython'", specifier = "==1.15.0" },
+    { name = "paramiko", marker = "platform_python_implementation != 'PyPy'", 
specifier = "==3.5.1" },
+    { name = "pep8", specifier = "==1.7.1" },
+    { name = "prek", specifier = ">=0.2.17" },
+    { name = "pylint", marker = "python_full_version >= '3.10'", specifier = 
"==3.3.4" },
+    { name = "pyopenssl", specifier = "==25.0.0" },
+    { name = "pytest", specifier = "==8.3.5" },
+    { name = "pytest-benchmark", extras = ["histogram"], marker = 
"python_full_version >= '3.10'", specifier = "==5.1.0" },
+    { name = "pytest-timeout", specifier = "==2.3.1" },
+    { name = "pytest-xdist", specifier = "==3.6.1" },
+    { name = "pyupgrade", specifier = "==3.3.1" },
+    { name = "requests", specifier = ">=2.27.1" },
+    { name = "requests", specifier = ">=2.31.0" },
+    { name = "requests-mock", specifier = "==1.11.0" },
+    { name = "rstcheck", marker = "python_full_version >= '3.10'", specifier = 
"==6.2.4" },
+    { name = "tox", specifier = "==4.24.1" },
+    { name = "types-certifi" },
+    { name = "types-requests" },
+    { name = "types-simplejson" },
+    { name = "types-urllib3" },
+]
+docs = [
+    { name = "fasteners" },
+    { name = "rstcheck", marker = "python_full_version >= '3.10'", specifier = 
"==6.2.4" },
+    { name = "sphinx", specifier = "==6.2.1" },
+    { name = "sphinx-rtd-theme", specifier = "==2.0.0" },
+]
+integration-compute = [{ name = "bottle" }]
+integration-storage = [
+    { name = "azure-identity" },
+    { name = "azure-mgmt-resource" },
+    { name = "azure-mgmt-storage" },
+    { name = "boto3" },
+    { name = "docker" },
+    { name = "requests" },
+]
+lint = [
+    { name = "astroid", marker = "python_full_version >= '3.10'", specifier = 
"==3.3.8" },
+    { name = "bandit", extras = ["toml"], marker = "python_full_version >= 
'3.10'", specifier = "==1.9.3" },
+    { name = "black", marker = "python_full_version >= '3.10' and 
implementation_name == 'cpython'", specifier = "==25.1.0" },
+    { name = "codespell", specifier = "==2.4.1" },
+    { name = "flake8", specifier = "==5.0.4" },
+    { name = "isort", marker = "python_full_version >= '3.10'", specifier = 
"==6.0.1" },
+    { name = "paramiko", marker = "platform_python_implementation != 'PyPy'", 
specifier = "==3.5.1" },
+    { name = "pep8", specifier = "==1.7.1" },
+    { name = "prek", specifier = ">=0.2.17" },
+    { name = "pylint", marker = "python_full_version >= '3.10'", specifier = 
"==3.3.4" },
+    { name = "pyupgrade", specifier = "==3.3.1" },
+    { name = "requests", specifier = ">=2.27.1" },
+    { name = "rstcheck", marker = "python_full_version >= '3.10'", specifier = 
"==6.2.4" },
+]
+mypy = [
+    { name = "mypy", marker = "python_full_version >= '3.10' and 
implementation_name == 'cpython'", specifier = "==1.15.0" },
+    { name = "types-certifi" },
+    { name = "types-requests" },
+    { name = "types-simplejson" },
+    { name = "types-urllib3" },
+]
+publish = [{ name = "twine", specifier = "==5.1.1" }]
+test = [
+    { name = "coverage", extras = ["toml"], marker = "python_full_version >= 
'3.10'", specifier = "==7.2.7" },
+    { name = "cryptography", specifier = "==44.0.2" },
+    { name = "fasteners" },
+    { name = "libvirt-python", specifier = "==10.2.0" },
+    { name = "paramiko", marker = "platform_python_implementation != 'PyPy'", 
specifier = "==3.5.1" },
+    { name = "pyopenssl", specifier = "==25.0.0" },
+    { name = "pytest", specifier = "==8.3.5" },
+    { name = "pytest-benchmark", extras = ["histogram"], marker = 
"python_full_version >= '3.10'", specifier = "==5.1.0" },
+    { name = "pytest-timeout", specifier = "==2.3.1" },
+    { name = "pytest-xdist", specifier = "==3.6.1" },
+    { name = "requests", specifier = ">=2.31.0" },
+    { name = "requests-mock", specifier = "==1.11.0" },
+]
 
 [[package]]
 name = "astroid"
@@ -263,7 +329,7 @@ wheels = [
 
 [[package]]
 name = "bandit"
-version = "1.7.8"
+version = "1.9.3"
 source = { registry = "https://pypi.org/simple"; }
 dependencies = [
     { name = "colorama", marker = "sys_platform == 'win32'" },
@@ -271,9 +337,9 @@ dependencies = [
     { name = "rich" },
     { name = "stevedore" },
 ]
-sdist = { url = 
"https://files.pythonhosted.org/packages/92/60/3f6e0e58f3f53bbb7227daf61654c9b22ff651e670e44cdc08a0f1d0f493/bandit-1.7.8.tar.gz";,
 hash = 
"sha256:36de50f720856ab24a24dbaa5fee2c66050ed97c1477e0a1159deab1775eab6b", size 
= 1983678, upload-time = "2024-03-08T19:25:56.173Z" }
+sdist = { url = 
"https://files.pythonhosted.org/packages/89/76/a7f3e639b78601118aaa4a394db2c66ae2597fbd8c39644c32874ed11e0c/bandit-1.9.3.tar.gz";,
 hash = 
"sha256:ade4b9b7786f89ef6fc7344a52b34558caec5da74cb90373aed01de88472f774", size 
= 4242154, upload-time = "2026-01-19T04:05:22.802Z" }
 wheels = [
-    { url = 
"https://files.pythonhosted.org/packages/c2/88/03935559af80b39cb64a00a4731d62ed2f79f4799c1758eadb01a4ef6b8d/bandit-1.7.8-py3-none-any.whl";,
 hash = 
"sha256:509f7af645bc0cd8fd4587abc1a038fc795636671ee8204d502b933aee44f381", size 
= 127633, upload-time = "2024-03-08T19:25:54.618Z" },
+    { url = 
"https://files.pythonhosted.org/packages/e0/0b/8bdc52111c83e2dc2f97403dc87c0830b8989d9ae45732b34b686326fb2c/bandit-1.9.3-py3-none-any.whl";,
 hash = 
"sha256:4745917c88d2246def79748bde5e08b9d5e9b92f877863d43fab70cd8814ce6a", size 
= 134451, upload-time = "2026-01-19T04:05:20.938Z" },
 ]
 
 [package.optional-dependencies]

Reply via email to