Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply new deprecation decorators to circuit folder #9869

Merged
merged 13 commits into from
May 10, 2023
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 17 additions & 25 deletions qiskit/circuit/bit.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
"""
Quantum bit and Classical bit objects.
"""
import warnings

from qiskit.circuit.exceptions import CircuitError
from qiskit.utils.deprecation import deprecate_func


class Bit:
Expand Down Expand Up @@ -59,53 +59,45 @@ def __init__(self, register=None, index=None):
self._repr = f"{self.__class__.__name__}({self._register}, {self._index})"

@property
@deprecate_func(
is_property=True,
since="0.17",
additional_msg=(
"Instead, use the method ``QuantumCircuit.find_bit`` to find all the containing "
Eric-Arellano marked this conversation as resolved.
Show resolved Hide resolved
"registers within a circuit and the index of the bit within the circuit."
),
)
def register(self):
"""Get the register of an old-style bit.

.. deprecated:: 0.17
Use :meth:`.QuantumCircuit.find_bit` instead.

In modern Qiskit Terra (version 0.17+), bits are the fundamental object and registers are
aliases to collections of bits. A bit can be in many registers depending on the circuit, so
a single containing register is no longer a property of a bit. It is an error to access
this attribute on bits that were not constructed as "owned" by a register."""
if (self._register, self._index) == (None, None):
raise CircuitError("Attempt to query register of a new-style Bit.")

warnings.warn(
"'Bit.register' is deprecated since Qiskit Terra 0.17 and will be removed "
"in a future release. Bits may be in more than one register. "
"Use 'QuantumCircuit.find_bit' to find all the containing registers within a circuit, "
"and the index of the bit within the circuit.",
DeprecationWarning,
stacklevel=2,
)

return self._register

@property
@deprecate_func(
is_property=True,
since="0.17",
additional_msg=(
"Instead, use the method ``QuantumCircuit.find_bit`` to find all the containing "
"registers within a circuit and the index of the bit within the circuit."
),
)
def index(self):
"""Get the index of an old-style bit in the register that owns it.

.. deprecated:: 0.17
Use :meth:`.QuantumCircuit.find_bit` instead.

In modern Qiskit Terra (version 0.17+), bits are the fundamental object and registers are
aliases to collections of bits. A bit can be in many registers depending on the circuit, so
a single containing register is no longer a property of a bit. It is an error to access
this attribute on bits that were not constructed as "owned" by a register."""
if (self._register, self._index) == (None, None):
raise CircuitError("Attempt to query index of a new-style Bit.")

warnings.warn(
"'Bit.index' is deprecated since Qiskit Terra 0.17 and will be removed "
"in a future release. Bits may be in more than one register. "
"Use 'QuantumCircuit.find_bit' to find all the containing registers within a circuit, "
"and the index of the bit within the circuit.",
DeprecationWarning,
stacklevel=2,
)

return self._index

def __repr__(self):
Expand Down
13 changes: 7 additions & 6 deletions qiskit/circuit/classicalregister.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@

from qiskit.circuit.exceptions import CircuitError

# Over-specific import to avoid cyclic imports.
from qiskit.utils.deprecation import deprecate_function
from qiskit.utils.deprecation import deprecate_func
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, the comment is still true lol. It's fine to get rid of it, though.

from .register import Register
from .bit import Bit

Expand Down Expand Up @@ -58,10 +57,12 @@ class ClassicalRegister(Register):
prefix = "c"
bit_type = Clbit

@deprecate_function(
"Register.qasm() is deprecated since Terra 0.23, as correct exporting to OpenQASM 2 is "
"the responsibility of a larger exporter; it cannot safely be done on an object-by-object "
"basis without context. No replacement will be provided, because the premise is wrong.",
@deprecate_func(
additional_msg=(
"Correct exporting to OpenQASM 2 is the responsibility of a larger exporter; it cannot "
"safely be done on an object-by-object basis without context. No replacement will be "
"provided, because the premise is wrong."
),
since="0.23.0",
)
def qasm(self):
Expand Down
28 changes: 12 additions & 16 deletions qiskit/circuit/instructionset.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@

from __future__ import annotations
import functools
import warnings
from typing import Callable

from qiskit.circuit.exceptions import CircuitError
from qiskit.utils.deprecation import deprecate_arg
from .classicalregister import Clbit, ClassicalRegister
from .operation import Operation
from .quantumcircuitdata import CircuitInstruction
Expand Down Expand Up @@ -95,7 +95,17 @@ class InstructionSet:

__slots__ = ("_instructions", "_requester")

def __init__(
@deprecate_arg(
"circuit_cregs",
since="0.19.0",
additional_msg=(
"Instead, pass a complete resource requester with the 'resource_requester' argument. "
"(The classical registers are insufficient to access all classical resources in a "
"circuit, as there may be loose classical bits as well. It can also cause integer "
"indices to be resolved incorrectly if any registers overlap.)"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

super nitpicky, but the parenthetical sentences here end up being longer than the actual deprecation message, which feels pretty weird to me. It's either important information for the user, in which case it needn't be parenthesised, or it's not and it can be a code/docs-only comment instead. I don't particularly mind which.

),
)
def __init__( # pylint: disable=bad-docstring-quotes
self,
circuit_cregs: list[ClassicalRegister] | None = None,
*,
Expand All @@ -109,13 +119,6 @@ def __init__(
Args:
circuit_cregs (list[ClassicalRegister]): Optional. List of ``cregs`` of the
circuit to which the instruction is added. Default: `None`.

.. deprecated:: 0.19
The classical registers are insufficient to access all classical resources in a
circuit, as there may be loose classical bits as well. It can also cause
integer indices to be resolved incorrectly if any registers overlap. Instead,
pass a complete requester to the ``resource_requester`` argument.

resource_requester: A callable that takes in the classical resource used in the
condition, verifies that it is present in the attached circuit, resolves any indices
into concrete :obj:`.Clbit` instances, and returns the concrete resource. If this
Expand All @@ -136,13 +139,6 @@ def __init__(
if circuit_cregs is not None:
if resource_requester is not None:
raise CircuitError("Cannot pass both 'circuit_cregs' and 'resource_requester'.")
warnings.warn(
"The 'circuit_cregs' argument to 'InstructionSet' is deprecated as of"
" qiskit-terra 0.19, and will be removed no sooner than 3 months after its release."
" Pass a complete resource requester as the 'resource_requester' instead.",
DeprecationWarning,
stacklevel=2,
)
self._requester: Callable[..., ClassicalRegister | Clbit] = _requester_from_cregs(
tuple(circuit_cregs)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
"""Polynomially controlled Pauli-rotations."""

from __future__ import annotations
import warnings

from itertools import product

from qiskit.circuit import QuantumRegister, QuantumCircuit
from qiskit.circuit.exceptions import CircuitError
from qiskit.utils.deprecation import deprecate_func

from .functional_pauli_rotations import FunctionalPauliRotations

Expand Down Expand Up @@ -214,15 +214,13 @@ def degree(self) -> int:
return 0

@property
@deprecate_func(
Cryoris marked this conversation as resolved.
Show resolved Hide resolved
is_property=True,
since="0.16.0",
additional_msg="Instead, use the property ``num_ancillas``.",
)
def num_ancilla_qubits(self):
"""Deprecated. Use num_ancillas instead."""
warnings.warn(
"The PolynomialPauliRotations.num_ancilla_qubits property is deprecated "
"as of 0.16.0. It will be removed no earlier than 3 months after the release "
"date. You should use the num_ancillas property instead.",
DeprecationWarning,
stacklevel=2,
)
return self.num_ancillas

def _reset_registers(self, num_state_qubits):
Expand Down
12 changes: 7 additions & 5 deletions qiskit/circuit/quantumregister.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from qiskit.circuit.exceptions import CircuitError

# Over-specific import to avoid cyclic imports.
from qiskit.utils.deprecation import deprecate_function
from qiskit.utils.deprecation import deprecate_func
from .register import Register
from .bit import Bit

Expand Down Expand Up @@ -58,10 +58,12 @@ class QuantumRegister(Register):
prefix = "q"
bit_type = Qubit

@deprecate_function(
"Register.qasm() is deprecated since Terra 0.23, as correct exporting to OpenQASM 2 is "
"the responsibility of a larger exporter; it cannot safely be done on an object-by-object "
"basis without context. No replacement will be provided, because the premise is wrong.",
@deprecate_func(
additional_msg=(
"Correct exporting to OpenQASM 2 is the responsibility of a larger exporter; it cannot "
"safely be done on an object-by-object basis without context. No replacement will be "
"provided, because the premise is wrong."
),
since="0.23.0",
)
def qasm(self):
Expand Down
2 changes: 1 addition & 1 deletion qiskit/test/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ def setUpClass(cls):
r"elementwise comparison failed.*",
r"The jsonschema validation included in qiskit-terra.*",
r"The DerivativeBase.parameter_expression_grad method.*",
r"'Bit\.(register|index)' is deprecated.*",
r"The property ``qiskit\.circuit\.bit\.Bit\.(register|index)`` is deprecated.*",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is only semi-related: the error message we've got here shows a potential place for improvement in the decorators to me; qiskit.circuit.bit.Bit.register feels way too long to put out. I think Bit.register would be less noisy - the user will always be able to inspect the object themselves if they need to know more about it.

r"The CXDirection pass has been deprecated",
r"The pauli_basis function with PauliTable.*",
# Caused by internal scikit-learn scipy usage
Expand Down
16 changes: 8 additions & 8 deletions test/python/circuit/test_instructions.py
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ def test_instructionset_c_if_deprecated_resolution(self):
registers = [ClassicalRegister(2), ClassicalRegister(3), ClassicalRegister(1)]
bits = [bit for register in registers for bit in register]

deprecated_regex = r"The 'circuit_cregs' argument to 'InstructionSet' is deprecated .*"
deprecated_regex = r".* argument ``circuit_cregs`` is deprecated .*"

def dummy_requester(specifier):
"""A dummy requester that technically fulfills the spec."""
Expand All @@ -583,30 +583,30 @@ def dummy_requester(specifier):
with self.subTest("classical register"):
instruction = HGate()
with self.assertWarnsRegex(DeprecationWarning, deprecated_regex):
instructions = InstructionSet(registers)
instructions = InstructionSet(circuit_cregs=registers)
Eric-Arellano marked this conversation as resolved.
Show resolved Hide resolved
instructions.add(instruction, [Qubit()], [])
instructions.c_if(registers[0], 0)
self.assertIs(instruction.condition[0], registers[0])
with self.subTest("classical bit"):
instruction = HGate()
with self.assertWarnsRegex(DeprecationWarning, deprecated_regex):
instructions = InstructionSet(registers)
instructions = InstructionSet(circuit_cregs=registers)
instructions.add(instruction, [Qubit()], [])
instructions.c_if(registers[0][1], 0)
self.assertIs(instruction.condition[0], registers[0][1])
for i, bit in enumerate(bits):
with self.subTest("bit index", index=i):
instruction = HGate()
with self.assertWarnsRegex(DeprecationWarning, deprecated_regex):
instructions = InstructionSet(registers)
instructions = InstructionSet(circuit_cregs=registers)
instructions.add(instruction, [Qubit()], [])
instructions.c_if(i, 0)
self.assertIs(instruction.condition[0], bit)

with self.subTest("raises on bad register"):
instruction = HGate()
with self.assertWarnsRegex(DeprecationWarning, deprecated_regex):
instructions = InstructionSet(registers)
instructions = InstructionSet(circuit_cregs=registers)
instructions.add(instruction, [Qubit()], [])
with self.assertRaisesRegex(
CircuitError, r"Condition register .* is not one of the registers known here: .*"
Expand All @@ -615,7 +615,7 @@ def dummy_requester(specifier):
with self.subTest("raises on bad bit"):
instruction = HGate()
with self.assertWarnsRegex(DeprecationWarning, deprecated_regex):
instructions = InstructionSet(registers)
instructions = InstructionSet(circuit_cregs=registers)
instructions.add(instruction, [Qubit()], [])
with self.assertRaisesRegex(
CircuitError, "Condition bit .* is not in the registers known here: .*"
Expand All @@ -624,14 +624,14 @@ def dummy_requester(specifier):
with self.subTest("raises on bad index"):
instruction = HGate()
with self.assertWarnsRegex(DeprecationWarning, deprecated_regex):
instructions = InstructionSet(registers)
instructions = InstructionSet(circuit_cregs=registers)
instructions.add(instruction, [Qubit()], [])
with self.assertRaisesRegex(CircuitError, r"Bit index .* is out-of-range\."):
instructions.c_if(len(bits), 0)
with self.subTest("raises on bad type"):
instruction = HGate()
with self.assertWarnsRegex(DeprecationWarning, deprecated_regex):
instructions = InstructionSet(registers)
instructions = InstructionSet(circuit_cregs=registers)
instructions.add(instruction, [Qubit()], [])
with self.assertRaisesRegex(CircuitError, r"Invalid classical condition\. .*"):
instructions.c_if([0], 0)
Expand Down