From 3b97cf3b0f02729d0313015095297ba2bd909f7b Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Wed, 7 Jun 2023 17:03:04 +0200 Subject: [PATCH 01/22] __qiskit_version__ deprecation --- qiskit/tools/jupyter/version_table.py | 31 ++++++++++----- qiskit/utils/deprecation.py | 2 +- qiskit/version.py | 57 +++++---------------------- test/python/test_version.py | 2 +- 4 files changed, 33 insertions(+), 59 deletions(-) diff --git a/qiskit/tools/jupyter/version_table.py b/qiskit/tools/jupyter/version_table.py index f013c4fb860d..4146d66a7aa3 100644 --- a/qiskit/tools/jupyter/version_table.py +++ b/qiskit/tools/jupyter/version_table.py @@ -14,6 +14,8 @@ """A module for monitoring backends.""" import time +from sys import modules +from collections import OrderedDict from IPython.display import HTML, display from IPython.core.magic import line_magic, Magics, magics_class import qiskit @@ -33,19 +35,30 @@ def qiskit_version_table(self, line="", cell=None): """ html = "

Version Information

" html += "" - html += "" + html += "" - packages = [] - qver = qiskit.__qiskit_version__ + packages = OrderedDict() - for pkg in qver: - if qver[pkg]: - packages.append((f"{pkg}", qver[pkg])) + from importlib.metadata import metadata - for name, version in packages: - html += f"" + try: + packages["qiskit"] = metadata("qiskit")["Version"] + except Exception: + packages["qiskit"] = None + + packages["qiskit-terra"] = qiskit.__version__ + + qiskit_modules = {module.split(".")[0] for module in modules.keys() if "qiskit" in module} + for qiskit_module in qiskit_modules: + try: + packages[metadata(qiskit_module)["Name"]] = metadata(qiskit_module)["Version"] + except Exception: + packages["qiskit"] = None + + for name, version in packages.items(): + html += f"" - html += "" + html += "" local_hw_info = local_hardware_info() sys_info = [ diff --git a/qiskit/utils/deprecation.py b/qiskit/utils/deprecation.py index 92cd4d44b863..744d4c3f0986 100644 --- a/qiskit/utils/deprecation.py +++ b/qiskit/utils/deprecation.py @@ -91,7 +91,7 @@ def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): - warnings.warn(msg, category=category, stacklevel=2) + warnings.warn(msg, category=category) return func(*args, **kwargs) add_deprecation_to_docstring(wrapper, msg, since=since, pending=pending) diff --git a/qiskit/version.py b/qiskit/version.py index 6fed7c92bc7e..0d0d846bfd11 100644 --- a/qiskit/version.py +++ b/qiskit/version.py @@ -18,6 +18,8 @@ import subprocess from collections.abc import Mapping +import warnings + ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) @@ -86,16 +88,19 @@ def get_version_info(): class QiskitVersion(Mapping): - """A lazy loading wrapper to get qiskit versions.""" + """DEPRECATED in 0.25.0 use qiskit.__version__""" __slots__ = ["_version_dict", "_loaded"] def __init__(self): + warnings.warn( + "qiskit.__qiskit_version__ is deprecated since " + "Qiskit Terra 0.25.0, and will be removed 3 months or more later. " + "Instead, you should use qiskit.__version__.", + category=DeprecationWarning, + ) self._version_dict = { "qiskit-terra": __version__, - "qiskit-aer": None, - "qiskit-ignis": None, - "qiskit-ibmq-provider": None, "qiskit": None, } self._loaded = False @@ -103,50 +108,6 @@ def __init__(self): def _load_versions(self): from importlib.metadata import version - try: - # TODO: Update to use qiskit_aer instead when we remove the - # namespace redirect - from qiskit.providers import aer - - self._version_dict["qiskit-aer"] = aer.__version__ - except Exception: - self._version_dict["qiskit-aer"] = None - try: - from qiskit import ignis - - self._version_dict["qiskit-ignis"] = ignis.__version__ - except Exception: - self._version_dict["qiskit-ignis"] = None - try: - from qiskit.providers import ibmq - - self._version_dict["qiskit-ibmq-provider"] = ibmq.__version__ - except Exception: - self._version_dict["qiskit-ibmq-provider"] = None - try: - import qiskit_nature - - self._version_dict["qiskit-nature"] = qiskit_nature.__version__ - except Exception: - self._version_dict["qiskit-nature"] = None - try: - import qiskit_finance - - self._version_dict["qiskit-finance"] = qiskit_finance.__version__ - except Exception: - self._version_dict["qiskit-finance"] = None - try: - import qiskit_optimization - - self._version_dict["qiskit-optimization"] = qiskit_optimization.__version__ - except Exception: - self._version_dict["qiskit-optimization"] = None - try: - import qiskit_machine_learning - - self._version_dict["qiskit-machine-learning"] = qiskit_machine_learning.__version__ - except Exception: - self._version_dict["qiskit-machine-learning"] = None try: self._version_dict["qiskit"] = version("qiskit") except Exception: diff --git a/test/python/test_version.py b/test/python/test_version.py index 1fdb541074f8..a1fa54311a7a 100644 --- a/test/python/test_version.py +++ b/test/python/test_version.py @@ -21,5 +21,5 @@ class TestVersion(QiskitTestCase): """Tests for qiskit/version.py""" def test_qiskit_version(self): - """Test qiskit-version sets the correct version for terra.""" + """Test qisqqkit-version sets the correct version for terra.""" self.assertEqual(__version__, __qiskit_version__["qiskit-terra"]) From 251c13bd94cb60f5da4aae202739ede5224a591f Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Wed, 7 Jun 2023 17:03:30 +0200 Subject: [PATCH 02/22] reno --- releasenotes/notes/qiskit_version-956916f7b8d7bbb9.yaml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 releasenotes/notes/qiskit_version-956916f7b8d7bbb9.yaml diff --git a/releasenotes/notes/qiskit_version-956916f7b8d7bbb9.yaml b/releasenotes/notes/qiskit_version-956916f7b8d7bbb9.yaml new file mode 100644 index 000000000000..7cc761f8ffc2 --- /dev/null +++ b/releasenotes/notes/qiskit_version-956916f7b8d7bbb9.yaml @@ -0,0 +1,7 @@ + + +--- +deprecations: + - | + The dictionary qiskit.__qiskit_version__ is deprecated, as Qiskit is define with a single package (``qiskit-terra``). + In the future, qiskit.__version__ will be the single point to query the Qiskit release. From 21007467d396347a0ee9fe727933e85c525f0943 Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Wed, 7 Jun 2023 17:13:13 +0200 Subject: [PATCH 03/22] reno feature --- .../notes/qiskit_version-956916f7b8d7bbb9.yaml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/releasenotes/notes/qiskit_version-956916f7b8d7bbb9.yaml b/releasenotes/notes/qiskit_version-956916f7b8d7bbb9.yaml index 7cc761f8ffc2..b26cf9b97665 100644 --- a/releasenotes/notes/qiskit_version-956916f7b8d7bbb9.yaml +++ b/releasenotes/notes/qiskit_version-956916f7b8d7bbb9.yaml @@ -1,7 +1,9 @@ - - --- +features: + - | + The magic ``%qiskit_version_table`` from ``qiskit.tools.jupyter`` now includes all + the modules with ``'qiskit`` in the name. deprecations: - | - The dictionary qiskit.__qiskit_version__ is deprecated, as Qiskit is define with a single package (``qiskit-terra``). - In the future, qiskit.__version__ will be the single point to query the Qiskit release. + The dictionary ``qiskit.__qiskit_version__`` is deprecated, as Qiskit is define with a single package (``qiskit-terra``). + In the future, ``qiskit.__version__`` will be the single point to query the Qiskit release, as a standard string. From d30025c1474f108de5d0fc01d98844aaedf05c84 Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Sat, 10 Jun 2023 21:14:31 +0200 Subject: [PATCH 04/22] PackageNotFoundError --- qiskit/tools/jupyter/version_table.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qiskit/tools/jupyter/version_table.py b/qiskit/tools/jupyter/version_table.py index 4146d66a7aa3..3a6068408048 100644 --- a/qiskit/tools/jupyter/version_table.py +++ b/qiskit/tools/jupyter/version_table.py @@ -39,11 +39,11 @@ def qiskit_version_table(self, line="", cell=None): packages = OrderedDict() - from importlib.metadata import metadata + from importlib.metadata import metadata, PackageNotFoundError try: packages["qiskit"] = metadata("qiskit")["Version"] - except Exception: + except PackageNotFoundError: packages["qiskit"] = None packages["qiskit-terra"] = qiskit.__version__ @@ -52,7 +52,7 @@ def qiskit_version_table(self, line="", cell=None): for qiskit_module in qiskit_modules: try: packages[metadata(qiskit_module)["Name"]] = metadata(qiskit_module)["Version"] - except Exception: + except PackageNotFoundError: packages["qiskit"] = None for name, version in packages.items(): From 67641150491fa86785062627dc04e0a03d176612 Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Sat, 10 Jun 2023 21:16:58 +0200 Subject: [PATCH 05/22] revert stacklevel=2 --- qiskit/utils/deprecation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/utils/deprecation.py b/qiskit/utils/deprecation.py index 744d4c3f0986..92cd4d44b863 100644 --- a/qiskit/utils/deprecation.py +++ b/qiskit/utils/deprecation.py @@ -91,7 +91,7 @@ def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): - warnings.warn(msg, category=category) + warnings.warn(msg, category=category, stacklevel=2) return func(*args, **kwargs) add_deprecation_to_docstring(wrapper, msg, since=since, pending=pending) From db99e1d8fc932fe100d1c8c281b1135327b62b4d Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Sat, 10 Jun 2023 21:18:17 +0200 Subject: [PATCH 06/22] revert change in test --- test/python/test_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/python/test_version.py b/test/python/test_version.py index a1fa54311a7a..1fdb541074f8 100644 --- a/test/python/test_version.py +++ b/test/python/test_version.py @@ -21,5 +21,5 @@ class TestVersion(QiskitTestCase): """Tests for qiskit/version.py""" def test_qiskit_version(self): - """Test qisqqkit-version sets the correct version for terra.""" + """Test qiskit-version sets the correct version for terra.""" self.assertEqual(__version__, __qiskit_version__["qiskit-terra"]) From d0d858872d82501187b71b2611e8d769cb40d5dc Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Thu, 13 Jul 2023 10:36:39 +0200 Subject: [PATCH 07/22] remove OrderedDict --- qiskit/tools/jupyter/version_table.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qiskit/tools/jupyter/version_table.py b/qiskit/tools/jupyter/version_table.py index 3a6068408048..f5472fbc6cfc 100644 --- a/qiskit/tools/jupyter/version_table.py +++ b/qiskit/tools/jupyter/version_table.py @@ -15,7 +15,6 @@ import time from sys import modules -from collections import OrderedDict from IPython.display import HTML, display from IPython.core.magic import line_magic, Magics, magics_class import qiskit @@ -37,7 +36,7 @@ def qiskit_version_table(self, line="", cell=None): html += "
Qiskit SoftwareVersion
SoftwareVersion
{name}{version}
{name}{version}
System information
System information
" html += "" - packages = OrderedDict() + packages = dict() from importlib.metadata import metadata, PackageNotFoundError From a846ffe49f5e65f294651873eaeab80ecc738e80 Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Thu, 13 Jul 2023 10:46:03 +0200 Subject: [PATCH 08/22] other qiskit.__qiskit_version__ packages have their own __version__ --- qiskit/version.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qiskit/version.py b/qiskit/version.py index 0d0d846bfd11..b2968cdf5ebd 100644 --- a/qiskit/version.py +++ b/qiskit/version.py @@ -12,7 +12,7 @@ # pylint: disable=no-name-in-module,broad-except,cyclic-import -"""Contains the terra version.""" +"""Contains Qiskit (terra) version.""" import os import subprocess @@ -96,7 +96,9 @@ def __init__(self): warnings.warn( "qiskit.__qiskit_version__ is deprecated since " "Qiskit Terra 0.25.0, and will be removed 3 months or more later. " - "Instead, you should use qiskit.__version__.", + "Instead, you should use qiskit.__version__. The other packages listed in " + "former qiskit.__qiskit_version__ have their own __version__ module level dunder, " + "as standard in PEP 8.", category=DeprecationWarning, ) self._version_dict = { From bab5901ca463332e3d3224f0cefb5f4417b7a332 Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Thu, 13 Jul 2023 10:49:02 +0200 Subject: [PATCH 09/22] wording in the reno --- releasenotes/notes/qiskit_version-956916f7b8d7bbb9.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releasenotes/notes/qiskit_version-956916f7b8d7bbb9.yaml b/releasenotes/notes/qiskit_version-956916f7b8d7bbb9.yaml index b26cf9b97665..33f8d825e3af 100644 --- a/releasenotes/notes/qiskit_version-956916f7b8d7bbb9.yaml +++ b/releasenotes/notes/qiskit_version-956916f7b8d7bbb9.yaml @@ -2,7 +2,7 @@ features: - | The magic ``%qiskit_version_table`` from ``qiskit.tools.jupyter`` now includes all - the modules with ``'qiskit`` in the name. + imported modules with ``'qiskit`` in their name. deprecations: - | The dictionary ``qiskit.__qiskit_version__`` is deprecated, as Qiskit is define with a single package (``qiskit-terra``). From 08a3778a9d0659cf4115bcc25065058840f4beab Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Thu, 13 Jul 2023 11:18:10 +0200 Subject: [PATCH 10/22] qiskit-terra == qiskit in version libraries --- qiskit/tools/jupyter/version_table.py | 21 +++++++-------------- qiskit/version.py | 5 ++--- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/qiskit/tools/jupyter/version_table.py b/qiskit/tools/jupyter/version_table.py index f5472fbc6cfc..c44fc3c4ec1b 100644 --- a/qiskit/tools/jupyter/version_table.py +++ b/qiskit/tools/jupyter/version_table.py @@ -36,23 +36,16 @@ def qiskit_version_table(self, line="", cell=None): html += "
SoftwareVersion
" html += "" - packages = dict() + packages = {"qiskit": qiskit.__version__} from importlib.metadata import metadata, PackageNotFoundError - try: - packages["qiskit"] = metadata("qiskit")["Version"] - except PackageNotFoundError: - packages["qiskit"] = None - - packages["qiskit-terra"] = qiskit.__version__ - - qiskit_modules = {module.split(".")[0] for module in modules.keys() if "qiskit" in module} - for qiskit_module in qiskit_modules: - try: - packages[metadata(qiskit_module)["Name"]] = metadata(qiskit_module)["Version"] - except PackageNotFoundError: - packages["qiskit"] = None + for module in modules.keys(): + if "qiskit" in module and "qiskit" != module: + try: + packages[metadata(module)["Name"]] = metadata(module)["Version"] + except PackageNotFoundError: + pass for name, version in packages.items(): html += f"" diff --git a/qiskit/version.py b/qiskit/version.py index b2968cdf5ebd..57ae9c01e1bb 100644 --- a/qiskit/version.py +++ b/qiskit/version.py @@ -12,7 +12,7 @@ # pylint: disable=no-name-in-module,broad-except,cyclic-import -"""Contains Qiskit (terra) version.""" +"""Contains Qiskit version.""" import os import subprocess @@ -102,8 +102,7 @@ def __init__(self): category=DeprecationWarning, ) self._version_dict = { - "qiskit-terra": __version__, - "qiskit": None, + "qiskit": __version__, } self._loaded = False From 51aa73a4bee44d6a1bc7b602b2ea551631d4378f Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Thu, 13 Jul 2023 11:24:52 +0200 Subject: [PATCH 11/22] lint --- qiskit/tools/jupyter/version_table.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/tools/jupyter/version_table.py b/qiskit/tools/jupyter/version_table.py index f5472fbc6cfc..73a67970c64f 100644 --- a/qiskit/tools/jupyter/version_table.py +++ b/qiskit/tools/jupyter/version_table.py @@ -36,7 +36,7 @@ def qiskit_version_table(self, line="", cell=None): html += "
SoftwareVersion
{name}{version}
" html += "" - packages = dict() + packages = {} from importlib.metadata import metadata, PackageNotFoundError From 7b27fc6b29458a391ebb9f63084da0e61fc3efb1 Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Thu, 13 Jul 2023 12:36:23 +0200 Subject: [PATCH 12/22] readjust test --- test/python/test_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/python/test_version.py b/test/python/test_version.py index 1fdb541074f8..f13bfedc3765 100644 --- a/test/python/test_version.py +++ b/test/python/test_version.py @@ -22,4 +22,4 @@ class TestVersion(QiskitTestCase): def test_qiskit_version(self): """Test qiskit-version sets the correct version for terra.""" - self.assertEqual(__version__, __qiskit_version__["qiskit-terra"]) + self.assertEqual(__version__, __qiskit_version__["qiskit"]) From 92b4ee1e8b5842ab82ff7a90a18ced89a5394fc2 Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Sun, 16 Jul 2023 18:04:32 +0200 Subject: [PATCH 13/22] raise an exception with a custom gate with no qubits or with one-or-more clbits --- qiskit/circuit/quantumcircuit.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/qiskit/circuit/quantumcircuit.py b/qiskit/circuit/quantumcircuit.py index e6cb4c4638d7..88c0efe64309 100644 --- a/qiskit/circuit/quantumcircuit.py +++ b/qiskit/circuit/quantumcircuit.py @@ -5089,6 +5089,15 @@ def _qasm2_define_custom_operation(operation, existing_gate_names, gates_to_defi ) else: parameters_qasm = "" + + # Gate definitions with 0 qubits or with any classical bits are not allowed. + if operation.num_qubits == 0 or operation.num_clbits != 0: + raise CircuitError( + "OpenQASM 2 does not allow gate definitions with no qubits or with any " + f"classical bit: '{operation.name}' has {operation.num_qubits} qubits " + f"and {operation.num_clbits} clbits" + ) + qubits_qasm = ",".join(f"q{i}" for i in range(parameterized_operation.num_qubits)) parameterized_definition = getattr(parameterized_operation, "definition", None) if parameterized_definition is None: From fc0d3be7aeffddef5b8a7ffb6c7ec41b2ee5732e Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Sun, 23 Jul 2023 18:28:42 +0200 Subject: [PATCH 14/22] QASM2ExportError --- qiskit/circuit/quantumcircuit.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qiskit/circuit/quantumcircuit.py b/qiskit/circuit/quantumcircuit.py index 329f9b11a480..9889b47bb866 100644 --- a/qiskit/circuit/quantumcircuit.py +++ b/qiskit/circuit/quantumcircuit.py @@ -5088,8 +5088,10 @@ def _qasm2_define_custom_operation(operation, existing_gate_names, gates_to_defi parameters_qasm = "" # Gate definitions with 0 qubits or with any classical bits are not allowed. + from qiskit.qasm2 import QASM2ExportError # pylint: disable=cyclic-import + if operation.num_qubits == 0 or operation.num_clbits != 0: - raise CircuitError( + raise QASM2ExportError( "OpenQASM 2 does not allow gate definitions with no qubits or with any " f"classical bit: '{operation.name}' has {operation.num_qubits} qubits " f"and {operation.num_clbits} clbits" From b4e8ce81b65cf00342ba337774882118d977c008 Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Mon, 24 Jul 2023 07:59:41 +0200 Subject: [PATCH 15/22] test_circuit_raises_invalid_custom_gate_1 --- test/python/circuit/test_circuit_qasm.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/python/circuit/test_circuit_qasm.py b/test/python/circuit/test_circuit_qasm.py index 32f12e2c89ef..222e62fdba98 100644 --- a/test/python/circuit/test_circuit_qasm.py +++ b/test/python/circuit/test_circuit_qasm.py @@ -657,6 +657,15 @@ def test_circuit_raises_on_single_bit_condition(self): with self.assertRaisesRegex(QasmError, "OpenQASM 2 can only condition on registers"): qc.qasm() + def test_circuit_raises_invalid_custom_gate_1(self): + """OpenQASM 2 exporter of custom gates with no qubits.""" + legit_circuit = QuantumCircuit(5, name="legit_circuit") + empty_circuit = QuantumCircuit(name="empty_circuit") + legit_circuit.append(empty_circuit) + + with self.assertRaisesRegex(QasmError, "gate definitions with no qubits"): + legit_circuit.qasm() + def test_circuit_qasm_with_permutations(self): """Test circuit qasm() method with Permutation gates.""" From a8127baddb93bec2b6a662973f7e4f04e1767085 Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Mon, 24 Jul 2023 07:59:55 +0200 Subject: [PATCH 16/22] test_circuit_raises_invalid_custom_gate_2 --- test/python/circuit/test_circuit_qasm.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/python/circuit/test_circuit_qasm.py b/test/python/circuit/test_circuit_qasm.py index 222e62fdba98..848b39169fea 100644 --- a/test/python/circuit/test_circuit_qasm.py +++ b/test/python/circuit/test_circuit_qasm.py @@ -666,6 +666,19 @@ def test_circuit_raises_invalid_custom_gate_1(self): with self.assertRaisesRegex(QasmError, "gate definitions with no qubits"): legit_circuit.qasm() + def test_circuit_raises_invalid_custom_gate_2(self): + """OpenQASM 2 exporter of custom instruction.""" + instruction = QuantumCircuit(2, 2, name="inst") + instruction.cx(0, 1) + instruction.measure_all() + custom_instruction = instruction.to_instruction() + + qc = QuantumCircuit(2, 2) + qc.append(custom_instruction, [0, 1], [0, 1]) + + with self.assertRaisesRegex(QasmError, "gate definitions with no qubits"): + qc.qasm() + def test_circuit_qasm_with_permutations(self): """Test circuit qasm() method with Permutation gates.""" From a03841e01e2535c035acc7a1b3c00b4cd9525e8d Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Mon, 24 Jul 2023 08:19:09 +0200 Subject: [PATCH 17/22] reno --- .../qasm_invalid_custom_instruction-7738db7ba1a1a5cf.yaml | 7 +++++++ test/python/circuit/test_circuit_qasm.py | 6 ++++-- 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 releasenotes/notes/qasm_invalid_custom_instruction-7738db7ba1a1a5cf.yaml diff --git a/releasenotes/notes/qasm_invalid_custom_instruction-7738db7ba1a1a5cf.yaml b/releasenotes/notes/qasm_invalid_custom_instruction-7738db7ba1a1a5cf.yaml new file mode 100644 index 000000000000..743883b52286 --- /dev/null +++ b/releasenotes/notes/qasm_invalid_custom_instruction-7738db7ba1a1a5cf.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + Some of the custom operator that Qiskit is available to express are not expressible in OpenQASM 2. + When exporting those gates using :meth:`qiskit.QuantumCircuit.qasm`, this sort of operators are now + raising. See `#7351 `__ and + `#10435 `__. diff --git a/test/python/circuit/test_circuit_qasm.py b/test/python/circuit/test_circuit_qasm.py index 848b39169fea..12521fd3f22c 100644 --- a/test/python/circuit/test_circuit_qasm.py +++ b/test/python/circuit/test_circuit_qasm.py @@ -658,7 +658,8 @@ def test_circuit_raises_on_single_bit_condition(self): qc.qasm() def test_circuit_raises_invalid_custom_gate_1(self): - """OpenQASM 2 exporter of custom gates with no qubits.""" + """OpenQASM 2 exporter of custom gates with no qubits. + See: https://github.com/Qiskit/qiskit-terra/issues/10435""" legit_circuit = QuantumCircuit(5, name="legit_circuit") empty_circuit = QuantumCircuit(name="empty_circuit") legit_circuit.append(empty_circuit) @@ -667,7 +668,8 @@ def test_circuit_raises_invalid_custom_gate_1(self): legit_circuit.qasm() def test_circuit_raises_invalid_custom_gate_2(self): - """OpenQASM 2 exporter of custom instruction.""" + """OpenQASM 2 exporter of custom instruction. + See: https://github.com/Qiskit/qiskit-terra/issues/7351""" instruction = QuantumCircuit(2, 2, name="inst") instruction.cx(0, 1) instruction.measure_all() From 980905d379f043030d452fec9cb3982d4bf5832b Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Mon, 24 Jul 2023 13:33:51 +0200 Subject: [PATCH 18/22] revert --- qiskit/circuit/quantumcircuit.py | 11 --------- ...d_custom_instruction-7738db7ba1a1a5cf.yaml | 7 ------ test/python/circuit/test_circuit_qasm.py | 24 ------------------- 3 files changed, 42 deletions(-) delete mode 100644 releasenotes/notes/qasm_invalid_custom_instruction-7738db7ba1a1a5cf.yaml diff --git a/qiskit/circuit/quantumcircuit.py b/qiskit/circuit/quantumcircuit.py index 9889b47bb866..5dfea905bdc3 100644 --- a/qiskit/circuit/quantumcircuit.py +++ b/qiskit/circuit/quantumcircuit.py @@ -5086,17 +5086,6 @@ def _qasm2_define_custom_operation(operation, existing_gate_names, gates_to_defi ) else: parameters_qasm = "" - - # Gate definitions with 0 qubits or with any classical bits are not allowed. - from qiskit.qasm2 import QASM2ExportError # pylint: disable=cyclic-import - - if operation.num_qubits == 0 or operation.num_clbits != 0: - raise QASM2ExportError( - "OpenQASM 2 does not allow gate definitions with no qubits or with any " - f"classical bit: '{operation.name}' has {operation.num_qubits} qubits " - f"and {operation.num_clbits} clbits" - ) - qubits_qasm = ",".join(f"q{i}" for i in range(parameterized_operation.num_qubits)) parameterized_definition = getattr(parameterized_operation, "definition", None) if parameterized_definition is None: diff --git a/releasenotes/notes/qasm_invalid_custom_instruction-7738db7ba1a1a5cf.yaml b/releasenotes/notes/qasm_invalid_custom_instruction-7738db7ba1a1a5cf.yaml deleted file mode 100644 index 743883b52286..000000000000 --- a/releasenotes/notes/qasm_invalid_custom_instruction-7738db7ba1a1a5cf.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -fixes: - - | - Some of the custom operator that Qiskit is available to express are not expressible in OpenQASM 2. - When exporting those gates using :meth:`qiskit.QuantumCircuit.qasm`, this sort of operators are now - raising. See `#7351 `__ and - `#10435 `__. diff --git a/test/python/circuit/test_circuit_qasm.py b/test/python/circuit/test_circuit_qasm.py index 12521fd3f22c..32f12e2c89ef 100644 --- a/test/python/circuit/test_circuit_qasm.py +++ b/test/python/circuit/test_circuit_qasm.py @@ -657,30 +657,6 @@ def test_circuit_raises_on_single_bit_condition(self): with self.assertRaisesRegex(QasmError, "OpenQASM 2 can only condition on registers"): qc.qasm() - def test_circuit_raises_invalid_custom_gate_1(self): - """OpenQASM 2 exporter of custom gates with no qubits. - See: https://github.com/Qiskit/qiskit-terra/issues/10435""" - legit_circuit = QuantumCircuit(5, name="legit_circuit") - empty_circuit = QuantumCircuit(name="empty_circuit") - legit_circuit.append(empty_circuit) - - with self.assertRaisesRegex(QasmError, "gate definitions with no qubits"): - legit_circuit.qasm() - - def test_circuit_raises_invalid_custom_gate_2(self): - """OpenQASM 2 exporter of custom instruction. - See: https://github.com/Qiskit/qiskit-terra/issues/7351""" - instruction = QuantumCircuit(2, 2, name="inst") - instruction.cx(0, 1) - instruction.measure_all() - custom_instruction = instruction.to_instruction() - - qc = QuantumCircuit(2, 2) - qc.append(custom_instruction, [0, 1], [0, 1]) - - with self.assertRaisesRegex(QasmError, "gate definitions with no qubits"): - qc.qasm() - def test_circuit_qasm_with_permutations(self): """Test circuit qasm() method with Permutation gates.""" From eb49e3d0d75b51b79a323ae81f6e4641e1b9f3ca Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Mon, 24 Jul 2023 13:35:07 +0200 Subject: [PATCH 19/22] revert From e8e20d81166545e260143a42963da7a4f2a1b02f Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Fri, 4 Aug 2023 21:28:41 +0200 Subject: [PATCH 20/22] adapt test --- qiskit/version.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/qiskit/version.py b/qiskit/version.py index dd06053acaca..2b958d1cffb3 100644 --- a/qiskit/version.py +++ b/qiskit/version.py @@ -102,14 +102,11 @@ def __init__(self): category=DeprecationWarning, ) self._version_dict = { - "qiskit-terra": __version__, - "qiskit": None, + "qiskit": __version__, } self._loaded = False def _load_versions(self): - from importlib.metadata import version - try: # TODO: Update to use qiskit_aer instead when we remove the # namespace redirect @@ -154,10 +151,7 @@ def _load_versions(self): self._version_dict["qiskit-machine-learning"] = qiskit_machine_learning.__version__ except Exception: self._version_dict["qiskit-machine-learning"] = None - try: - self._version_dict["qiskit"] = version("qiskit") - except Exception: - self._version_dict["qiskit"] = None + self._loaded = True def __repr__(self): From 40cf4587025e7161d9c2d8fdd2f0f5ed4e3626bc Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Fri, 4 Aug 2023 22:28:07 +0200 Subject: [PATCH 21/22] reno --- .../notes/qiskit_terra_version-956916f7b8d7bbb9.yaml | 4 ++++ releasenotes/notes/qiskit_version-956916f7b8d7bbb9.yaml | 9 --------- 2 files changed, 4 insertions(+), 9 deletions(-) create mode 100644 releasenotes/notes/qiskit_terra_version-956916f7b8d7bbb9.yaml delete mode 100644 releasenotes/notes/qiskit_version-956916f7b8d7bbb9.yaml diff --git a/releasenotes/notes/qiskit_terra_version-956916f7b8d7bbb9.yaml b/releasenotes/notes/qiskit_terra_version-956916f7b8d7bbb9.yaml new file mode 100644 index 000000000000..06ded95fc998 --- /dev/null +++ b/releasenotes/notes/qiskit_terra_version-956916f7b8d7bbb9.yaml @@ -0,0 +1,4 @@ +--- +upgrade: + - | + The magic ``%qiskit_version_table`` from ``qiskit.tools.jupyter`` and the deprecated ``qiskit.__qiskit_version__`` do not include `qiskit-terra` anymore. Now Qiskit Terra is called Qiskit. diff --git a/releasenotes/notes/qiskit_version-956916f7b8d7bbb9.yaml b/releasenotes/notes/qiskit_version-956916f7b8d7bbb9.yaml deleted file mode 100644 index 33f8d825e3af..000000000000 --- a/releasenotes/notes/qiskit_version-956916f7b8d7bbb9.yaml +++ /dev/null @@ -1,9 +0,0 @@ ---- -features: - - | - The magic ``%qiskit_version_table`` from ``qiskit.tools.jupyter`` now includes all - imported modules with ``'qiskit`` in their name. -deprecations: - - | - The dictionary ``qiskit.__qiskit_version__`` is deprecated, as Qiskit is define with a single package (``qiskit-terra``). - In the future, ``qiskit.__version__`` will be the single point to query the Qiskit release, as a standard string. From bb80e1d42528a842b593b686cb04bc0d40e347ff Mon Sep 17 00:00:00 2001 From: Luciano Bello Date: Fri, 25 Aug 2023 13:36:12 +0200 Subject: [PATCH 22/22] conflicts --- qiskit/version.py | 16 ++++++++-------- test/python/test_version.py | 3 ++- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/qiskit/version.py b/qiskit/version.py index 2b958d1cffb3..79cadf189742 100644 --- a/qiskit/version.py +++ b/qiskit/version.py @@ -93,20 +93,21 @@ class QiskitVersion(Mapping): __slots__ = ["_version_dict", "_loaded"] def __init__(self): + self._version_dict = { + "qiskit": __version__, + } + self._loaded = False + + def _load_versions(self): warnings.warn( "qiskit.__qiskit_version__ is deprecated since " "Qiskit Terra 0.25.0, and will be removed 3 months or more later. " - "Instead, you should use qiskit.__version__. The other packages listed in " + "Instead, you should use qiskit.__version__. The other packages listed in the" "former qiskit.__qiskit_version__ have their own __version__ module level dunder, " "as standard in PEP 8.", category=DeprecationWarning, + stacklevel=3, ) - self._version_dict = { - "qiskit": __version__, - } - self._loaded = False - - def _load_versions(self): try: # TODO: Update to use qiskit_aer instead when we remove the # namespace redirect @@ -151,7 +152,6 @@ def _load_versions(self): self._version_dict["qiskit-machine-learning"] = qiskit_machine_learning.__version__ except Exception: self._version_dict["qiskit-machine-learning"] = None - self._loaded = True def __repr__(self): diff --git a/test/python/test_version.py b/test/python/test_version.py index f13bfedc3765..3d260d6a3a8e 100644 --- a/test/python/test_version.py +++ b/test/python/test_version.py @@ -22,4 +22,5 @@ class TestVersion(QiskitTestCase): def test_qiskit_version(self): """Test qiskit-version sets the correct version for terra.""" - self.assertEqual(__version__, __qiskit_version__["qiskit"]) + with self.assertWarnsRegex(DeprecationWarning, "__qiskit_version__"): + self.assertEqual(__version__, __qiskit_version__["qiskit"])
SoftwareVersion