Skip to content

Commit

Permalink
Remove deprecated methods and improve reprs (#2717)
Browse files Browse the repository at this point in the history
- Delete all v0.8 deprecated methods
- Allow cirq.Moment to take OP_TREE arguments, deprecate `operations=` keyword.
- GateOperation now prefers reprs like "{gate}({qubits})" when it can prove "{gate}" is safe to append () onto
- ControlledOperation now prefers reprs like "{op}.controlled_by({qubits})"
- GateOperation can now delegate to _op_repr_ of its gate
- MeasurementGate now prefers op reprs like "cirq.measure({})"
- Fix a few type annotations not using top-level types
  • Loading branch information
Strilanc committed Apr 28, 2020
1 parent b4c4066 commit 4e86982
Show file tree
Hide file tree
Showing 33 changed files with 202 additions and 468 deletions.
10 changes: 0 additions & 10 deletions cirq/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,18 +195,15 @@
generalized_amplitude_damp,
GeneralizedAmplitudeDampingChannel,
givens,
GivensRotation,
GlobalPhaseOperation,
H,
HPowGate,
I,
identity_each,
IdentityGate,
IdentityOperation,
InterchangeableQubitsGate,
ISWAP,
ISwapPowGate,
ISwapRotation,
LinearCombinationOfGates,
LinearCombinationOfOperations,
MatrixGate,
Expand All @@ -216,7 +213,6 @@
Moment,
MutableDensePauliString,
NamedQubit,
op_gate_of_type,
OP_TREE,
Operation,
ParallelGateOperation,
Expand Down Expand Up @@ -246,17 +242,13 @@
reset,
ResetChannel,
riswap,
Rx,
rx,
Ry,
ry,
Rz,
rz,
S,
SingleQubitCliffordGate,
SingleQubitGate,
SingleQubitPauliStringGateOperation,
SingleQubitMatrixGate,
SWAP,
SwapPowGate,
T,
Expand All @@ -266,7 +258,6 @@
TOFFOLI,
transform_op_tree,
TwoQubitGate,
TwoQubitMatrixGate,
WaitGate,
X,
XPowGate,
Expand Down Expand Up @@ -469,7 +460,6 @@
from cirq.ion import (
ConvertToIonGates,
IonDevice,
MS,
ms,
two_qubit_matrix_to_ion_operations,
)
Expand Down
43 changes: 3 additions & 40 deletions cirq/circuits/circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import numpy as np

from cirq import devices, linalg, ops, protocols
from cirq._compat import deprecated, deprecated_parameter
from cirq.circuits._bucket_priority_queue import BucketPriorityQueue
from cirq.circuits.insert_strategy import InsertStrategy
from cirq.circuits.text_diagram_drawer import TextDiagramDrawer
Expand Down Expand Up @@ -101,23 +100,6 @@ class Circuit:
circuit[1:7] = [Moment(...)]
"""

@deprecated_parameter(
deadline='v0.8',
fix='Pass circuit contents positionally (without a keyword).',
func_name='cirq.Circuit',
parameter_desc='moments keyword',
match=lambda args, kwargs: 'moments' in kwargs,
rewrite=lambda args, kwargs: (args + (kwargs[
'moments'],), {k: v for k, v in kwargs.items() if k != 'moments'}))
@deprecated_parameter(
deadline='v0.8',
fix='Pass the device using the "device=" keyword.',
func_name='cirq.Circuit',
parameter_desc='positional device',
match=lambda args, kwargs: len(args) == 3 and isinstance(
args[2], devices.Device),
rewrite=lambda args, kwargs: (
args[:2], dict(list(kwargs.items()) + [('device', args[2])])))
def __init__(self,
*contents: 'cirq.OP_TREE',
strategy: 'cirq.InsertStrategy' = InsertStrategy.EARLIEST,
Expand Down Expand Up @@ -149,26 +131,6 @@ def device(self, new_device: 'cirq.Device') -> None:
new_device.validate_circuit(self)
self._device = new_device

@staticmethod
@deprecated(deadline='v0.8.0', fix='use `cirq.Circuit(*ops)` instead.')
def from_ops(*operations: 'cirq.OP_TREE',
strategy: 'cirq.InsertStrategy' = InsertStrategy.EARLIEST,
device: 'cirq.Device' = devices.UNCONSTRAINED_DEVICE
) -> 'Circuit':
"""Creates an empty circuit and appends the given operations.
Args:
operations: The operations to append to the new circuit.
strategy: How to append the operations.
device: Hardware that the circuit should be able to run on.
Returns:
The constructed circuit containing the operations.
"""
result = Circuit(device=device)
result.append(operations, strategy)
return result

def __copy__(self) -> 'Circuit':
return self.copy()

Expand Down Expand Up @@ -1111,11 +1073,12 @@ def insert(
self._moments.insert(k, moment_or_op)
k += 1
else:
op = cast(ops.Operation, moment_or_op)
p = self._pick_or_create_inserted_op_moment_index(
k, moment_or_op, strategy)
k, op, strategy)
while p >= len(self._moments):
self._moments.append(ops.Moment())
self._moments[p] = self._moments[p].with_operation(moment_or_op)
self._moments[p] = self._moments[p].with_operation(op)
self._device.validate_moment(self._moments[p])
k = max(k, p + 1)
if strategy is InsertStrategy.NEW_THEN_INLINE:
Expand Down
4 changes: 2 additions & 2 deletions cirq/circuits/circuit_dag_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ def test_wrapper_repr():
q0 = cirq.LineQubit(0)

node = cirq.CircuitDag.make_node(cirq.X(q0))
assert (repr(node) ==
'cirq.Unique(' + str(id(node)) + ', cirq.X.on(cirq.LineQubit(0)))')
assert (repr(node) == 'cirq.Unique(' + str(id(node)) +
', cirq.X(cirq.LineQubit(0)))')


def test_init():
Expand Down
90 changes: 18 additions & 72 deletions cirq/circuits/circuit_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

import cirq
import cirq.google as cg
from cirq._compat_test import capture_logging
from cirq import ops


Expand Down Expand Up @@ -285,14 +284,14 @@ def test_repr():
])
cirq.testing.assert_equivalent_repr(c)
assert repr(c) == """cirq.Circuit([
cirq.Moment(operations=[
cirq.H.on(cirq.NamedQubit('a')),
cirq.H.on(cirq.NamedQubit('b')),
]),
cirq.Moment(
cirq.H(cirq.NamedQubit('a')),
cirq.H(cirq.NamedQubit('b')),
),
cirq.Moment(),
cirq.Moment(operations=[
cirq.CZ.on(cirq.NamedQubit('a'), cirq.NamedQubit('b')),
]),
cirq.Moment(
cirq.CZ(cirq.NamedQubit('a'), cirq.NamedQubit('b')),
),
])"""

c = cirq.Circuit(device=cg.Foxtail)
Expand All @@ -302,9 +301,9 @@ def test_repr():
c = cirq.Circuit(cirq.Z(cirq.GridQubit(0, 0)), device=cg.Foxtail)
cirq.testing.assert_equivalent_repr(c)
assert repr(c) == """cirq.Circuit([
cirq.Moment(operations=[
cirq.Z.on(cirq.GridQubit(0, 0)),
]),
cirq.Moment(
cirq.Z(cirq.GridQubit(0, 0)),
),
], device=cirq.google.Foxtail)"""

def test_empty_moments():
Expand Down Expand Up @@ -1182,11 +1181,10 @@ def test_findall_operations_until_blocked():

assert_findall_operations_until_blocked_as_expected()

circuit = cirq.Circuit.from_ops(cirq.H(a), cirq.CZ(a, b), cirq.H(b),
cirq.CZ(b, c), cirq.H(c), cirq.CZ(c, d),
cirq.H(d), cirq.CZ(c, d), cirq.H(c),
cirq.CZ(b, c), cirq.H(b), cirq.CZ(a, b),
cirq.H(a))
circuit = cirq.Circuit(cirq.H(a), cirq.CZ(a, b), cirq.H(b), cirq.CZ(b, c),
cirq.H(c), cirq.CZ(c, d), cirq.H(d), cirq.CZ(c, d),
cirq.H(c), cirq.CZ(b, c), cirq.H(b), cirq.CZ(a, b),
cirq.H(a))
expected_diagram = """
0: ───H───@───────────────────────────────────────@───H───
│ │
Expand Down Expand Up @@ -1259,9 +1257,7 @@ def test_findall_operations_until_blocked():
is_blocker=stop_if_h_on_a,
expected_ops=[(11, cirq.CZ.on(a, b))])

circuit = cirq.Circuit.from_ops(
[cirq.CZ(a, b), cirq.CZ(a, b),
cirq.CZ(b, c)])
circuit = cirq.Circuit([cirq.CZ(a, b), cirq.CZ(a, b), cirq.CZ(b, c)])
expected_diagram = """
0: ───@───@───────
│ │
Expand All @@ -1281,7 +1277,7 @@ def test_findall_operations_until_blocked():
is_blocker=is_blocker,
expected_ops=expected_ops)

circuit = cirq.Circuit.from_ops([cirq.ZZ(a, b), cirq.ZZ(b, c)])
circuit = cirq.Circuit([cirq.ZZ(a, b), cirq.ZZ(b, c)])
expected_diagram = """
0: ───ZZ────────
Expand All @@ -1300,7 +1296,7 @@ def test_findall_operations_until_blocked():
is_blocker=is_blocker,
expected_ops=[])

circuit = cirq.Circuit.from_ops(
circuit = cirq.Circuit(
[cirq.ZZ(a, b), cirq.XX(c, d),
cirq.ZZ(b, c), cirq.Z(b)])
expected_diagram = """
Expand All @@ -1323,7 +1319,7 @@ def test_findall_operations_until_blocked():
is_blocker=is_blocker,
expected_ops=[(0, cirq.ZZ(a, b))])

circuit = cirq.Circuit.from_ops(
circuit = cirq.Circuit(
[cirq.XX(a, b),
cirq.Z(a),
cirq.ZZ(b, c),
Expand Down Expand Up @@ -1776,56 +1772,6 @@ def _qid_shape_(self):
_ = circuit.qid_shape(qubit_order=[b, c])


def test_deprecated_circuit_init_parameter_positional_device():
with capture_logging() as log:
actual = cirq.Circuit([], cirq.UNCONSTRAINED_DEVICE)
assert len(log) == 1
assert 'positional device parameter' in log[0].getMessage()
assert 'deprecated' in log[0].getMessage()

assert actual == cirq.Circuit(device=cirq.UNCONSTRAINED_DEVICE)


def test_deprecated_circuit_init_parameter_moments_keywords():
a = cirq.LineQubit(0)
with capture_logging() as log:
# pylint: disable=unexpected-keyword-arg
actual = cirq.Circuit(moments=[cirq.X(a)])
# pylint: enable=unexpected-keyword-arg
assert len(log) == 1
assert 'moments keyword parameter' in log[0].getMessage()
assert 'deprecated' in log[0].getMessage()

assert actual == cirq.Circuit(cirq.X(a))


def test_deprecated_from_ops():
a = cirq.NamedQubit('a')
b = cirq.NamedQubit('b')

with capture_logging() as log:
_ = cirq.Circuit.from_ops()
assert len(log) == 1
assert 'Circuit.from_ops' in log[0].getMessage()
assert 'deprecated' in log[0].getMessage()

with capture_logging():
actual = cirq.Circuit.from_ops(
cirq.X(a),
[cirq.Y(a), cirq.Z(b)],
cirq.CZ(a, b),
cirq.X(a),
[cirq.Z(b), cirq.Y(a)],
)
assert actual == cirq.Circuit([
cirq.Moment([cirq.X(a), cirq.Z(b)]),
cirq.Moment([cirq.Y(a)]),
cirq.Moment([cirq.CZ(a, b)]),
cirq.Moment([cirq.X(a), cirq.Z(b)]),
cirq.Moment([cirq.Y(a)]),
])


def test_to_text_diagram_teleportation_to_diagram():
ali = cirq.NamedQubit('(0, 0)')
bob = cirq.NamedQubit('(0, 1)')
Expand Down
4 changes: 1 addition & 3 deletions cirq/ion/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@
"""

from cirq.ion.ion_gates import (
MS,
ms,
)
ms,)

from cirq.ion.ion_decomposition import (
two_qubit_matrix_to_ion_operations,)
Expand Down
8 changes: 1 addition & 7 deletions cirq/ion/ion_gates.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import numpy as np

from cirq import ops
from cirq._compat import deprecated


def ms(rads: float) -> ops.XXPowGate:
Expand All @@ -38,9 +37,4 @@ def ms(rads: float) -> ops.XXPowGate:
Returns:
Mølmer–Sørensen gate rotating by the desired amount.
"""
return ops.XXPowGate(exponent=rads*2/np.pi, global_shift=-0.5)


@deprecated(deadline='v0.8.0', fix='Use cirq.ms, instead.')
def MS(rads: float) -> ops.XXPowGate:
return ms(rads)
return ops.XXPowGate(exponent=rads * 2 / np.pi, global_shift=-0.5)
12 changes: 2 additions & 10 deletions cirq/ion/ion_gates_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@
# limitations under the License.

import numpy as np
import pytest

import cirq
from cirq._compat_test import capture_logging


def test_ms_arguments():
Expand Down Expand Up @@ -56,15 +54,9 @@ def test_ms_diagrams():
b = cirq.NamedQubit('b')
circuit = cirq.Circuit(cirq.SWAP(a, b), cirq.X(a), cirq.Y(a),
cirq.ms(np.pi).on(a, b))
cirq.testing.assert_has_diagram(circuit, """
cirq.testing.assert_has_diagram(
circuit, """
a: ───×───X───Y───MS(π)───
│ │
b: ───×───────────MS(π)───
""")


@pytest.mark.parametrize('rads', (-1, -0.1, 0.2, 1))
def test_deprecated_ms(rads):
with capture_logging():
assert np.all(
cirq.unitary(cirq.ms(rads)) == cirq.unitary(cirq.MS(rads)))

0 comments on commit 4e86982

Please sign in to comment.