Skip to content

Commit

Permalink
Add python 3.8 support and deprecate python 3.5 (#3268)
Browse files Browse the repository at this point in the history
* Add python 3.8 support and deprecate python 3.5

This commit adds support for running terra under python 3.8. It does
this by adding the trove classifiers to the package metadata and adding
a test job for python 3.8 (only travis for now this can be expanded in
the future when azure pipelines adds it to their image). At the same
time this commit starts the deprecation window for python 3.5. Python
3.5 goes end of life by upstream python in Sept. 2020. We should give
our users running with python 3.5 (which is about 10% of our users based
on pypi data) fair notice that when upstream python stops supporting it
we do as well.

* Fix lint

* Add back empty cache detection

As part of the refactors the empty stestr timing cache removal code was
removed from the travis config, but the cache wasn't removed. Adding the
python 3.8 job causes a failure because travis has no cached timing data
but still creates the empty directory which triggers
mtreinish/stestr#266. This adds back the empty cache removal to
workaround it so we can use the timing data for scheduling in future
runs.

* Add azure-pipelines python 3.8 jobs too

* Fix python 3.8 dictionary keys changed error

Starting in python 3.8 a new RuntimeError is raised, RuntimeError:
dictionary keys changed during iteration. This is caused by modifying an
iterator while looping over it. We were doing that in the
optimize_swap_before_measure pass. This commit fixes this by wrapping
the iterator in list() to make a copy of it for looping. This way we
don't modify the contents of what we're iterating over in the pass.

* Revert "Add azure-pipelines python 3.8 jobs too"

The missing matplotlib wheels are blockers for windows and osx
environment. Since we do not have the necessary dependencies installed
in those ci envs to compile matplotlib from source. We'll rely on just
travis for 3.8 testing until the matplotlib 3.2.0 release is pushed so
we don't have to compile it.

This reverts commit 4015762.

* Add skip for failing matplotlib test

The image comparison tests which are quite flaky are failing with
matplotlib compiled on 3.8. Looking at the image output from these
failures are very subtle (looks like resolution differences) again
questioning the value of these tests. This commit just skips the test
that is failing here to unblock the PR.

* Add azure 3.8 test jobs

* Pin to pre-release mpl for python 3.8

* Add spawn guard for python3.8 osx in examples

When running examples with execute, transpile, or any other calls using
parallel_map() the new default for spawn instead of fork requires that
scripts have a __name__ == "__main__" check in them to function
properly. If not calls to parallel_map fail errors around the
bootstrapping phase. To avoid this in the ci jobs this commit adds the
necessary checks to the example scripts we run in ci as part of
test_examples.

* Remove cryptography pin from constraints file

We pinned the cryptography package version back during the cryptography
2.6 release which broke our ci. It was a temporary step to avoid a
packaging issue in CI that was blocking development. However, when the
issue was resolved we never circled back to fix the issue. Now trying to
enable python 3.8 support to terra cryptography >=2.8 is needed for
python 3.8 on windows (to get a precompiled binary). This commit removes
the unecessary pin to unblock windows 3.8 ci.

* Bump cibuildwheel version to build 3.8 wheels

cibuildwheel 1.0.0 was released in early November [1] and added support
for building python 3.8 wheels. This commit bumps the cibuildwheel
version we use in the wheel build jobs at release time to also build 3.8
wheels for upload to pypi.

* Add skip and release note about macos py38 issues

This commit adds a skip for the failing python 3.8 test on osx and
windows so that we don't block everything over a small issue in the
tests. It also add a release note documenting the limitation with python
3.8 on macos with regardess to parallel_map/multiprocessing. Since this
limitation is new for this release (being the first release with python
3.8 support) we should document it as a known issue in the release
notes, especially since it likely won't be resolved until a python 3.8.1
release.

* Revert "Add spawn guard for python3.8 osx in examples"

While we can fix the tests to work on osx python3.8 by adjusting the
example scripts to only call functions using parallel_map from inside a
block run via if __name__ == '__main__': this unecessarily changes the
scripts for the quirks of a single environment. This commit reverts the
example scripts back to their original form and instead just skips the
unittest that executes them on python 3.8 macOS. We already have
documented this limitation in the release notes. When/if we have an
alternative solution for how we launch additional processes in python
3.8 on macOS that does not require this workaround we can look at
removing the skip.

This reverts commit 76ae197.

* Apply suggestions from code review

Co-Authored-By: Kevin Krsulich <kevin@krsulich.net>
  • Loading branch information
2 people authored and Luciano Bello committed Dec 10, 2019
1 parent c028aee commit f17f8f0
Show file tree
Hide file tree
Showing 11 changed files with 97 additions and 6 deletions.
10 changes: 10 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ stage_generic: &stage_generic
- stestr run
after_failure:
- python tools/report_ci_failure.py
before_script:
- |
if [ ! "$(ls -A .stestr)" ]; then
rm -rf .stestr
fi
stage_linux: &stage_linux
<<: *stage_generic
Expand All @@ -56,6 +62,10 @@ jobs:
- pip install diff-cover || true
- diff-cover --compare-branch master coverage.xml || true

- name: Python 3.8 Tests
<<: *stage_linux
python: 3.8

# Randomized testing
- name: Randomized tests
<<: *stage_linux
Expand Down
12 changes: 9 additions & 3 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ stages:
- bash: |
set -e
python -m pip install --upgrade pip
pip install cibuildwheel==0.11.1
pip install cibuildwheel==1.0.0
pip install -U twine
cibuildwheel --output-dir wheelhouse .
- task: PublishBuildArtifacts@1
Expand Down Expand Up @@ -74,7 +74,7 @@ stages:
- bash: |
set -e
python -m pip install --upgrade pip
pip install cibuildwheel==0.11.1
pip install cibuildwheel==1.0.0
pip install -U twine
cibuildwheel --output-dir wheelhouse .
- task: PublishBuildArtifacts@1
Expand Down Expand Up @@ -104,7 +104,7 @@ stages:
- bash: |
set -e
python -m pip install --upgrade pip
pip install cibuildwheel==0.11.1
pip install cibuildwheel==1.0.0
pip install -U twine
cibuildwheel --output-dir wheelhouse
- task: PublishBuildArtifacts@1
Expand Down Expand Up @@ -286,6 +286,8 @@ stages:
python.version: '3.6'
Python37:
python.version: '3.7'
Python38:
python.version: '3.8'
steps:
- task: UsePythonVersion@0
inputs:
Expand Down Expand Up @@ -338,6 +340,8 @@ stages:
python.version: '3.6'
Python37:
python.version: '3.7'
Python38:
python.version: '3.8'
steps:
- task: UsePythonVersion@0
inputs:
Expand Down Expand Up @@ -391,6 +395,8 @@ stages:
python.version: '3.6'
Python37:
python.version: '3.7'
Python38:
python.version: '3.8'
steps:
- task: UsePythonVersion@0
inputs:
Expand Down
2 changes: 1 addition & 1 deletion constraints.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
astroid==2.2.5
cryptography==2.5.0
pylint==2.3.1
matplotlib==3.2.0rc1;python_version=='3.8'
8 changes: 8 additions & 0 deletions qiskit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"""Main Qiskit public functionality."""

import pkgutil
import sys
import warnings

# First, check for required Python and API version
Expand Down Expand Up @@ -70,4 +71,11 @@
from .version import _get_qiskit_versions


if sys.version_info[0] == 3 and sys.version_info[1] == 5:
warnings.warn(
"Using Qiskit with Python 3.5 is deprecated as of the 0.12.0 release. "
"Support for running Qiskit with Python 3.5 will be removed at the "
"Python 3.5 EoL on 09/13/2020.", DeprecationWarning)


__qiskit_version__ = _get_qiskit_versions()
2 changes: 1 addition & 1 deletion qiskit/transpiler/passes/optimize_swap_before_measure.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def run(self, dag):
measure_layer.add_qreg(qreg)
for creg in dag.cregs.values():
measure_layer.add_creg(creg)
for successor in dag.successors(swap):
for successor in list(dag.successors(swap)):
if successor.type == 'op' and successor.op.name == 'measure':
# replace measure node with a new one, where qargs is set with the "other"
# swap qarg.
Expand Down
54 changes: 54 additions & 0 deletions releasenotes/notes/deprecate-python-3.5-5bc0aadebc79d6b5.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
issues:
- |
Running functions that use ``qiskit.tools.parallel_map()`` (for example
``qiskit.execute``, ``qiskit.transpile``, and
``qiskit.transpiler.passmanager.PassManager.run()``) may not work when
called from a script running outside of a ``if __name__ == '__main__':``
block when using Python 3.8 on MacOS. Other environments are uneffected by
this issue. This is due to changes in how parallel processes are launched
by Python 3.8 on MacOS. If ``RuntimeError`` or ``AttributeError`` are raised
by scripts that are directly calling ``parallel_map()`` or when
calling a function that uses it internally with Python 3.8 on MacOS
embedding the script calls inside ``if __name__ == '__main__':`` should
workaround the issue. For example::
from qiskit import QuantumCircuit, QiskitError
from qiskit import execute, BasicAer
qc1 = QuantumCircuit(2, 2)
qc1.h(0)
qc1.cx(0, 1)
qc1.measure([0,1], [0,1])
# making another circuit: superpositions
qc2 = QuantumCircuit(2, 2)
qc2.h([0,1])
qc2.measure([0,1], [0,1])
execute([qc1, qc2], BasicAer.get_backend('qasm_simulator'))
should be changed to::
from qiskit import QuantumCircuit, QiskitError
from qiskit import execute, BasicAer
def main():
qc1 = QuantumCircuit(2, 2)
qc1.h(0)
qc1.cx(0, 1)
qc1.measure([0,1], [0,1])
# making another circuit: superpositions
qc2 = QuantumCircuit(2, 2)
qc2.h([0,1])
qc2.measure([0,1], [0,1])
execute([qc1, qc2], BasicAer.get_backend('qasm_simulator'))
if __name__ == '__main__':
main()
if errors are encountered with Python 3.8 on MacOS.
deprecations:
- |
Python 3.5 support in qiskit-terra is deprecated. Support will be
removed on the upstream python community's end of life date for the version,
which is 09/13/2020.
2 changes: 2 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,11 @@
"Operating System :: Microsoft :: Windows",
"Operating System :: MacOS",
"Operating System :: POSIX :: Linux",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Topic :: Scientific/Engineering",
],
keywords="qiskit sdk quantum",
Expand Down
6 changes: 6 additions & 0 deletions test/python/test_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ class TestPythonExamples(QiskitTestCase):
"""Test example scripts"""

@unittest.skipIf(os.name == 'nt', 'Skip on windows until #2616 is fixed')
@unittest.skipIf(sys.platform == 'darwin' and sys.version_info[1] == 8,
"Multiprocess spawn fails on macOS python 3.8 without "
"__name__ == '__main__' guard")
def test_all_examples(self):
"""Execute the example python files and pass if it returns 0."""
examples = []
Expand All @@ -52,6 +55,9 @@ def test_all_examples(self):
self.assertEqual(run_example.returncode, 0, error_string)

@unittest.skipIf(os.name == 'nt', 'Skip on windows until #2616 is fixed')
@unittest.skipIf(sys.platform == 'darwin' and sys.version_info[1] == 8,
"Multiprocess spawn fails on macOS python 3.8 without "
"__name__ == '__main__' guard")
@online_test
@slow_test
def test_all_ibmq_examples(self, qe_token, qe_url):
Expand Down
4 changes: 4 additions & 0 deletions test/python/tools/jupyter/test_notebooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"""Tests for the wrapper functionality."""

import os
import sys
import unittest

import nbformat
Expand Down Expand Up @@ -58,6 +59,9 @@ def _execute_notebook(self, filename, qe_token=None, qe_url=None):
execute_preprocessor.preprocess(
notebook, {'metadata': {'path': self.execution_path}})

@unittest.skipIf(
sys.version_info[0] == 3 and sys.version_info[1] == 8 and
sys.platform != 'linux', 'Fails with Python 3.8 on osx and windows')
def test_jupyter_jobs_pbars(self):
"""Test Jupyter progress bars and job status functionality"""
self._execute_notebook(self._get_resource_path(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ def test_plot_barriers(self):

@unittest.skipIf(not visualization.HAS_MATPLOTLIB,
'matplotlib not available.')
@unittest.skip('Unreliable across python version')
def test_long_name(self):
"""Test to see that long register names can be seen completely
As reported in #2605
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tox]
minversion = 2.1
envlist = py35, py36, py37, lint
envlist = py35, py36, py37, py38, lint
skipsdist = True

[testenv]
Expand Down

0 comments on commit f17f8f0

Please sign in to comment.