Skip to content

Commit

Permalink
Remove public fields for pauli ops (quantumlib#5062)
Browse files Browse the repository at this point in the history
quantumlib#4851 for all the pauli stuff.

I skipped BaseDensePauliString because including `cirq._compat` there makes a weird circular dependency.
  • Loading branch information
daxfohl authored Mar 13, 2022
1 parent e4ac8e6 commit e1c3e49
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 10 deletions.
58 changes: 53 additions & 5 deletions cirq/ops/pauli_interaction_gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import numpy as np

from cirq import value, protocols
from cirq._compat import proper_repr
from cirq._compat import deprecated, proper_repr
from cirq.ops import gate_features, common_gates, eigen_gate, pauli_gates
from cirq.ops.clifford_gate import SingleQubitCliffordGate

Expand Down Expand Up @@ -66,10 +66,58 @@ def __init__(
equal to the tensor product of the two conditions.
"""
super().__init__(exponent=exponent)
self.pauli0 = pauli0
self.invert0 = invert0
self.pauli1 = pauli1
self.invert1 = invert1
self._pauli0 = pauli0
self._invert0 = invert0
self._pauli1 = pauli1
self._invert1 = invert1

@property
def pauli0(self) -> 'cirq.Pauli':
return self._pauli0

@pauli0.setter # type: ignore
@deprecated(
deadline="v0.15",
fix="The mutators of this class are deprecated, instantiate a new object instead.",
)
def pauli0(self, pauli0: 'cirq.Pauli'):
self._pauli0 = pauli0

@property
def invert0(self) -> bool:
return self._invert0

@invert0.setter # type: ignore
@deprecated(
deadline="v0.15",
fix="The mutators of this class are deprecated, instantiate a new object instead.",
)
def invert0(self, invert0: bool):
self._invert0 = invert0

@property
def pauli1(self) -> 'cirq.Pauli':
return self._pauli1

@pauli1.setter # type: ignore
@deprecated(
deadline="v0.15",
fix="The mutators of this class are deprecated, instantiate a new object instead.",
)
def pauli1(self, pauli1: 'cirq.Pauli'):
self._pauli1 = pauli1

@property
def invert1(self) -> bool:
return self._invert1

@invert1.setter # type: ignore
@deprecated(
deadline="v0.15",
fix="The mutators of this class are deprecated, instantiate a new object instead.",
)
def invert1(self, invert1: bool):
self._invert1 = invert1

def _num_qubits_(self) -> int:
return 2
Expand Down
16 changes: 16 additions & 0 deletions cirq/ops/pauli_interaction_gate_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,19 @@ def test_text_diagrams():
q1: ───X───X──────(-X)───(-X)───Y───@───Y───(-@)───(-Y)───
""".strip()
)


def test_setters_deprecated():
gate = cirq.PauliInteractionGate(cirq.X, False, cirq.X, False)
with cirq.testing.assert_deprecated('mutators', deadline='v0.15'):
gate.pauli0 = cirq.Y
assert gate.pauli0 == cirq.Y
with cirq.testing.assert_deprecated('mutators', deadline='v0.15'):
gate.pauli1 = cirq.Y
assert gate.pauli1 == cirq.Y
with cirq.testing.assert_deprecated('mutators', deadline='v0.15'):
gate.invert0 = True
assert gate.invert0
with cirq.testing.assert_deprecated('mutators', deadline='v0.15'):
gate.invert1 = True
assert gate.invert1
27 changes: 23 additions & 4 deletions cirq/ops/pauli_measurement_gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from typing import Any, Dict, FrozenSet, Iterable, Tuple, Sequence, TYPE_CHECKING, Union, cast

from cirq import protocols, value
from cirq._compat import deprecated
from cirq.ops import (
raw_types,
measurement_gate,
Expand Down Expand Up @@ -68,17 +69,35 @@ def __init__(
)

self._observable = dps.DensePauliString(observable, coefficient=coefficient)
self.key = key # type: ignore
self._mkey = (
key if isinstance(key, value.MeasurementKey) else value.MeasurementKey(name=key)
)

@property
def key(self) -> str:
return str(self.mkey)

@key.setter
def key(self, key: Union[str, 'cirq.MeasurementKey']) -> None:
@key.setter # type: ignore
@deprecated(
deadline="v0.15",
fix="The mutators of this class are deprecated, instantiate a new object instead.",
)
def key(self, key: Union[str, 'cirq.MeasurementKey']):
if isinstance(key, str):
key = value.MeasurementKey(name=key)
self.mkey = key
self._mkey = key

@property
def mkey(self) -> 'cirq.MeasurementKey':
return self._mkey

@mkey.setter # type: ignore
@deprecated(
deadline="v0.15",
fix="The mutators of this class are deprecated, instantiate a new object instead.",
)
def mkey(self, mkey: 'cirq.MeasurementKey'):
self._mkey = mkey

def _qid_shape_(self) -> Tuple[int, ...]:
return (2,) * len(self._observable)
Expand Down
16 changes: 16 additions & 0 deletions cirq/ops/pauli_measurement_gate_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,19 @@ def test_pauli_measurement_gate_samples(rot, obs, out):
q = cirq.NamedQubit("q")
c = cirq.Circuit(rot(q), cirq.PauliMeasurementGate(obs, key='out').on(q))
assert cirq.Simulator().sample(c)['out'][0] == out


def test_setters_deprecated():
gate = cirq.PauliMeasurementGate(cirq.DensePauliString("Z", coefficient=+1), key='m')
with cirq.testing.assert_deprecated('mutators', deadline='v0.15'):
gate.key = 'n'
assert gate.key == 'n'
assert gate.mkey == cirq.MeasurementKey('n')
with cirq.testing.assert_deprecated('mutators', deadline='v0.15'):
gate.key = cirq.MeasurementKey('o')
assert gate.key == 'o'
assert gate.mkey == cirq.MeasurementKey('o')
with cirq.testing.assert_deprecated('mutators', deadline='v0.15'):
gate.mkey = cirq.MeasurementKey('p')
assert gate.key == 'p'
assert gate.mkey == cirq.MeasurementKey('p')
15 changes: 14 additions & 1 deletion cirq/ops/pauli_string_raw_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import abc

from cirq import protocols
from cirq._compat import deprecated
from cirq.ops import pauli_string as ps, raw_types

if TYPE_CHECKING:
Expand All @@ -29,7 +30,19 @@

class PauliStringGateOperation(raw_types.Operation, metaclass=abc.ABCMeta):
def __init__(self, pauli_string: ps.PauliString) -> None:
self.pauli_string = pauli_string
self._pauli_string = pauli_string

@property
def pauli_string(self) -> 'cirq.PauliString':
return self._pauli_string

@pauli_string.setter # type: ignore
@deprecated(
deadline="v0.15",
fix="The mutators of this class are deprecated, instantiate a new object instead.",
)
def pauli_string(self, pauli_string: 'cirq.PauliString'):
self._pauli_string = pauli_string

def validate_args(self, qubits: Sequence[raw_types.Qid]) -> None:
if len(qubits) != len(self.pauli_string):
Expand Down
13 changes: 13 additions & 0 deletions cirq/ops/pauli_string_raw_types_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,16 @@ def _circuit_diagram_info_(
q2: ───[Z]───[Z]───
""",
)


def test_setters_deprecated():
q0 = cirq.LineQubit(0)

class DummyGate(cirq.PauliStringGateOperation):
def map_qubits(self, qubit_map):
pass

gate = DummyGate(cirq.PauliString({q0: cirq.X}))
with cirq.testing.assert_deprecated('mutators', deadline='v0.15'):
gate.pauli_string = cirq.PauliString({q0: cirq.Z})
assert gate.pauli_string == cirq.PauliString({q0: cirq.Z})

0 comments on commit e1c3e49

Please sign in to comment.