diff --git a/qiskit/circuit/add_control.py b/qiskit/circuit/_add_control.py similarity index 100% rename from qiskit/circuit/add_control.py rename to qiskit/circuit/_add_control.py diff --git a/qiskit/circuit/gate.py b/qiskit/circuit/gate.py index 7bef359a9355..c55817710020 100644 --- a/qiskit/circuit/gate.py +++ b/qiskit/circuit/gate.py @@ -135,7 +135,7 @@ def control( """ if not annotated: # captures both None and False # pylint: disable=cyclic-import - from .add_control import add_control + from ._add_control import add_control return add_control(self, num_ctrl_qubits, label, ctrl_state) diff --git a/releasenotes/notes/private-add_control-2367872c0f7136c4.yaml b/releasenotes/notes/private-add_control-2367872c0f7136c4.yaml new file mode 100644 index 000000000000..17fe70ef8d6d --- /dev/null +++ b/releasenotes/notes/private-add_control-2367872c0f7136c4.yaml @@ -0,0 +1,6 @@ +--- +upgrade_circuits: + - | + The internal function ``qiskit.circuit.add_control.add_control`` was removed, as it is not part of the + public API. It had fragile preconditions to uphold and was a common source of bugs. Uses of ``add_control(SomeGate(...), ...)`` + should change to ``SomeGate(...).control(...)`` using :meth:`.Gate.control` instead, which is far safer. diff --git a/test/python/circuit/test_controlled_gate.py b/test/python/circuit/test_controlled_gate.py index 02190e07f882..980c670194de 100644 --- a/test/python/circuit/test_controlled_gate.py +++ b/test/python/circuit/test_controlled_gate.py @@ -27,7 +27,6 @@ from qiskit.quantum_info.operators.predicates import matrix_equal, is_unitary_matrix from qiskit.quantum_info.random import random_unitary from qiskit.quantum_info.states import Statevector -import qiskit.circuit.add_control as ac from qiskit.transpiler.passes import UnrollCustomDefinitions, BasisTranslator from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager from qiskit.converters.circuit_to_dag import circuit_to_dag @@ -1584,10 +1583,10 @@ class TestSingleControlledRotationGates(QiskitTestCase): gry = ry.RYGate(theta) grz = rz.RZGate(theta) - ugu1 = ac._unroll_gate(gu1, ["p", "u", "cx"]) - ugrx = ac._unroll_gate(grx, ["p", "u", "cx"]) - ugry = ac._unroll_gate(gry, ["p", "u", "cx"]) - ugrz = ac._unroll_gate(grz, ["p", "u", "cx"]) + ugu1 = u1.U1Gate(theta).definition + ugrx = rx.RXGate(theta).definition + ugry = ry.RYGate(theta).definition + ugrz = rz.RZGate(theta).definition ugrz.params = grz.params cgu1 = ugu1.control(num_ctrl)