diff --git a/CHANGELOG.md b/CHANGELOG.md index daae26bfb..2355ce4b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ The 4.0 release of pyQuil migrates its core functionality into Rigetti's latest - The `pyquil.quil.get_default_qubit_mapping` function for getting a mapping of `QubitPlaceholders` to resolved indices has been removed. Generating a default mapping is handled automatically by the placeholder resolving methods. - The `JumpConditional` base class has been removed, use `JumpWhen` and/or `JumpUnless` directly instead. - The `Program` class automatically sorts `DECLARE` instructions to the top of the Program when converting to Quil. +- `FenceAll` is now a subclass of `Fence`. This can be impactful if you are doing something like `isinstance(instruction, Fence)` since that will now match `Fence` and `FenceAll`. If the difference between the two is important, check for `FenceAll` first. You can also check if the `qubits` property is empty, which implies a `FenceAll` instruction. ### Features @@ -62,7 +63,7 @@ installation, perform diagnostics checks, and return a summary. - `percolate_declares` is a no-op and will be removed in future versions. `Program` now “percolates” declares automatically. - `merge_programs` continues to work, but will be removed in future versions, use `Program` addition instead. - The `format_parameter` function continues to work, but will be removed in future versions. -- The `WaveformReference` and `TemplateWaveform` classes continue to work, but will be removed in future versions. The new `WaveformInvocation` should be used instead. +- The `WaveformReference` class continues to work, but will be removed in future versions. The new `WaveformInvocation` should be used instead. ## 3.5.4 diff --git a/pyquil/quil.py b/pyquil/quil.py index 5ef7d5d1d..78fefbfb0 100644 --- a/pyquil/quil.py +++ b/pyquil/quil.py @@ -31,6 +31,7 @@ Sequence, Set, Tuple, + TypeVar, Union, cast, ) @@ -100,6 +101,9 @@ ] +RetType = TypeVar("RetType") + + class Program: """ A list of pyQuil instructions that comprise a quantum program. diff --git a/pyquil/quilatom.py b/pyquil/quilatom.py index 2680d0c50..7ab1d3eb3 100644 --- a/pyquil/quilatom.py +++ b/pyquil/quilatom.py @@ -13,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. ############################################################################## - from fractions import Fraction import inspect from numbers import Number @@ -1015,10 +1014,12 @@ def fget(self: "TemplateWaveform") -> Optional[ParameterDesignator]: return parameter if dtype is int or dtype is float: + if isinstance(parameter, dtype): + return parameter if not isinstance(parameter, complex): raise TypeError( - f"Requested float for parameter {name}, but a non-numeric value of type {type(parameter)} was found" - "instead" + f"Requested float for parameter {name}, but a non-numeric value of type {type(parameter)} was " + "found instead" ) if parameter.imag != 0.0: raise ValueError( @@ -1037,10 +1038,6 @@ def fdel(self: "TemplateWaveform") -> None: return property(fget, fset, fdel, doc) -@deprecated( - version="4.0", - reason="The TemplateWaveform class will be removed, consider using WaveformInvocation instead.", -) class TemplateWaveform(quil_rs.WaveformInvocation, QuilAtom): NAME: ClassVar[str] @@ -1136,7 +1133,7 @@ def _from_rs_waveform_invocation(cls, waveform: quil_rs.WaveformInvocation) -> " ] if set(waveform.parameters.keys()).issubset(parameter_names): try: - parameters = {key: value.inner() for key, value in waveform.parameters.items()} + parameters = {key: _convert_to_py_expression(value) for key, value in waveform.parameters.items()} return template(**parameters) # type: ignore[arg-type] except TypeError: break diff --git a/pyquil/quilbase.py b/pyquil/quilbase.py index 7d67f6df7..96018c362 100644 --- a/pyquil/quilbase.py +++ b/pyquil/quilbase.py @@ -219,6 +219,8 @@ def _convert_to_py_instruction(instr: Any) -> AbstractInstruction: if isinstance(instr, quil_rs.Delay): return Delay._from_rs_delay(instr) if isinstance(instr, quil_rs.Fence): + if len(instr.qubits) == 0: + return FenceAll() return Fence._from_rs_fence(instr) if isinstance(instr, quil_rs.FrameDefinition): return DefFrame._from_rs_frame_definition(instr) @@ -2352,7 +2354,6 @@ def parameters(self) -> Sequence[ParameterDesignator]: @parameters.setter def parameters(self, parameters: Sequence[ParameterDesignator]) -> None: - quil_rs.Calibration.parameters.__set__(self, _convert_to_rs_expressions(parameters)) # type: ignore[attr-defined] # noqa @property # type: ignore[override] diff --git a/pyquil/quiltwaveforms.py b/pyquil/quiltwaveforms.py index 0b570ce01..dc388d362 100644 --- a/pyquil/quiltwaveforms.py +++ b/pyquil/quiltwaveforms.py @@ -1,8 +1,6 @@ from typing import Optional from typing_extensions import Self -from warnings import warn -from deprecated.sphinx import deprecated import numpy as np from scipy.special import erf @@ -12,17 +10,7 @@ _template_waveform_property, ) -warn( - DeprecationWarning("The quiltwaveforms module is deprecated. Use quilatom.WaveformInvocation instead."), - category=DeprecationWarning, - stacklevel=2, -) - -@deprecated( - version="4.0", - reason="The TemplateWaveform class and its subclasses will be removed, consider using WaveformInvocation instead.", -) class FlatWaveform(TemplateWaveform): """ A flat (constant) waveform. @@ -50,10 +38,6 @@ def samples(self, rate: float) -> np.ndarray: return _update_envelope(iqs, rate, scale=self.scale, phase=self.phase, detuning=self.detuning) -@deprecated( - version="4.0", - reason="The TemplateWaveform class and its subclasses will be removed, consider using WaveformInvocation instead.", -) class GaussianWaveform(TemplateWaveform): """A Gaussian pulse.""" @@ -89,10 +73,6 @@ def samples(self, rate: float) -> np.ndarray: return _update_envelope(iqs, rate, scale=self.scale, phase=self.phase, detuning=self.detuning) -@deprecated( - version="4.0", - reason="The TemplateWaveform class and its subclasses will be removed, consider using WaveformInvocation instead.", -) class DragGaussianWaveform(TemplateWaveform): """A DRAG Gaussian pulse.""" @@ -145,10 +125,6 @@ def samples(self, rate: float) -> np.ndarray: return _update_envelope(iqs, rate, scale=self.scale, phase=self.phase, detuning=self.detuning) -@deprecated( - version="4.0", - reason="The TemplateWaveform class and its subclasses will be removed, consider using WaveformInvocation instead.", -) class HrmGaussianWaveform(TemplateWaveform): """A Hermite Gaussian waveform. @@ -221,10 +197,6 @@ def samples(self, rate: float) -> np.ndarray: return _update_envelope(iqs, rate, scale=self.scale, phase=self.phase, detuning=self.detuning) -@deprecated( - version="4.0", - reason="The TemplateWaveform class and its subclasses will be removed, consider using WaveformInvocation instead.", -) class ErfSquareWaveform(TemplateWaveform): """A pulse with a flat top and edges that are error functions (erf).""" @@ -283,10 +255,6 @@ def samples(self, rate: float) -> np.ndarray: return _update_envelope(iqs, rate, scale=self.scale, phase=self.phase, detuning=self.detuning) -@deprecated( - version="4.0", - reason="The TemplateWaveform class and its subclasses will be removed, consider using WaveformInvocation instead.", -) class BoxcarAveragerKernel(TemplateWaveform): NAME = "boxcar_kernel" diff --git a/test/unit/test_quil.py b/test/unit/test_quil.py index 394b5a6e9..65bc05dc0 100644 --- a/test/unit/test_quil.py +++ b/test/unit/test_quil.py @@ -1136,3 +1136,4 @@ def test_copy_everything_except_instructions(): program = program.copy_everything_except_instructions() assert len(program.instructions) == 0 # the purpose of copy_everything_except_instructions() assert len(program.declarations) == 0 # this is a view on the instructions member; must be consistent +