Skip to content

Commit a95a2e3

Browse files
authored
Fix TrialResult deprecation (#3381) (#3382)
Fix TrialResult deprecation to cater for JSON parsing of old JSON formats. It adds back the TrialResult json and repr files for the json repr testing, adds extra tests for the old, TrialResult based JSON parsing. It also adds the ability to deprecate classes properly via `@deprecate_class`. Fixes #3380.
1 parent 785ffaf commit a95a2e3

File tree

7 files changed

+410
-4
lines changed

7 files changed

+410
-4
lines changed

cirq/_compat.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"""Workarounds for compatibility issues between versions and libraries."""
1616
import functools
1717
import warnings
18-
from typing import Any, Callable, Optional, Dict, Tuple
18+
from typing import Any, Callable, Optional, Dict, Tuple, Type
1919
from types import ModuleType
2020

2121
import numpy as np
@@ -122,6 +122,47 @@ def decorated_func(*args, **kwargs) -> Any:
122122
return decorator
123123

124124

125+
def deprecated_class(*, deadline: str, fix: str,
126+
name: Optional[str] = None) -> Callable[[Type], Type]:
127+
"""Marks a class as deprecated.
128+
129+
Args:
130+
deadline: The version where the function will be deleted (e.g. "v0.7").
131+
fix: A complete sentence describing what the user should be using
132+
instead of this particular function (e.g. "Use cos instead.")
133+
name: How to refer to the class.
134+
Defaults to `class.__qualname__`.
135+
136+
Returns:
137+
A decorator that decorates classes with a deprecation warning.
138+
"""
139+
140+
def decorator(clazz: Type) -> Type:
141+
clazz_new = clazz.__new__
142+
143+
def patched_new(cls, *args, **kwargs):
144+
qualname = (clazz.__qualname__ if name is None else name)
145+
print(f"HELLO {qualname}")
146+
warnings.warn(
147+
f'{qualname} was used but is deprecated.\n'
148+
f'It will be removed in cirq {deadline}.\n'
149+
f'{fix}\n',
150+
DeprecationWarning,
151+
stacklevel=2)
152+
153+
return clazz_new(cls)
154+
155+
setattr(clazz, '__new__', patched_new)
156+
clazz.__doc__ = (f'THIS CLASS IS DEPRECATED.\n\n'
157+
f'IT WILL BE REMOVED IN `cirq {deadline}`.\n\n'
158+
f'{fix}\n\n'
159+
f'{clazz.__doc__ or ""}')
160+
161+
return clazz
162+
163+
return decorator
164+
165+
125166
def deprecated_parameter(
126167
*,
127168
deadline: str,

cirq/_compat_test.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
import cirq.testing
2222
from cirq._compat import (proper_repr, deprecated, deprecated_parameter,
23-
proper_eq, wrap_module)
23+
proper_eq, wrap_module, deprecated_class)
2424

2525

2626
def test_proper_repr():
@@ -152,3 +152,35 @@ def test_wrap_module():
152152

153153
with cirq.testing.assert_logs(count=0):
154154
_ = wrapped.bar
155+
156+
157+
def test_deprecated_class():
158+
159+
class NewClass:
160+
161+
def __init__(self, a):
162+
self._a = a
163+
164+
@property
165+
def a(self):
166+
return self._a
167+
168+
def __repr__(self):
169+
return f"NewClass: {self.a}"
170+
171+
@classmethod
172+
def hello(cls):
173+
return f"hello {cls}"
174+
175+
@deprecated_class(deadline="deadline", fix="theFix", name="foo")
176+
class OldClass(NewClass):
177+
"""The OldClass docs"""
178+
179+
assert OldClass.__doc__.startswith("THIS CLASS IS DEPRECATED")
180+
assert "OldClass docs" in OldClass.__doc__
181+
182+
with cirq.testing.assert_logs('foo was used but is deprecated',
183+
'will be removed in cirq deadline', 'theFix'):
184+
old_obj = OldClass("1")
185+
assert repr(old_obj) == "NewClass: 1"
186+
assert "OldClass" in old_obj.hello()

cirq/protocols/json_serialization.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ def two_qubit_matrix_gate(matrix):
160160
'TaggedOperation': cirq.TaggedOperation,
161161
'ThreeDQubit': cirq.pasqal.ThreeDQubit,
162162
'Result': cirq.Result,
163+
'TrialResult': cirq.TrialResult,
163164
'TwoDQubit': cirq.pasqal.TwoDQubit,
164165
'TwoQubitMatrixGate': two_qubit_matrix_gate,
165166
'TwoQubitDiagonalGate': cirq.TwoQubitDiagonalGate,

0 commit comments

Comments
 (0)