Skip to content

Commit

Permalink
Poison import if Qiskit 1.0+ is detected (#11617)
Browse files Browse the repository at this point in the history
* Poison import if Qiskit 1.0+ is detected

This uses `importlib.metadata` to search for installations of Qiskit 1.0
at runtime, and poison the import if one is detected.  The two packages
are incompatible in a way that we cannot express to `pip` without having
poisoned the `qiskit-terra` package as a whole, which is something we're
less willing to do in order to keep it easier to install old versions
of Qiskit-dependent software, and to keep the Qiskit 1.0 packaging story
clean for the coming years.

It is not generally expected that a user specifically attempting to
install Qiskit 0.45/0.46 will accidentally install Qiskit 1.0 as well.
The intention of this poisoning in the "stable" branch is so that the
case that a user installs Qiskit 1.0, but either also includes an old
package with a dependency purely on `qiskit-terra`, or runs a subsequent
`pip install` command whose version resolution causes `qiskit-terra` to
become installed.  In both these cases, it could be the case that the
`import qiskit` command finds the `qiskit-terra` `__init__.py` file,
and so any error we also place in Qiskit 1.0 would have been skipped.

* Hide inner variable from init

* Add shortlink to migration guide

* Improve release note

* Use specific version ranges

Co-authored-by: Matthew Treinish <[email protected]>

---------

Co-authored-by: Matthew Treinish <[email protected]>
  • Loading branch information
jakelishman and mtreinish authored Jan 31, 2024
1 parent 6730bdf commit 94ea49d
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
22 changes: 22 additions & 0 deletions qiskit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,31 @@

"""Main Qiskit public functionality."""

import os
import pkgutil
import sys
import warnings
import importlib.metadata

try:
_qiskit_version = importlib.metadata.version("qiskit")
except importlib.metadata.PackageNotFoundError:
# Terra doesn't care if there's no metapackage installed.
pass
else:
_major, _ = _qiskit_version.split(".", 1)
_suppress_error = os.environ.get("QISKIT_SUPPRESS_1_0_IMPORT_ERROR", False) == "1"
if int(_major) > 0 and not _suppress_error:
raise ImportError(
"Qiskit is installed in an invalid environment that has both Qiskit >=1.0"
" and an earlier version."
" You should create a new virtual environment, and ensure that you do not mix"
" dependencies between Qiskit <1.0 and >=1.0."
" Any packages that depend on 'qiskit-terra' are not compatible with Qiskit 1.0 and"
" will need to be updated."
" Qiskit unfortunately cannot enforce this requirement during environment resolution."
" See https://qisk.it/packaging-1-0 for more detail."
)

import qiskit._accelerate

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
prelude: |
Qiskit 0.45.3 is a point release with no code changes other than to raise an :exc:`ImportError`
if it detects it has been installed in an invalid environment with Qiskit 1.0+.
Please read `our migration guide about the new packaging <https://qisk.it/1-0-packaging-migration>`__
for help on errors, preparing for Qiskit 1.0, and more detailed background information.
The packaging structure of Qiskit is changing in Qiskit 1.0, and unfortunately the changed
requirements cannot be fully communicated to ``pip``, especially if ``pip install --upgrade``
commands are run after the environment has been initially configured. All versions of Qiskit
prior to 1.0 (including this one) have an installation conflict with Qiskit 1.0 that ``pip``
will not resolve.
If ``import qiskit`` raises an :exc:`ImportError` for you, your environment is in an invalid
state, and versions of Qiskit 0.45/0.46 and 1.0 are both reachable, which will result in subtley
broken code. You will need to create a new virtual environment, and ensure that *only* one of
the two versions are installed. In particular, if you are intending to install Qiskit 1.0,
you must have no packages that depend on ``qiskit-terra`` installed; these packages are
incompatible with Qiskit 1.0 and must be updated. If you are intending to install Qiskit 0.45
or 0.46, you must ensure that you have nothing attempting to install ``qiskit>=1.0``.
If you develop a library based on Qiskit and you still have a dependency on ``qiskit-terra``,
you should urgently release a new package that depends only on ``qiskit``. Since version 0.44,
the ``qiskit`` package contained only the ``qiskit-terra`` compiler core (the component that is
now simply called "Qiskit"), so if your minimum version is ``0.44``, you can safely switch a
``qiskit-terra>=0.44`` dependency to ``qiskit>=0.44`` with no change in what will be installed.
For more detail and recommendations for testing and preparation, see the
`section for developers of the migration guide <https://qisk.it/1-0-packaging-migration#for-developers>`__.

0 comments on commit 94ea49d

Please sign in to comment.