diff --git a/.github/workflows/test_development_versions.yml b/.github/workflows/test_development_versions.yml index cac3d71fb..faf9a07d5 100644 --- a/.github/workflows/test_development_versions.yml +++ b/.github/workflows/test_development_versions.yml @@ -30,8 +30,8 @@ jobs: shell: bash run: | python -m pip install --upgrade pip tox - python -m pip install toml typer - python tools/extremal-python-dependencies.py pin-dependencies \ + python -m pip install ./tools/extremal-python-dependencies + extremal-python-dependencies pin-dependencies \ "qiskit @ git+https://github.com/Qiskit/qiskit.git" \ "qiskit-ibm-runtime @ git+https://github.com/Qiskit/qiskit-ibm-runtime.git" \ --inplace diff --git a/.github/workflows/test_minimum_versions.yml b/.github/workflows/test_minimum_versions.yml index bf454c7c1..0095b4963 100644 --- a/.github/workflows/test_minimum_versions.yml +++ b/.github/workflows/test_minimum_versions.yml @@ -28,9 +28,9 @@ jobs: shell: bash run: | python -m pip install --upgrade pip - python -m pip install toml typer - pip install "tox==$(python tools/extremal-python-dependencies.py get-tox-minversion)" - python tools/extremal-python-dependencies.py pin-dependencies-to-minimum --inplace + python -m pip install ./tools/extremal-python-dependencies + pip install "tox==$(extremal-python-dependencies get-tox-minversion)" + extremal-python-dependencies pin-dependencies-to-minimum --inplace - name: Modify tox.ini for more thorough check shell: bash run: | diff --git a/tools/extremal-python-dependencies/README.md b/tools/extremal-python-dependencies/README.md new file mode 100644 index 000000000..397cb58ac --- /dev/null +++ b/tools/extremal-python-dependencies/README.md @@ -0,0 +1,40 @@ +# extremal-python-dependencies + +Install extremal versions of package dependencies for more robust continuous integration testing, given a package that specifies its dependencies in a `pyproject.toml` file. + +For instance, one might use this utility to install the minimum supported version of each dependency before a CI run. Ensuring all tests then pass ensures that the code is indeed compatible with the range of package versions it claims to be compatible with, helping to prevent users from encountering broken installs. + +Another way to use this tool is to install development versions of certain packages. + +This utility works with dependencies specified in a `pyproject.toml` file. It modifies `pyproject.toml`, either by sending the transformed version to stdout (the default) or by modifying in place (which may be useful in CI scripts). + +## How to use + +The following snippet modifies `pyproject.toml` in place to test with the minimum supported version of each direct dependency, under the minimum supported [tox](https://tox.wiki/) version (as specified by `minversion` in `tox.ini`). + +```sh +pip install "tox==$(extremal-python-dependencies get-tox-minversion)" +extremal-python-dependencies pin-dependencies-to-minimum --inplace +tox -epy +``` + +The following snippet modifies `pyproject.toml` in place to test with the development version of one or more dependencies: + +```sh +extremal-python-dependencies pin-dependencies \ + "qiskit @ git+https://github.com/Qiskit/qiskit.git" \ + "qiskit-ibm-runtime @ git+https://github.com/Qiskit/qiskit-ibm-runtime.git" \ + --inplace +tox -epy +``` + +Each of the above patterns can be used in a CI script. + +## Caveats + +- The minimum versions of all optional dependencies installed simultaneously must be compatible with each other. +- This tool does not set the minimum supported version of transitive dependencies. + +## Similar tools + +- [requirements-builder](https://requirements-builder.readthedocs.io/) (builds requirements from a `setup.py` file instead of a `pyproject.toml` file) diff --git a/tools/extremal-python-dependencies/extremal_python_dependencies/__init__.py b/tools/extremal-python-dependencies/extremal_python_dependencies/__init__.py new file mode 100644 index 000000000..75efffef4 --- /dev/null +++ b/tools/extremal-python-dependencies/extremal_python_dependencies/__init__.py @@ -0,0 +1,10 @@ +# This code is a Qiskit project. + +# (C) Copyright IBM 2024. + +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. diff --git a/tools/extremal-python-dependencies.py b/tools/extremal-python-dependencies/extremal_python_dependencies/main.py old mode 100755 new mode 100644 similarity index 98% rename from tools/extremal-python-dependencies.py rename to tools/extremal-python-dependencies/extremal_python_dependencies/main.py index e64e48b55..9f962331c --- a/tools/extremal-python-dependencies.py +++ b/tools/extremal-python-dependencies/extremal_python_dependencies/main.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # This code is a Qiskit project. # (C) Copyright IBM 2022. @@ -151,5 +150,5 @@ def _save_pyproject_toml(d: dict, inplace: bool) -> None: print(toml.dumps(d)) -if __name__ == "__main__": - app() +def main(): + return app() diff --git a/tools/extremal-python-dependencies/pyproject.toml b/tools/extremal-python-dependencies/pyproject.toml new file mode 100644 index 000000000..0023036dc --- /dev/null +++ b/tools/extremal-python-dependencies/pyproject.toml @@ -0,0 +1,38 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "extremal-python-dependencies" +version = "0.0.0" +description = "A utility for installing extremal versions of dependencies for more robust testing" +readme = "README.md" +license = {file = "../../LICENSE.txt"} +classifiers = [ + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Natural Language :: English", + "Operating System :: MacOS", + "Operating System :: POSIX :: Linux", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", +] + +requires-python = ">=3.8" + +dependencies = [ + "toml==0.10.2", + "typer==0.12.3", +] + +[tool.hatch.build.targets.wheel] +only-include = [ + "extremal_python_dependencies", +] + +[project.scripts] +extremal-python-dependencies = "extremal_python_dependencies.main:main"