From 2feb8f9581dfbff3876a1bd78ea9e66bb6d68442 Mon Sep 17 00:00:00 2001 From: Jake Lishman Date: Wed, 15 Nov 2023 09:22:26 +0000 Subject: [PATCH 1/4] Replace `qiskit` metapackage with `qiskit-terra` This commit completely removes the concept of the `qiskit-terra` package from Qiskit main. The hitherto metapackage `qiskit` is promoted to be the concrete code package. This is a completely breaking change for packaging purposes for users, as there is no clean upgrade path from `qiskit-terra` to `qiskit`; PyPI and pip do not give us the tools to mark that the former obsoletes and supersedes the latter. We intend to follow this PR with a technical blog post somewhere explaining the changes, how users should adapt ("to install Qiskit 1.0, you must start a new venv"), and why we needed to do this. The "why", in part, is: - the metapackage legacy causes awkward upgrade paths on every release; some packages still depend on `qiskit-terra`, some on `qiskit`, and pip will happily make those two get out-of-sync when upgrading a transitive dependency with only a warning that users are used to ignoring. - with the 1.0 release, we (believe we) will have some leeway from users to make such a breaking change. - having the metapackage split makes it difficult for downstream projects and developers to test against `main` - they always must install both `qiskit-terra` and `qiskit`, and the latter has no meaning in editable installs, so needs re-installing after each version bump. Problems surrounding this have already broken CI for Qiskit, for at least one internal IBM repo, and at least my dev install of Qiskit. This could be improved a bit with more education, but it's still always going to increase the barrier to entry and make it much harder to do the right thing. We will not publish any 1.0 or above version of `qiskit-terra`. All dependents on Qiskit should switch their requirements to `qiskit`. --- .azure/lint-linux.yml | 5 +- .azure/test-linux.yml | 4 +- .azure/test-macos.yml | 1 - .azure/test-windows.yml | 1 - .github/workflows/coverage.yml | 2 +- .github/workflows/slow.yml | 2 +- .github/workflows/wheels.yml | 30 +------- qiskit_pkg/LICENSE.txt | 1 - qiskit_pkg/MANIFEST.in | 1 - qiskit_pkg/README.md | 1 - qiskit_pkg/setup.py | 74 ------------------- .../notes/terra-nullius-7ef598626d8118c1.yaml | 29 ++++++++ setup.py | 2 +- tools/deploy_translatable_strings.sh | 5 +- tox.ini | 16 ++-- 15 files changed, 44 insertions(+), 130 deletions(-) delete mode 120000 qiskit_pkg/LICENSE.txt delete mode 100644 qiskit_pkg/MANIFEST.in delete mode 120000 qiskit_pkg/README.md delete mode 100644 qiskit_pkg/setup.py create mode 100644 releasenotes/notes/terra-nullius-7ef598626d8118c1.yaml diff --git a/.azure/lint-linux.yml b/.azure/lint-linux.yml index 5855fe1e6e67..a1809bd829bd 100644 --- a/.azure/lint-linux.yml +++ b/.azure/lint-linux.yml @@ -26,7 +26,6 @@ jobs: -c constraints.txt \ -r requirements.txt \ -r requirements-dev.txt \ - ./qiskit_pkg \ -e . # Build and install both qiskit and qiskit-terra so that any optionals # depending on `qiskit` will resolve correctly. @@ -38,7 +37,7 @@ jobs: set -e source test-job/bin/activate echo "Running black, any errors reported can be fixed with 'tox -eblack'" - black --check qiskit test tools examples setup.py qiskit_pkg + black --check qiskit test tools examples setup.py echo "Running rustfmt check, any errors reported can be fixed with 'cargo fmt'" cargo fmt --check displayName: "Formatting" @@ -47,7 +46,7 @@ jobs: set -e source test-job/bin/activate echo "Running ruff" - ruff qiskit test tools examples setup.py qiskit_pkg/setup.py + ruff qiskit test tools examples setup.py echo "Running pylint" pylint -rn qiskit test tools echo "Running Cargo Clippy" diff --git a/.azure/test-linux.yml b/.azure/test-linux.yml index eb456f8497ad..512e1d773c35 100644 --- a/.azure/test-linux.yml +++ b/.azure/test-linux.yml @@ -74,12 +74,11 @@ jobs: python -m pip install -U pip python -m pip install -U build python -m build --sdist . - python -m build --sdist qiskit_pkg python -m pip install -U \ -c constraints.txt \ -r requirements.txt \ -r requirements-dev.txt \ - dist/qiskit*.tar.gz + dist/qiskit-*.tar.gz # Build and install both qiskit and qiskit-terra so that any optionals # depending on `qiskit` will resolve correctly. displayName: "Install Terra from sdist" @@ -92,7 +91,6 @@ jobs: -c constraints.txt \ -r requirements.txt \ -r requirements-dev.txt \ - ./qiskit_pkg \ -e . # Build and install both qiskit and qiskit-terra so that any optionals # depending on `qiskit` will resolve correctly. diff --git a/.azure/test-macos.yml b/.azure/test-macos.yml index cbf2fc8b0e08..c241f51f57e9 100644 --- a/.azure/test-macos.yml +++ b/.azure/test-macos.yml @@ -43,7 +43,6 @@ jobs: -c constraints.txt \ -r requirements.txt \ -r requirements-dev.txt \ - ./qiskit_pkg \ -e . # Build and install both qiskit and qiskit-terra so that any optionals # depending on `qiskit` will resolve correctly. diff --git a/.azure/test-windows.yml b/.azure/test-windows.yml index 6ba2e442946c..f546fdb41dc3 100644 --- a/.azure/test-windows.yml +++ b/.azure/test-windows.yml @@ -42,7 +42,6 @@ jobs: -c constraints.txt \ -r requirements.txt \ -r requirements-dev.txt \ - ./qiskit_pkg \ -e . # Build and install both qiskit and qiskit-terra so that any optionals # depending on `qiskit` will resolve correctly. diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 221840b4e7c6..de3485c5fdce 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -42,7 +42,7 @@ jobs: run: python -m pip install -c constraints.txt --upgrade pip setuptools wheel - name: Build and install qiskit-terra - run: python -m pip install -c constraints.txt -e . ./qiskit_pkg + run: python -m pip install -c constraints.txt -e . env: CARGO_INCREMENTAL: 0 RUSTFLAGS: "-Cinstrument-coverage" diff --git a/.github/workflows/slow.yml b/.github/workflows/slow.yml index 528305740d95..62fa9ec19c62 100644 --- a/.github/workflows/slow.yml +++ b/.github/workflows/slow.yml @@ -19,7 +19,7 @@ jobs: python -m pip install -U pip setuptools wheel python -m pip install -U -r requirements.txt -c constraints.txt python -m pip install -U -r requirements-dev.txt -c constraints.txt - python -m pip install -c constraints.txt -e . ./qiskit_pkg + python -m pip install -c constraints.txt -e . python -m pip install "qiskit-aer" "z3-solver" "cplex" -c constraints.txt env: SETUPTOOLS_ENABLE_FEATURES: "legacy-editable" diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 41b15d89653b..4f2b59f257a0 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -168,7 +168,7 @@ jobs: with: packages-dir: wheelhouse/ sdist: - name: Build and publish terra sdist + name: Build and publish sdist runs-on: ${{ matrix.os }} needs: ["upload_shared_wheels"] environment: release @@ -190,31 +190,3 @@ jobs: run: python -m build . --sdist - name: Publish package distributions to PyPI uses: pypa/gh-action-pypi-publish@release/v1 - metapackage: - name: Build and publish terra sdist - runs-on: ${{ matrix.os }} - needs: ["sdist"] - environment: release - permissions: - id-token: write - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest] - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 - name: Install Python - with: - python-version: '3.10' - - name: Install deps - run: pip install -U twine setuptools-rust wheel build - - name: Build packages - run: | - set -e - cd qiskit_pkg - python -m build . - - name: Publish package distributions to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 - with: - packages-dir: qiskit_pkg/dist diff --git a/qiskit_pkg/LICENSE.txt b/qiskit_pkg/LICENSE.txt deleted file mode 120000 index 4ab43736a839..000000000000 --- a/qiskit_pkg/LICENSE.txt +++ /dev/null @@ -1 +0,0 @@ -../LICENSE.txt \ No newline at end of file diff --git a/qiskit_pkg/MANIFEST.in b/qiskit_pkg/MANIFEST.in deleted file mode 100644 index 42eb4101e514..000000000000 --- a/qiskit_pkg/MANIFEST.in +++ /dev/null @@ -1 +0,0 @@ -include LICENSE.txt diff --git a/qiskit_pkg/README.md b/qiskit_pkg/README.md deleted file mode 120000 index 32d46ee883b5..000000000000 --- a/qiskit_pkg/README.md +++ /dev/null @@ -1 +0,0 @@ -../README.md \ No newline at end of file diff --git a/qiskit_pkg/setup.py b/qiskit_pkg/setup.py deleted file mode 100644 index ecff044d2ac5..000000000000 --- a/qiskit_pkg/setup.py +++ /dev/null @@ -1,74 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2018. -# -# 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. - -# This file is the setup.py file for the qiskit package. Because python -# packaging doesn't offer a mechanism to have qiskit supersede qiskit-terra -# and cleanly upgrade from one to the other, there needs to be a separate -# package shim to ensure no matter how people installed qiskit < 0.45.0 the -# upgrade works. - -import os - -from setuptools import setup - -README_PATH = os.path.join(os.path.abspath(os.path.dirname(__file__)), "README.md") -with open(README_PATH) as readme_file: - README = readme_file.read() - -requirements = ["qiskit-terra==1.0.0"] - -setup( - name="qiskit", - version="1.0.0", - description="Software for developing quantum computing programs", - long_description=README, - long_description_content_type="text/markdown", - url="https://qiskit.org/", - author="Qiskit Development Team", - author_email="hello@qiskit.org", - license="Apache 2.0", - py_modules=[], - packages=[], - classifiers=[ - "Environment :: Console", - "License :: OSI Approved :: Apache Software License", - "Intended Audience :: Developers", - "Intended Audience :: Science/Research", - "Operating System :: Microsoft :: Windows", - "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", - "Topic :: Scientific/Engineering", - ], - keywords="qiskit sdk quantum", - install_requires=requirements, - project_urls={ - "Bug Tracker": "https://github.com/Qiskit/qiskit/issues", - "Documentation": "https://qiskit.org/documentation/", - "Source Code": "https://github.com/Qiskit/qiskit", - }, - include_package_data=True, - python_requires=">=3.8", - extras_require={ - "qasm3-import": ["qiskit-terra[qasm3-import]"], - "visualization": ["qiskit-terra[visualization]"], - "crosstalk-pass": ["qiskit-terra[crosstalk-pass]"], - "csp-layout-pass": ["qiskit-terra[csp-layout-pass]"], - "all": ["qiskit-terra[all]"], - }, -) diff --git a/releasenotes/notes/terra-nullius-7ef598626d8118c1.yaml b/releasenotes/notes/terra-nullius-7ef598626d8118c1.yaml new file mode 100644 index 000000000000..c6c1fe3867b9 --- /dev/null +++ b/releasenotes/notes/terra-nullius-7ef598626d8118c1.yaml @@ -0,0 +1,29 @@ +--- +critical: + - | + You cannot upgrade in place to Qiskit 1.0. You must begin a new virtual environment. + + From Qiskit 1.0, Qiskit is comprised of exactly one Python package: ``qiskit``. Previously, + as a legacy of the "component elements" of early Qiskit, the ``qiskit`` package was a + dependency-only "metapackage", and the core code of Qiskit was in a package called ``qiskit-terra``. + As Qiskit grew, the other elements split off into their own packages (such as ``qiskit-aer``) + until only the core was left in the metapackage. For Qiskit 1.0, we are removing the metapackage + entirely, and replacing it with the actual Qiskit code. + + This means that you cannot upgrade an existing installation to Qiskit 1.0. Instead, you must + create a new Python virtual environment. Using the built-in ``venv`` module, you can do (Linux + and Mac): + + .. code-block:: bash + + # Create the new environment (only once). + python -m venv ~/qiskit-1.0-venv + # Activate the environment (every session). + source ~/qiskit-1.0-venv/bin/activate + # Install Qiskit (only once). + pip install 'qiskit>=1.0' + + On Windows, replace ``source /bin/activate`` with ``source /Scripts/activate``. + + If you are a library author, or have code that depends on Qiskit, you should update any old + dependencies on ``qiskit-terra`` to instead depend on ``qiskit``. diff --git a/setup.py b/setup.py index 751a151f21fc..55950efef410 100644 --- a/setup.py +++ b/setup.py @@ -56,7 +56,7 @@ setup( - name="qiskit-terra", + name="qiskit", version="1.0.0", description="Software for developing quantum computing programs", long_description=README, diff --git a/tools/deploy_translatable_strings.sh b/tools/deploy_translatable_strings.sh index afac6869447d..1ae60b5f7072 100755 --- a/tools/deploy_translatable_strings.sh +++ b/tools/deploy_translatable_strings.sh @@ -84,8 +84,9 @@ rm -rf \ echo "+ 'cp' wanted files from source to target" # Copy the new rendered files and add them to the commit. cp -r "$SOURCE_PO_DIR/." "$TARGET_PO_DIR" -# Copy files necessary to build the Qiskit metapackage. -cp "$SOURCE_REPO_ROOT/qiskit_pkg/setup.py" "${TARGET_REPO_ROOT}" +# Copy files necessary to build the Qiskit package. +cp "$SOURCE_REPO_ROOT/setup.py" "${TARGET_REPO_ROOT}" +cp "$SOURCE_REPO_ROOT/pyproject.toml" "${TARGET_REPO_ROOT}" cat "$SOURCE_REPO_ROOT/requirements-dev.txt" "$SOURCE_REPO_ROOT/requirements-optional.txt" \ > "${TARGET_REPO_ROOT}/requirements-dev.txt" cp "$SOURCE_REPO_ROOT/constraints.txt" "${TARGET_REPO_ROOT}" diff --git a/tox.ini b/tox.ini index 5c517b1d2cc9..df46820fc026 100644 --- a/tox.ini +++ b/tox.ini @@ -4,10 +4,6 @@ envlist = py38, py39, py310, py311, py312, lint-incr isolated_build = true [testenv] -# We pretend that we're not actually installing the package, because we need tox to let us have two -# packages ('qiskit' and 'qiskit-terra') under test at the same time. For that, we have to stuff -# them into 'deps'. -skip_install = true install_command = pip install -c{toxinidir}/constraints.txt -U {opts} {packages} setenv = VIRTUAL_ENV={envdir} @@ -22,16 +18,14 @@ deps = setuptools_rust # This is work around for the bug of tox 3 (see #8606 for more details.) -r{toxinidir}/requirements.txt -r{toxinidir}/requirements-dev.txt - -e . - -e ./qiskit_pkg commands = stestr run {posargs} [testenv:lint] basepython = python3 commands = - ruff check qiskit test tools examples setup.py qiskit_pkg - black --check {posargs} qiskit test tools examples setup.py qiskit_pkg + ruff check qiskit test tools examples setup.py + black --check {posargs} qiskit test tools examples setup.py pylint -rn qiskit test tools # This line is commented out until #6649 merges. We can't run this currently # via tox because tox doesn't support globbing @@ -45,8 +39,8 @@ commands = basepython = python3 allowlist_externals = git commands = - ruff check qiskit test tools examples setup.py qiskit_pkg - black --check {posargs} qiskit test tools examples setup.py qiskit_pkg + ruff check qiskit test tools examples setup.py + black --check {posargs} qiskit test tools examples setup.py -git fetch -q https://github.com/Qiskit/qiskit-terra.git :lint_incr_latest python {toxinidir}/tools/pylint_incr.py -rn -j4 -sn --paths :/qiskit/*.py :/test/*.py :/tools/*.py python {toxinidir}/tools/pylint_incr.py -rn -j4 -sn --disable='invalid-name,missing-module-docstring,redefined-outer-name' --paths :(glob,top)examples/python/*.py @@ -59,7 +53,7 @@ commands = skip_install = true deps = -r requirements-dev.txt -commands = black {posargs} qiskit test tools examples setup.py qiskit_pkg +commands = black {posargs} qiskit test tools examples setup.py [testenv:coverage] basepython = python3 From 2e986d71636ae17d0d61159e71f4342414c81ff4 Mon Sep 17 00:00:00 2001 From: Jake Lishman Date: Fri, 24 Nov 2023 21:27:47 +0000 Subject: [PATCH 2/4] Add manual uninstall for Neko --- .github/workflows/neko.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/neko.yml b/.github/workflows/neko.yml index bda60fd39790..30921c8b051b 100644 --- a/.github/workflows/neko.yml +++ b/.github/workflows/neko.yml @@ -16,4 +16,6 @@ jobs: - uses: Qiskit/qiskit-neko@main with: test_selection: terra - repo_install_command: "pip install -c constraints.txt ." + # We have to forcibly uninstall any old version of qiskit or qiskit-terra during the + # changeover, because it's not possible to safely upgrade an existing installation to 1.0. + repo_install_command: "pip uninstall qiskit qiskit-terra && pip install -c constraints.txt ." From d8b7ebf3ad3921d595be3a45e2c71751dd3bd71f Mon Sep 17 00:00:00 2001 From: Jake Lishman Date: Mon, 27 Nov 2023 18:05:13 +0000 Subject: [PATCH 3/4] Fix Windows paths Co-authored-by: Matthew Treinish --- releasenotes/notes/terra-nullius-7ef598626d8118c1.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releasenotes/notes/terra-nullius-7ef598626d8118c1.yaml b/releasenotes/notes/terra-nullius-7ef598626d8118c1.yaml index c6c1fe3867b9..d9a49344a18e 100644 --- a/releasenotes/notes/terra-nullius-7ef598626d8118c1.yaml +++ b/releasenotes/notes/terra-nullius-7ef598626d8118c1.yaml @@ -23,7 +23,7 @@ critical: # Install Qiskit (only once). pip install 'qiskit>=1.0' - On Windows, replace ``source /bin/activate`` with ``source /Scripts/activate``. + On Windows, replace ``source /bin/activate`` with ``source \Scripts\activate``. If you are a library author, or have code that depends on Qiskit, you should update any old dependencies on ``qiskit-terra`` to instead depend on ``qiskit``. From 6f5b066f2a7ee4ce734cfe3eea331a3dccba8301 Mon Sep 17 00:00:00 2001 From: Jake Lishman Date: Mon, 27 Nov 2023 18:19:49 +0000 Subject: [PATCH 4/4] Refer to stdlib documentation for odd shells --- releasenotes/notes/terra-nullius-7ef598626d8118c1.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/releasenotes/notes/terra-nullius-7ef598626d8118c1.yaml b/releasenotes/notes/terra-nullius-7ef598626d8118c1.yaml index d9a49344a18e..562929a17b9f 100644 --- a/releasenotes/notes/terra-nullius-7ef598626d8118c1.yaml +++ b/releasenotes/notes/terra-nullius-7ef598626d8118c1.yaml @@ -23,7 +23,8 @@ critical: # Install Qiskit (only once). pip install 'qiskit>=1.0' - On Windows, replace ``source /bin/activate`` with ``source \Scripts\activate``. + For other platforms, or more unusual shells, refer to `the Python standard-library documentation + on activating virtual environments `__. If you are a library author, or have code that depends on Qiskit, you should update any old dependencies on ``qiskit-terra`` to instead depend on ``qiskit``.