Skip to content

Commit 0438a4b

Browse files
Add no-optionals and full-optionals test runs (Qiskit#8967)
* Add no-optionals and full-optionals test runs This restructures the CI slightly to perform a complete "no-optionals" run, and a complete "all optionals" run (for the optionals that are readily accessible as Python packages, without complex additional setup). Previously, we only did a partial test with some of the oldest optional components, which could have allowed for behaviour to accidentally require optional components without us noticing. This splits the `requirements-dev.txt` file into two; lines that remain in the file are what is actually _required_ to run the test suite, run the style checks, and do the documentation build. The rest (and everything that was missing) is added to a new `requirements-optional.txt` file, which can be used to pull in (almost) all of the packages that Terra can use to provide additional / accelerated functionality. Several tests needed to gain additional skips to account for this change. There is a good chance that some tests are missing skips for some libraries that are not the first point of failure, but it's hard to test explicitly for these in one go. * Fix typo in coverage workflow * Try relaxing ipython constraints * Squash newly exposed lint failures * Fix typo in tutorials pipeline * Update the 'also update' comments * Remove unneeded qiskit-toqm dependency * Section requirements-optional.txt * Test all optionals on min not max Python version Optionals are generally more likely to have been made available on the older Pythons, and some may take excessively long to provide wheels for the latest versions of Python. * Add missing test skip * Fix optional call * Use correct boolean syntax * Fix tests relying on Jupyter * Install ipykernel in tutorials * Remove HAS_PDFLATEX skip from quantum_info tests For simple LaTeX tests, IPython/Jupyter can handle the compilation internally using MathJax, and doesn't actually need a `pdflatex` installation. We only need that when we're depending on LaTeX libraries that are beyond what MathJax can handle natively. * Include additional tutorials dependencies * Install all of Terra's optionals in tutorial run * Do not install all optionals in docs build * Use class-level skips where appropriate * Do not install ibmq-provider in tutorials run * Include matplotlib in docs requirements * Remove unnecessary whitespace * Split long pip line * Only install graphviz when installOptionals Co-authored-by: Eric Arellano <[email protected]> * Install visualization extras in docs build * Don't `--upgrade` when installing optionals This is to prevent any optionals that have a dependency on Terra from potentially upgrading it to some PyPI version during their installation. This shouldn't happen with the current development model of having only one supported stable branch and the main branch, but the `-U` is unnecessary, and not having it is safer for the future. * Update secondary installation of Terra in docs build * Install all optionals during the docs build I yoyo-ed on this, not wanting it to be too onerous to build the documentation, but in the end, we need to have the optional features installed in order to build most of the documentation of those features, and some unrelated parts of the documentation may use these features to enhance their own output. * Fix test setup job * Remove duplication of matplotlib in requirements files * Update image test installation command * Restore editable build * Move `pip check` to `pip` section * Remove redundant "post-install" description * Expand comment on first-stage choices * pytohn lol --------- Co-authored-by: Eric Arellano <[email protected]>
1 parent d7f02a6 commit 0438a4b

28 files changed

+210
-77
lines changed

.azure/test-linux.yml

+20-15
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ parameters:
1212
- name: "testImages"
1313
type: boolean
1414

15+
- name: "installOptionals"
16+
type: boolean
17+
default: false
18+
1519
- name: "installFromSdist"
1620
type: boolean
1721
default: false
@@ -84,27 +88,27 @@ jobs:
8488
env:
8589
SETUPTOOLS_ENABLE_FEATURES: "legacy-editable"
8690
91+
- ${{ if eq(parameters.installOptionals, true) }}:
92+
- bash: |
93+
set -e
94+
source test-job/bin/activate
95+
python -m pip install -r requirements-optional.txt -c constraints.txt
96+
python -m pip check
97+
displayName: "Install optional packages"
98+
99+
- bash: |
100+
set -e
101+
sudo apt-get update
102+
sudo apt-get install -y graphviz
103+
displayName: 'Install optional non-Python dependencies'
104+
87105
- bash: |
88106
set -e
89107
source test-job/bin/activate
90-
python -m pip install -U \
91-
-c constraints.txt \
92-
"cplex ; python_version < '3.11'" \
93-
"qiskit-aer" \
94-
"tweedledum ; python_version < '3.11'" \
95-
"z3-solver"
96108
mkdir -p /tmp/terra-tests
97109
cp -r test /tmp/terra-tests/.
98110
cp .stestr.conf /tmp/terra-tests/.
99111
cp -r .stestr /tmp/terra-tests/. || :
100-
sudo apt-get update
101-
sudo apt-get install -y graphviz
102-
pip check
103-
displayName: 'Install post-install optional dependencies'
104-
105-
- bash: |
106-
set -e
107-
source test-job/bin/activate
108112
pushd /tmp/terra-tests
109113
export PYTHONHASHSEED=$(python -S -c "import random; print(random.randint(1, 4294967295))")
110114
echo "PYTHONHASHSEED=$PYTHONHASHSEED"
@@ -178,7 +182,8 @@ jobs:
178182
-c constraints.txt \
179183
-r requirements.txt \
180184
-r requirements-dev.txt \
181-
-e ".[visualization]"
185+
-r requirements-optional.txt \
186+
-e .
182187
sudo apt-get update
183188
sudo apt-get install -y graphviz pandoc
184189
image_tests/bin/pip check

.azure/test-macos.yml

+11
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ parameters:
33
type: string
44
displayName: "Version of Python to test"
55

6+
- name: "installOptionals"
7+
type: boolean
8+
default: false
9+
610
jobs:
711
- job: "MacOS_Tests_Python${{ replace(parameters.pythonVersion, '.', '') }}"
812
displayName: "Test macOS Python ${{ parameters.pythonVersion }}"
@@ -45,6 +49,13 @@ jobs:
4549
env:
4650
SETUPTOOLS_ENABLE_FEATURES: "legacy-editable"
4751
52+
- ${{ if eq(parameters.installOptionals, true) }}:
53+
- bash: |
54+
set -e
55+
source test-job/bin/activate
56+
pip install -r requirements-optional.txt -c constraints.txt
57+
displayName: "Install optional packages"
58+
4859
- bash: |
4960
set -e
5061
source test-job/bin/activate

.azure/test-windows.yml

+12-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ parameters:
33
type: string
44
displayName: "Versions of Python to test"
55

6+
- name: "installOptionals"
7+
type: boolean
8+
default: false
9+
610
jobs:
711
- job: "Windows_Tests_Python${{ replace(parameters.pythonVersion, '.', '') }}"
812
displayName: "Test Windows Python ${{ parameters.pythonVersion }}"
@@ -38,13 +42,20 @@ jobs:
3842
-c constraints.txt \
3943
-r requirements.txt \
4044
-r requirements-dev.txt \
41-
"z3-solver" \
4245
-e .
4346
pip check
4447
displayName: 'Install dependencies'
4548
env:
4649
SETUPTOOLS_ENABLE_FEATURES: "legacy-editable"
4750
51+
- ${{ if eq(parameters.installOptionals, true) }}:
52+
- bash: |
53+
set -e
54+
source test-job/Scripts/activate
55+
pip install -c constraints.txt -r requirements-optional.txt
56+
pip check
57+
displayName: "Install optional packages"
58+
4859
- bash: |
4960
set -e
5061
chcp.com 65001

.azure/tutorials-linux.yml

+2-10
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,8 @@ jobs:
2626
-c constraints.txt \
2727
-r requirements.txt \
2828
-r requirements-dev.txt \
29-
"qiskit-ibmq-provider" \
30-
"qiskit-aer" \
31-
"z3-solver" \
32-
"networkx" \
33-
"matplotlib>=3.3.0" \
34-
sphinx \
35-
nbsphinx \
36-
sphinx_rtd_theme \
37-
"tweedledum ; python_version < '3.11'" \
38-
cvxpy \
29+
-r requirements-optional.txt \
30+
-r requirements-tutorials.txt \
3931
-e .
4032
sudo apt-get update
4133
sudo apt-get install -y graphviz pandoc

.github/workflows/coverage.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ jobs:
5252
- name: Generate unittest coverage report
5353
run: |
5454
set -e
55-
python -m pip install -c constraints.txt -r requirements-dev.txt qiskit-aer
55+
python -m pip install -c constraints.txt -r requirements-dev.txt -r requirements-optional.txt
5656
stestr run
5757
# We set the --source-dir to '.' because we want all paths to appear relative to the repo
5858
# root (we need to combine them with the Python ones), but we only care about `grcov`

azure-pipelines.yml

+17-2
Original file line numberDiff line numberDiff line change
@@ -103,14 +103,17 @@ stages:
103103
testQPY: false
104104
testImages: false
105105
testRust: false
106+
installOptionals: true
106107

107108
- template: ".azure/test-macos.yml"
108109
parameters:
109110
pythonVersion: ${{ version }}
111+
installOptionals: true
110112

111113
- template: ".azure/test-windows.yml"
112114
parameters:
113115
pythonVersion: ${{ version }}
116+
installOptionals: true
114117

115118
- stage: "Nightly_Failure"
116119
displayName: "Comment on nightly failure"
@@ -150,9 +153,15 @@ stages:
150153
- template: ".azure/test-linux.yml"
151154
parameters:
152155
pythonVersion: ${{ parameters.minimumPythonVersion }}
156+
# A PR is more likely to fail CI because it introduces a logic error
157+
# into an existing test than because it adds a new test / optional
158+
# dependency that isn't accounted for in the test-skipping logic
159+
# (and such a failure would need fewer iterations to fix). We want
160+
# to fail fast in the first CI stage.
161+
installOptionals: true
153162
testRust: true
154163
testQPY: true
155-
testImages: false
164+
testImages: true
156165

157166
# The rest of the PR pipeline is to test the oldest and newest supported
158167
# versions of Python, along with the integration tests (via the tutorials).
@@ -172,24 +181,29 @@ stages:
172181
pythonVersion: ${{ parameters.maximumPythonVersion }}
173182
testRust: false
174183
testQPY: false
175-
testImages: true
184+
testImages: false
176185
installFromSdist: true
186+
installOptionals: false
177187

178188
- template: ".azure/test-macos.yml"
179189
parameters:
180190
pythonVersion: ${{ parameters.minimumPythonVersion }}
191+
installOptionals: true
181192

182193
- template: ".azure/test-macos.yml"
183194
parameters:
184195
pythonVersion: ${{ parameters.maximumPythonVersion }}
196+
installOptionals: false
185197

186198
- template: ".azure/test-windows.yml"
187199
parameters:
188200
pythonVersion: ${{ parameters.minimumPythonVersion }}
201+
installOptionals: true
189202

190203
- template: ".azure/test-windows.yml"
191204
parameters:
192205
pythonVersion: ${{ parameters.maximumPythonVersion }}
206+
installOptionals: false
193207

194208
# Push to main or the stable branches. The triggering branches also need to
195209
# be in the triggers at the top of this file.
@@ -202,6 +216,7 @@ stages:
202216
testRust: true
203217
testQPY: true
204218
testImages: true
219+
installOptionals: false
205220

206221
# Push to a tag. The triggering tags are set in the triggers at the top of
207222
# this file.

qiskit/transpiler/passes/layout/_csp_custom_solver.py

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
class CustomSolver(RecursiveBacktrackingSolver):
2626
"""A wrap to RecursiveBacktrackingSolver to support ``call_limit``"""
2727

28+
# pylint: disable=invalid-name
29+
2830
def __init__(self, call_limit=None, time_limit=None):
2931
self.call_limit = call_limit
3032
self.time_limit = time_limit

qiskit/utils/optionals.py

+8
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@
8787
- Some methods of gradient calculation within :mod:`.opflow.gradients` require `JAX
8888
<https://github.com/google/jax>`__ for autodifferentiation.
8989
90+
* - .. py:data:: HAS_JUPYTER
91+
- Some of the tests require a complete `Jupyter <https://jupyter.org/>`__ installation to test
92+
interactivity features.
93+
9094
* - .. py:data:: HAS_MATPLOTLIB
9195
- Qiskit Terra provides several visualisation tools in the :mod:`.visualization` module.
9296
Almost all of these are built using `Matplotlib <https://matplotlib.org/>`__, which must
@@ -205,6 +209,9 @@
205209
.. autoclass:: qiskit.utils.LazySubprocessTester
206210
"""
207211

212+
# NOTE: If you're changing this file, sync it with `requirements-optional.txt` and potentially
213+
# `setup.py` as well.
214+
208215
import logging as _logging
209216

210217
from .lazy_tester import (
@@ -256,6 +263,7 @@
256263
name="jax",
257264
install="pip install jax",
258265
)
266+
HAS_JUPYTER = _LazyImportTester(["jupyter", "nbformat", "nbconvert"], install="pip install jupyter")
259267
HAS_MATPLOTLIB = _LazyImportTester(
260268
("matplotlib.patches", "matplotlib.pyplot"),
261269
name="matplotlib",

qiskit/visualization/bloch.py

+2
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@
6262
class Arrow3D(Patch3D, FancyArrowPatch):
6363
"""Makes a fancy arrow"""
6464

65+
# pylint: disable=missing-function-docstring,invalid-name
66+
6567
# Nasty hack around a poorly implemented deprecation warning in Matplotlib 3.5 that issues two
6668
# deprecation warnings if an artist's module does not claim to be part of the below module.
6769
# This revolves around the method `Patch3D.do_3d_projection(self, renderer=None)`. The

requirements-dev.txt

+28-19
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,39 @@
1-
coverage>=4.4.0,<7.0
2-
hypothesis>=4.24.3
3-
python-constraint>=1.4
4-
ipython<7.22.0
5-
ipykernel<5.5.2
6-
ipywidgets>=7.3.0
7-
jupyter
8-
matplotlib>=3.3
9-
pillow>=4.2.1
1+
# Requirements to develop Terra, and the minimum needed to run its CI. All
2+
# optional requirements should go in `requirements-optionals.txt` instead.
3+
#
4+
# Version requirements here can be more restrictive than elsewhere, because they
5+
# never become actual package requirements, but still try to be as relaxed as
6+
# possible so it's easy to develop multiple packages from the same venv.
7+
8+
# Style
109
black[jupyter]~=22.0
11-
pydot
10+
11+
12+
# Lint
13+
#
14+
# These versions are pinned precisely because pylint frequently includes new
15+
# on-by-default lint failures in new versions, which breaks our CI.
1216
astroid==2.14.2
1317
pylint==2.16.2
1418
ruff==0.0.267
19+
20+
21+
# Tests
22+
coverage>=4.4.0
23+
hypothesis>=4.24.3
1524
stestr>=2.0.0,!=4.0.0
16-
pylatexenc>=1.4
1725
ddt>=1.2.0,!=1.4.0,!=1.4.3
18-
seaborn>=0.9.0
26+
27+
28+
# Documentation tooling.
29+
#
30+
# This alone is not sufficient to fully build the documentation, because several
31+
# components of Terra use some of its optional dependencies in order to document
32+
# themselves. These are the requirements that are _only_ required for the docs
33+
# build, and are not used by Terra itself.
34+
1935
# TODO: switch to stable release when 4.1 is released
2036
reno @ git+https://github.com/openstack/reno.git@81587f616f17904336cdc431e25c42b46cd75b8f
2137
Sphinx>=5.0
2238
qiskit-sphinx-theme~=1.11.0
2339
sphinx-design>=0.2.0
24-
pygments>=2.4
25-
scikit-learn>=0.20.0
26-
scikit-quant<=0.7;platform_system != 'Windows'
27-
jax;platform_system != 'Windows'
28-
jaxlib;platform_system != 'Windows'
29-
docplex
30-
qiskit-qasm3-import

requirements-optional.txt

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Optional dependencies of Terra that can (mostly) reliably be installed with
2+
# `pip`. This file is still called `requirements-optional.txt` just to match
3+
# standard pip conventions, even though none of these are required.
4+
#
5+
# If updating this, you probably want to update `qiskit.utils.optionals` and
6+
# maybe `setup.py` too.
7+
8+
# Test-runner enhancements.
9+
fixtures
10+
testtools
11+
jupyter
12+
13+
# Interactivity.
14+
ipykernel
15+
ipython
16+
ipywidgets>=7.3.0
17+
matplotlib>=3.3
18+
pillow>=4.2.1
19+
pydot
20+
pygments>=2.4
21+
pylatexenc>=1.4
22+
seaborn>=0.9.0
23+
24+
# Functionality and accelerators.
25+
qiskit-aer
26+
qiskit-qasm3-import
27+
python-constraint>=1.4
28+
cplex; python_version < '3.11'
29+
cvxpy
30+
docplex
31+
jax; platform_system != 'Windows'
32+
jaxlib; platform_system != 'Windows'
33+
scikit-learn>=0.20.0
34+
scikit-quant<=0.7; platform_system != 'Windows'
35+
SQSnobFit
36+
z3-solver>=4.7
37+
# Tweedledum is unmaintained and its existing Mac wheels are unreliable. If you
38+
# manage to get a working install on a Mac the functionality should still work,
39+
# but as a convenience this file won't attempt the install itself.
40+
tweedledum; python_version<'3.11' and platform_system!="Darwin"

requirements-tutorials.txt

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Requirements for the tutorials CI run that go beyond the others in `requirements-optional.txt`.
2+
# This may also include some requirements that are only in `requirements-dev.txt`, since those
3+
# aren't runtime dependencies or optionals of Terra.
4+
5+
networkx>=2.2
6+
jupyter
7+
Sphinx
8+
nbsphinx
9+
qiskit_sphinx_theme
10+
pyscf

setup.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@
3131
flags=re.S | re.M,
3232
)
3333

34-
3534
# If RUST_DEBUG is set, force compiling in debug mode. Else, use the default behavior of whether
3635
# it's an editable installation.
3736
rust_debug = True if os.getenv("RUST_DEBUG") == "1" else None
3837

39-
38+
# If modifying these optional extras, make sure to sync with `requirements-optional.txt` and
39+
# `qiskit.utils.optionals` as well.
4040
qasm3_import_extras = [
4141
"qiskit-qasm3-import>=0.1.0",
4242
]

0 commit comments

Comments
 (0)