diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index bd9dd696..4b7a35a6 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -10,49 +10,54 @@ jobs:
linting:
runs-on: ubuntu-24.04
steps:
- - name: Install dependencies
- run: sudo DEBIAN_FRONTEND=noninteractive apt-get -qy install tox
- name: Git checkout
uses: actions/checkout@v4
+ - name: Install uv
+ uses: astral-sh/setup-uv@v6
- name: Run ruff and mypy checks
- run: tox -e ruff,mypy
- py310:
- runs-on: ubuntu-22.04
- steps:
- - name: Install dependencies
- run: sudo DEBIAN_FRONTEND=noninteractive apt-get -qy install tox
- - name: Git checkout
- uses: actions/checkout@v4
- - name: Run tox
- run: tox -e py310
- py312:
- runs-on: ubuntu-24.04
+ run: uvx --with tox-uv tox -e ruff,mypy
+
+ unit-tests:
+ strategy:
+ matrix:
+ include:
+ - python: "3.10"
+ runner: ubuntu-22.04
+ tox-env: py310
+ - python: "3.12"
+ runner: ubuntu-24.04
+ tox-env: py312
+ runs-on: ${{ matrix.runner }}
steps:
- - name: Install dependencies
- run: sudo DEBIAN_FRONTEND=noninteractive apt-get -qy install tox
- name: Git checkout
uses: actions/checkout@v4
+ - name: Install uv
+ uses: astral-sh/setup-uv@v6
- name: Run tox
- run: tox -e py312
+ run: uvx --with tox-uv tox -e ${{ matrix.tox-env }}
+
docs:
runs-on: ubuntu-24.04
steps:
- - name: Install dependencies
- run: sudo DEBIAN_FRONTEND=noninteractive apt-get -qy install tox
- name: Git checkout
uses: actions/checkout@v4
+ - name: Install uv
+ uses: astral-sh/setup-uv@v6
- name: Build rtd docs
- run: tox -e docs
+ run: uvx --with tox-uv tox -e docs
+
integration-tests:
runs-on: ubuntu-24.04
steps:
- name: Install dependencies
run: |
sudo apt-get update -q
- sudo apt-get install -qy distro-info tox
+ sudo apt-get install -qy distro-info
sudo snap install lxd
- name: Git checkout
uses: actions/checkout@v3
+ - name: Install uv
+ uses: astral-sh/setup-uv@v6
- name: Setup LXD
uses: canonical/setup-lxd@v0.1.2
- name: Setup pycloudlib config and ssh key
@@ -62,4 +67,4 @@ jobs:
echo "[lxd]" > ~/.config/pycloudlib.toml
- name: Run CI integration tests
run: |
- tox -e integration-tests-ci -- --color=yes tests/integration_tests/
+ uvx --with tox-uv tox -e integration-tests-ci -- --color=yes tests/integration_tests/
diff --git a/.github/workflows/main_check.yaml b/.github/workflows/main_check.yaml
index c5679fd4..5333c675 100644
--- a/.github/workflows/main_check.yaml
+++ b/.github/workflows/main_check.yaml
@@ -12,7 +12,7 @@ jobs:
- name: Install dependencies
run: |
sudo apt-get update -q
- sudo apt-get install -qy distro-info tox
+ sudo apt-get install -qy distro-info
sudo apt-get remove --yes --purge azure-cli
- name: Initialize Pycloudlib
env:
@@ -25,7 +25,9 @@ jobs:
echo "$PYCLOUDLIB_TOML" > ~/.config/pycloudlib.toml
- name: Git checkout
uses: actions/checkout@v3
+ - name: Install uv
+ uses: astral-sh/setup-uv@v6
- name: Run CI integration tests
run: |
- GOOGLE_APPLICATION_CREDENTIALS=~/.config/gce_credentials tox -e integration-tests-main-check \
+ GOOGLE_APPLICATION_CREDENTIALS=~/.config/gce_credentials uvx --with tox-uv tox -e integration-tests-main-check \
-- --color=yes tests/integration_tests
diff --git a/.github/workflows/version_check.yaml b/.github/workflows/version_check.yaml
index 43c67c8a..6c566b71 100644
--- a/.github/workflows/version_check.yaml
+++ b/.github/workflows/version_check.yaml
@@ -11,10 +11,8 @@ jobs:
with:
fetch-depth: 0 # Necessary to compare with the main branch
- - name: Set up Python
- uses: actions/setup-python@v2
- with:
- python-version: '3.x' # Use Python 3.x
+ - name: Install uv
+ uses: astral-sh/setup-uv@v6
- name: Check version bump
run: |
@@ -22,12 +20,10 @@ jobs:
OLD_VERSION=$(git show origin/main:VERSION)
# Read VERSION file from the current branch
NEW_VERSION=$(cat VERSION)
-
+
echo "Old version: $OLD_VERSION"
echo "New version: $NEW_VERSION"
-
- pip install -r ci-requirements.txt
# Run the version comparison Python script
- python .github/workflows/version_check.py "$OLD_VERSION" "$NEW_VERSION"
+ uv run --with packaging .github/workflows/version_check.py "$OLD_VERSION" "$NEW_VERSION"
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index ae37cb38..84468f51 100644
--- a/.readthedocs.yaml
+++ b/.readthedocs.yaml
@@ -9,8 +9,10 @@ formats: all
python:
install:
- - path: .
- - requirements: docs/requirements.txt
+ - method: uv
+ path: .
+ extra-requirements:
+ - docs
sphinx:
configuration: docs/conf.py
diff --git a/Makefile b/Makefile
index 917dabc5..13afca55 100644
--- a/Makefile
+++ b/Makefile
@@ -1,35 +1,32 @@
PYTHON = python3
-SETUP := $(PYTHON) setup.py
+UV = uv
.PHONY: build clean install publish source test venv
build:
- $(SETUP) build
+ $(UV) build
clean:
- $(SETUP) clean
- rm -rf .tox .eggs *.egg-info build dist venv
+ rm -rf .tox .eggs *.egg-info build dist .venv
@find . -regex '.*\(__pycache__\|\.py[co]\)' -delete
$(MAKE) -C docs clean
install:
- $(SETUP) install
+ $(UV) sync
publish:
rm -rf dist/
- $(SETUP) sdist
- pip install twine
+ $(UV) build
+ $(UV) run pip install twine
twine upload dist/*
source:
- $(SETUP) sdist
+ $(UV) build
test:
- $(SETUP) check -r -s
- tox
+ $(UV) run tox
venv:
- $(PYTHON) -m virtualenv -p /usr/bin/$(PYTHON) venv
- venv/bin/pip install -Ur requirements.txt
+ uv sync
@echo "Now run the following to activate the virtual env:"
- @echo ". venv/bin/activate"
+ @echo ". .venv/bin/activate"
diff --git a/README.md b/README.md
index df5050ab..456f6ab4 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# pycloudlib
-[](https://travis-ci.com/canonical/pycloudlib)
+[](https://github.com/canonical/pycloudlib/actions/workflows/ci.yaml)
Python library to launch, interact, and snapshot cloud instances
@@ -9,17 +9,15 @@ Python library to launch, interact, and snapshot cloud instances
Install directly from [PyPI](https://pypi.org/project/pycloudlib/):
```shell
-pip3 install pycloudlib
+pip install pycloudlib
```
-Project's requirements.txt file can include pycloudlib as a dependency. Check out the [pip documentation](https://pip.readthedocs.io/en/1.1/requirements.html) for instructions on how to include a particular version or git hash.
-
-Install from latest changes in `main` branch:
+Install from the latest `main` branch:
```shell
-git clone https://github.com/canonical/pycloudlib.git
+git clone https://git.launchpad.net/pycloudlib
cd pycloudlib
-python3 setup.py install
+uv sync
```
## Usage
diff --git a/VERSION b/VERSION
index 63115ced..2f6094b5 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1!10.17.0
+1!10.18.0
diff --git a/ci-requirements.txt b/ci-requirements.txt
deleted file mode 100644
index 75aa6c06..00000000
--- a/ci-requirements.txt
+++ /dev/null
@@ -1 +0,0 @@
-packaging
\ No newline at end of file
diff --git a/docs/contributing.md b/docs/contributing.md
index 2ddd507d..adb23e17 100644
--- a/docs/contributing.md
+++ b/docs/contributing.md
@@ -25,7 +25,7 @@ The makefile can be used to create a Python virtual environment and do local tes
```shell
# Creates a python virtual environment with all requirements
make venv
-. venv/bin/activate
+. .venv/bin/activate
```
### Documentation
@@ -39,7 +39,7 @@ Documentation should be written in Markdown whenever possible.
When making changes please keep the following in mind:
* Keep pull requests limited to a single issue
-* Code must be formatted to [Black](https://black.readthedocs.io/en/stable/index.html) standards
+* Code must be formatted to [ruff](https://docs.astral.sh/ruff/) standards
* Run `tox -e format` to reformat code accordingly
* Run `tox` to execute style and lint checks
* When adding new clouds please add detailed documentation under the `docs` directory and code examples under `examples`
diff --git a/docs/index.rst b/docs/index.rst
index c8044fd2..9fcbdc6f 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -21,18 +21,15 @@ Install directly from `PyPI `_:
.. code-block:: shell
- pip3 install pycloudlib
+ uv pip install pycloudlib
-Project's requirements.txt file can include pycloudlib as a dependency. Check
-out the `pip documentation `_ for instructions on how to include a particular version or git hash.
-
-Install from latest master:
+Install from the latest ``main`` branch:
.. code-block:: shell
git clone https://git.launchpad.net/pycloudlib
cd pycloudlib
- python3 setup.py install
+ uv sync
*****
Usage
@@ -49,7 +46,7 @@ for more information.
Bugs
****
-File bugs on Launchpad under the `pycloudlib project `_.
+File bugs on `Launchpad `_.
*******
Contact
diff --git a/docs/requirements.txt b/docs/requirements.txt
deleted file mode 100644
index 2a4ec96e..00000000
--- a/docs/requirements.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-myst-parser
-sphinx
-sphinx_rtd_theme
diff --git a/examples/ibm_classic.py b/examples/ibm_classic.py
index 177e0f7b..0cac4480 100644
--- a/examples/ibm_classic.py
+++ b/examples/ibm_classic.py
@@ -4,6 +4,7 @@
import logging
import os
+from typing import Optional
import pycloudlib
import pycloudlib.ibm_classic
@@ -39,7 +40,7 @@ def manage_ssh_key(classic: pycloudlib.IBMClassic):
def launch_with_basic_cloud_config(
- ibm_classic: pycloudlib.IBMClassic, disk_size="25G", datacenter: str = None
+ ibm_classic: pycloudlib.IBMClassic, disk_size="25G", datacenter: Optional[str] = None
):
"""Launch a basic instance and demo basic functionality."""
image_gid = ibm_classic.released_image("22.04", disk_size=disk_size)
@@ -72,7 +73,7 @@ def launch_with_basic_cloud_config(
def launch_and_demo_all_lifecycle_features(
- ibm_classic: pycloudlib.IBMClassic, disk_size="25G", datacenter: str = None
+ ibm_classic: pycloudlib.IBMClassic, disk_size="25G", datacenter: Optional[str] = None
):
"""Launch a basic instance and demo basic functionality."""
image_gid = ibm_classic.released_image("22.04", disk_size=disk_size)
diff --git a/examples/oracle/oracle-cluster-demo.py b/examples/oracle/oracle-cluster-demo.py
index 8ecc06bf..0b8dd945 100644
--- a/examples/oracle/oracle-cluster-demo.py
+++ b/examples/oracle/oracle-cluster-demo.py
@@ -4,14 +4,15 @@
import logging
import sys
+from typing import Optional
import pycloudlib
def demo_cluster(
- availability_domain: str = None,
- compartment_id: str = None,
- vcn_name: str = None,
+ availability_domain: Optional[str] = None,
+ compartment_id: Optional[str] = None,
+ vcn_name: Optional[str] = None,
):
"""Show example of using the OCI library to launch a cluster instance and ping between them."""
with pycloudlib.OCI(
diff --git a/pycloudlib/azure/cloud.py b/pycloudlib/azure/cloud.py
index e49e6229..b2930723 100644
--- a/pycloudlib/azure/cloud.py
+++ b/pycloudlib/azure/cloud.py
@@ -11,7 +11,7 @@
from azure.core.exceptions import HttpResponseError, ResourceNotFoundError
from azure.mgmt.compute import ComputeManagementClient
from azure.mgmt.network import NetworkManagementClient
-from azure.mgmt.resource import ResourceManagementClient
+from azure.mgmt.resource.resources import ResourceManagementClient
from pycloudlib.azure import security_types, util
from pycloudlib.azure.instance import AzureInstance, VMInstanceStatus
diff --git a/pycloudlib/ec2/cloud.py b/pycloudlib/ec2/cloud.py
index 7a8fc314..72ef45c0 100644
--- a/pycloudlib/ec2/cloud.py
+++ b/pycloudlib/ec2/cloud.py
@@ -419,7 +419,7 @@ def list_keys(self):
keypair_names.append(keypair["KeyName"])
return keypair_names
- def snapshot(self, instance, clean=True):
+ def snapshot(self, instance, clean=True, **kwargs):
"""Snapshot an instance and generate an image from it.
Args:
diff --git a/pycloudlib/gce/instance.py b/pycloudlib/gce/instance.py
index cbb67c8f..f8944468 100644
--- a/pycloudlib/gce/instance.py
+++ b/pycloudlib/gce/instance.py
@@ -174,7 +174,7 @@ def _wait_for_instance_start(self, **kwargs):
self._wait_for_status("RUNNING")
self._ip = self._get_ip()
- def wait_for_delete(self, sleep_seconds=30, raise_on_fail=False):
+ def wait_for_delete(self, sleep_seconds=30, raise_on_fail=False, **kwargs):
"""Wait for instance to be deleted."""
get_instance_request = compute_v1.GetInstanceRequest(
project=self.project,
diff --git a/pycloudlib/lxd/cloud.py b/pycloudlib/lxd/cloud.py
index 9efba4b7..d60e7b44 100644
--- a/pycloudlib/lxd/cloud.py
+++ b/pycloudlib/lxd/cloud.py
@@ -397,7 +397,7 @@ def delete_image(self, image_id, **kwargs):
subp(["lxc", "image", "delete", image_id])
self._log.debug("Deleted %s", image_id)
- def snapshot(self, instance, clean=True, name=None):
+ def snapshot(self, instance, clean=True, name=None, **kwargs):
"""Take a snapshot of the passed in instance for use as image.
:param instance: The instance to create an image from
diff --git a/pycloudlib/lxd/instance.py b/pycloudlib/lxd/instance.py
index 45aa0ed3..ca034e95 100644
--- a/pycloudlib/lxd/instance.py
+++ b/pycloudlib/lxd/instance.py
@@ -462,7 +462,7 @@ def start(self, wait=True):
if wait:
self.wait()
- def wait_for_delete(self):
+ def wait_for_delete(self, **kwargs):
"""Wait for delete.
Not used for LXD.
@@ -494,13 +494,13 @@ def wait_for_state(self, desired_state: str, num_retries: int = 100):
time.sleep(1)
raise PycloudlibTimeoutError
- def wait_for_stop(self):
+ def wait_for_stop(self, **kwargs):
"""Wait for cloud instance to transition to stop state."""
# Ephemeral instances will not go to STOPPED. They get destroyed.
if not self.ephemeral:
self.wait_for_state("STOPPED")
- def _wait_for_instance_start(self):
+ def _wait_for_instance_start(self, **kwargs):
"""Wait for the cloud instance to be up.
LXD VMs need to install systemd units upon initialization. There is
@@ -530,17 +530,17 @@ def _wait_for_instance_start(self):
class LXDVirtualMachineInstance(LXDInstance):
"""LXD Virtual Machine backed instance."""
- def _run_command(self, command, stdin):
+ def _run_command(self, command, stdin, get_pty=False):
"""Run command in the instance."""
if self.execute_via_ssh:
- return super()._run_command(command, stdin)
+ return super()._run_command(command, stdin, get_pty=get_pty)
if self.series == "xenial":
self._log.warning(MISSING_AGENT_MSG, "lxc exec")
- return super()._run_command(command, stdin)
+ return super()._run_command(command, stdin, get_pty=get_pty)
- def _wait_for_instance_start(self):
+ def _wait_for_instance_start(self, **kwargs):
"""Wait for the cloud instance to be up.
LXD VMs need to install systemd units upon initialization. There is
diff --git a/pycloudlib/oci/cloud.py b/pycloudlib/oci/cloud.py
index 9aeae65d..9d9a6392 100644
--- a/pycloudlib/oci/cloud.py
+++ b/pycloudlib/oci/cloud.py
@@ -134,7 +134,7 @@ def delete_image(self, image_id, **kwargs):
"""
self.compute_client.delete_image(image_id, **kwargs)
- def released_image(self, release, operating_system="Canonical Ubuntu"):
+ def released_image(self, release, operating_system="Canonical Ubuntu", **kwargs):
"""Get the released image.
OCI just has periodic builds, so "released" and "daily" don't
@@ -359,7 +359,7 @@ def launch(
self.created_instances.append(instance)
return instance
- def snapshot(self, instance, clean=True, name=None):
+ def snapshot(self, instance, clean=True, name=None, **kwargs):
"""Snapshot an instance and generate an image from it.
Args:
diff --git a/pycloudlib/openstack/instance.py b/pycloudlib/openstack/instance.py
index 46f567bb..d66226f1 100644
--- a/pycloudlib/openstack/instance.py
+++ b/pycloudlib/openstack/instance.py
@@ -178,7 +178,7 @@ def _wait_for_instance_start(self, **kwargs):
"""Wait for instance to be up."""
self.conn.compute.wait_for_server(self.server, status="ACTIVE")
- def wait_for_delete(self):
+ def wait_for_delete(self, **kwargs):
"""Wait for instance to be deleted."""
try:
self.conn.compute.wait_for_server(self.server, status="DELETED")
diff --git a/pyproject.toml b/pyproject.toml
index 93bc1e5b..36dc6b93 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,92 @@
[build-system]
-requires = ["setuptools"]
-build-backend = "setuptools.build_meta"
+requires = ["hatchling"]
+build-backend = "hatchling.build"
+
+[project]
+dynamic = ["version"]
+requires-python = ">=3.10"
+name = "pycloudlib"
+description = "Python library to launch, interact, and snapshot cloud instances"
+classifiers = [
+ "Development Status :: 4 - Beta",
+ "Environment :: Console",
+ "Intended Audience :: Developers",
+ "Natural Language :: English",
+ "Operating System :: POSIX :: Linux",
+ "Programming Language :: Python :: 3 :: Only",
+ "Programming Language :: Python :: 3.10",
+ "Programming Language :: Python :: 3.11",
+ "Programming Language :: Python :: 3.12",
+ "Topic :: Software Development :: Libraries :: Python Modules",
+ "Topic :: Utilities",
+]
+dependencies = [
+ "azure-cli-core >= 2.21.0",
+ "azure-identity",
+ "azure-mgmt-compute >= 17",
+ "azure-mgmt-network >= 16",
+ "azure-mgmt-resource >= 15",
+ "boto3 >= 1.14.20",
+ "botocore >= 1.17.20",
+ "google-cloud-compute",
+ "googleapis-common-protos >= 1.63.1",
+ "ibm-cloud-sdk-core >= 3.14.0",
+ "ibm-platform-services",
+ "ibm-vpc >= 0.10, < 0.29.0",
+ "knack >= 0.7.1",
+ "oci >= 2.17.0",
+ "openstacksdk >= 4.2.0, < 4.9.0",
+ "paramiko >= 2.9.2",
+ "protobuf",
+ "pyparsing >= 2, < 3.0.0",
+ "python-openstackclient >= 5.2.1, < 8.3.0",
+ "pyyaml >= 5.1",
+ "qemu.qmp >= 0.0.3",
+ "requests >= 2.22",
+ "Softlayer >= 6.0.0",
+ "toml == 0.10",
+]
+
+[project.optional-dependencies]
+test = [
+ "mock",
+ "pytest",
+ "pytest-cov",
+ "pytest-mock",
+ "pytest-xdist",
+]
+docs = [
+ "myst-parser",
+ "sphinx",
+ "sphinx_rtd_theme",
+]
+dev = [
+ "mypy>=1.13",
+ "ruff==0.5.0",
+ "types-mock>=5.0.0",
+ "types-pyyaml>=6.0.12",
+ "types-requests>=2.31.0",
+ "types-setuptools>=67.0.0",
+ "types-toml>=0.10.8",
+ "packaging",
+]
+[dependency-groups]
+dev = [
+ "mypy>=1.13",
+ "ruff==0.5.0",
+ "types-mock>=5.0.0",
+ "types-pyyaml>=6.0.12",
+ "types-requests>=2.31.0",
+ "types-setuptools>=67.0.0",
+ "types-toml>=0.10.8",
+ "pytest",
+ "pytest-cov",
+ "pytest-mock",
+ "pytest-xdist",
+ "mock",
+ "packaging",
+]
+
[tool.mypy]
check_untyped_defs = true
@@ -63,4 +149,10 @@ markers = [
"ci: run test as part of continuous integration on PRs using GitHub Actions",
"main_check: run test as part of continuous integration after branch has merged to main using GitHub Actions",
]
-testpaths = ["tests/unit_tests"]
\ No newline at end of file
+testpaths = ["tests/unit_tests"]
+[tool.hatch.version]
+path = "VERSION"
+pattern = "(?P.+)"
+
+[tool.uv]
+python-preference = "only-system"
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index d6e1198b..00000000
--- a/requirements.txt
+++ /dev/null
@@ -1 +0,0 @@
--e .
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644
index e6239477..00000000
--- a/setup.cfg
+++ /dev/null
@@ -1,53 +0,0 @@
-[metadata]
-name = pycloudlib
-version = file:VERSION
-url = https://github.com/canonical/pycloudlib
-author = pycloudlib-devs
-author_email = pycloudlib-devs@lists.launchpad.net
-description = Python library to launch, interact, and snapshot cloud instances
-long_description = file: README.md
-long_description_content_type = text/markdown
-license = GNU General Public License v3 (GPLv3)
-classifiers =
- Development Status :: 4 - Beta
- Environment :: Console
- Intended Audience :: Developers
- Natural Language :: English
- Operating System :: POSIX :: Linux
- Programming Language :: Python :: 3 :: Only
- Topic :: Software Development :: Libraries :: Python Modules
- Topic :: Utilities
-
-[options]
-python_requires = >=3.8
-packages = find:
-zip_safe = True
-install_requires =
- azure-cli-core >= 2.21.0
- azure-identity
- azure-mgmt-compute >= 17
- azure-mgmt-network >= 16
- azure-mgmt-resource >= 15
- boto3 >= 1.14.20
- botocore >= 1.17.20
- google-cloud-compute
- googleapis-common-protos >= 1.63.1
- ibm-cloud-sdk-core >= 3.14.0
- ibm-platform-services
- ibm-vpc >= 0.10, < 0.29.0
- knack >= 0.7.1
- oci >= 2.17.0
- openstacksdk >= 1.1.0, < 1.5.0
- paramiko >= 2.9.2
- protobuf
- pyparsing >= 2, < 3.0.0
- python-openstackclient >= 5.2.1
- pyyaml >= 5.1
- qemu.qmp >= 0.0.3
- requests >= 2.22
- Softlayer >= 6.0.0
- toml == 0.10
-
-[options.package_data]
-pycloudlib =
- py.typed
diff --git a/setup.py b/setup.py
deleted file mode 100644
index c654c14f..00000000
--- a/setup.py
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/env python3
-"""Legacy Python packaging entry-point."""
-
-from setuptools import setup
-
-setup()
diff --git a/test-requirements.txt b/test-requirements.txt
deleted file mode 100644
index 9c0b714f..00000000
--- a/test-requirements.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-mock
-pytest
-pytest-cov
-pytest-mock
-pytest-xdist
diff --git a/tox.ini b/tox.ini
index c0b0aede..380f76c4 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,31 +1,20 @@
[tox]
+requires =
+ tox-uv
# As it may be undesired to make formatting changes, by default only check
-envlist = ruff, mypy, py38
+envlist = ruff, mypy, py310
skipsdist = true
[common]
envdir = {toxworkdir}/.testenv
deps =
- mypy==0.950
- ruff==0.5.0
- types-mock==5.0.0
- types-pyyaml==6.0.12
- types-requests==2.31.0.6
- types-setuptools==67.3.0
- types-toml==0.10.8
- -rrequirements.txt
- -rtest-requirements.txt
+ .[test,dev]
[testenv:pytest]
envdir = {[common]envdir}
deps = {[common]deps}
commands = {envpython} -m pytest --doctest-modules --cov=pycloudlib --cov-branch {posargs:tests/unit_tests}
-[testenv:py38]
-envdir = {[common]envdir}
-deps = {[common]deps}
-basepython = python3.8
-commands = {[testenv:pytest]commands}
[testenv:py310]
envdir = {[common]envdir}
@@ -43,60 +32,54 @@ commands = {[testenv:pytest]commands}
envdir = {[common]envdir}
deps =
{[common]deps}
-commands = {envpython} -m mypy {posargs:pycloudlib examples setup.py}
+commands = {envpython} -m mypy {posargs:pycloudlib examples}
[testenv:ruff]
envdir = {[common]envdir}
deps = {[common]deps}
commands =
- {envpython} -m ruff check {posargs:pycloudlib examples setup.py}
- {envpython} -m ruff format --check {posargs:pycloudlib examples setup.py}
+ {envpython} -m ruff check {posargs:pycloudlib examples}
+ {envpython} -m ruff format --check {posargs:pycloudlib examples}
[testenv:format]
envdir = {[common]envdir}
deps = {[common]deps}
commands =
- {envpython} -m ruff format {posargs:pycloudlib examples setup.py}
- {envpython} -m ruff check --fix {posargs:pycloudlib examples setup.py}
+ {envpython} -m ruff format {posargs:pycloudlib examples}
+ {envpython} -m ruff check --fix {posargs:pycloudlib examples}
[testenv:docs]
# Docs uses a separate environment because the changedir will
# cause tox to recreate the environment.
changedir = docs
deps =
- -rrequirements.txt
- -rtest-requirements.txt
- -rdocs/requirements.txt
+ .[test,docs]
commands = sphinx-build -M html "." "_build" -W
[tip]
envdir = {toxworkdir}/.testenv-tip
deps =
ruff
- -rrequirements.txt
[testenv:tip-ruff]
envdir = {[tip]envdir}
deps = {[tip]deps}
-commands = {envpython} -m ruff check -- pycloudlib examples setup.py
+commands = {envpython} -m ruff check -- pycloudlib examples
[testenv:integration-tests]
commands = {envpython} -m pytest --log-cli-level=INFO -svv {posargs:tests/integration_tests}
deps =
- -rrequirements.txt
- -rtest-requirements.txt
+ .[test]
[testenv:integration-tests-fast]
commands = {envpython} -m pytest -n auto --log-cli-level=INFO -svv {posargs:tests/integration_tests}
deps =
- -rrequirements.txt
- -rtest-requirements.txt
+ .[test]
[testenv:integration-tests-ci]
commands = {envpython} -m pytest -m ci --log-cli-level=INFO -svv {posargs:tests/integration_tests}
deps =
- -rrequirements.txt
- -rtest-requirements.txt
+ .[test]
[testenv:integration-tests-main-check]
# Since we can't use GH secrets from a forked PR, run the cloud-based