From 1bf76e344a498154c63e6e495854d7c86a91fe03 Mon Sep 17 00:00:00 2001 From: Mike Appleby <86076+appleby@users.noreply.github.com> Date: Tue, 17 Sep 2019 13:15:52 -0700 Subject: [PATCH] Satisfy mypy --strict about pyquil.quilatom type hints --- pyquil/quilatom.py | 30 +++++++++++++++++------------- pyquil/quilbase.py | 46 +++++++++++++++++++++++----------------------- 2 files changed, 40 insertions(+), 36 deletions(-) diff --git a/pyquil/quilatom.py b/pyquil/quilatom.py index 86fdec8f6..c3cfe5e59 100644 --- a/pyquil/quilatom.py +++ b/pyquil/quilatom.py @@ -25,19 +25,19 @@ class QuilAtom(object): Abstract class for atomic elements of Quil. """ - def out(self): + def out(self) -> str: raise NotImplementedError() - def __str__(self): + def __str__(self) -> str: raise NotImplementedError() - def __eq__(self, other): + def __eq__(self, other: object) -> bool: raise NotImplementedError() def __ne__(self, other: object) -> bool: return not self.__eq__(other) - def __hash__(self): + def __hash__(self) -> int: raise NotImplementedError() @@ -70,7 +70,7 @@ def __eq__(self, other: object) -> bool: class QubitPlaceholder(QuilAtom): - def out(self): + def out(self) -> str: raise RuntimeError("Qubit {} has not been assigned an index".format(self)) def __str__(self) -> str: @@ -125,8 +125,11 @@ def unpack_qubit(qubit: QubitDesignator) -> Union[Qubit, QubitPlaceholder]: raise TypeError("qubit should be an int or Qubit instance") -# Like the Tuple, the List must be length 2, where the first item is a string and the second an int. -MemoryReferenceDesignator = Union['MemoryReference', Tuple[str, int], List, str] +# Like the Tuple, the List must be length 2, where the first item is a string and the second an +# int. However, specifying Union[str, int] as the generic type argument to List doesn't sufficiently +# constrain the types, and mypy gets confused in unpack_classical_reg, below. Hence, just specify +# List here and add a "# type: ignore" comment to silence mypy --strict. +MemoryReferenceDesignator = Union['MemoryReference', Tuple[str, int], List, str] # type: ignore def unpack_classical_reg(c: MemoryReferenceDesignator) -> 'MemoryReference': @@ -184,7 +187,7 @@ class LabelPlaceholder(QuilAtom): def __init__(self, prefix: str = "L") -> None: self.prefix = prefix - def out(self): + def out(self) -> str: raise RuntimeError("Label has not been assigned a name") def __str__(self) -> str: @@ -245,7 +248,7 @@ def format_parameter(element: ParameterDesignator) -> str: assert False, "Invalid parameter: %r" % element -ExpressionValue = Union[int, float] +ExpressionValue = Union[int, float, complex] ExpressionOrValue = Union['Expression', ExpressionValue] @@ -365,7 +368,8 @@ class Function(Expression): """ Supported functions in Quil are sin, cos, sqrt, exp, and cis """ - def __init__(self, name: str, expression: ExpressionOrValue, fn: Callable) -> None: + def __init__(self, name: str, expression: ExpressionOrValue, + fn: Callable[[ExpressionValue], ExpressionValue]) -> None: self.name = name self.expression = expression self.fn = fn @@ -381,7 +385,7 @@ def __eq__(self, other: object) -> bool: and self.name == other.name and self.expression == other.expression) - def __neq__(self, other: 'Function'): + def __neq__(self, other: 'Function') -> bool: return not self.__eq__(other) @@ -402,7 +406,7 @@ def quil_exp(expression: ExpressionOrValue) -> Function: def quil_cis(expression: ExpressionOrValue) -> Function: - return Function('CIS', expression, lambda x: np.exp(1j * x)) + return Function('CIS', expression, lambda x: np.exp(1j * x)) # type: ignore class BinaryExp(Expression): @@ -411,7 +415,7 @@ class BinaryExp(Expression): associates: ClassVar[str] @staticmethod - def fn(a: ExpressionOrValue, b: ExpressionOrValue): + def fn(a: ExpressionOrValue, b: ExpressionOrValue) -> Union['BinaryExp', ExpressionValue]: raise NotImplementedError def __init__(self, op1: ExpressionOrValue, op2: ExpressionOrValue) -> None: diff --git a/pyquil/quilbase.py b/pyquil/quilbase.py index b81c487aa..12764fc5a 100644 --- a/pyquil/quilbase.py +++ b/pyquil/quilbase.py @@ -89,7 +89,7 @@ class Gate(AbstractInstruction): This is the pyQuil object for a quantum gate instruction. """ - def __init__(self, name, params, qubits): + def __init__(self, name, params, qubits) -> None: if not isinstance(name, string_types): raise TypeError("Gate name must be a string") @@ -221,7 +221,7 @@ class Measurement(AbstractInstruction): This is the pyQuil object for a Quil measurement instruction. """ - def __init__(self, qubit, classical_reg): + def __init__(self, qubit, classical_reg) -> None: if not isinstance(qubit, (Qubit, QubitPlaceholder)): raise TypeError("qubit should be a Qubit") if classical_reg and not isinstance(classical_reg, MemoryReference): @@ -251,7 +251,7 @@ class ResetQubit(AbstractInstruction): This is the pyQuil object for a Quil targeted reset instruction. """ - def __init__(self, qubit): + def __init__(self, qubit) -> None: if not isinstance(qubit, (Qubit, QubitPlaceholder)): raise TypeError("qubit should be a Qubit") self.qubit = qubit @@ -275,7 +275,7 @@ class DefGate(AbstractInstruction): :param list parameters: list of parameters that are used in this gate """ - def __init__(self, name, matrix, parameters=None): + def __init__(self, name, matrix, parameters=None) -> None: if not isinstance(name, string_types): raise TypeError("Gate name must be a string") @@ -370,7 +370,7 @@ def num_args(self): class DefPermutationGate(DefGate): - def __init__(self, name, permutation): + def __init__(self, name, permutation) -> None: if not isinstance(name, string_types): raise TypeError("Gate name must be a string") @@ -410,7 +410,7 @@ class JumpTarget(AbstractInstruction): Representation of a target that can be jumped to. """ - def __init__(self, label): + def __init__(self, label) -> None: if not isinstance(label, (Label, LabelPlaceholder)): raise TypeError("label must be a Label") self.label = label @@ -428,7 +428,7 @@ class JumpConditional(AbstractInstruction): """ op = NotImplemented - def __init__(self, target, condition): + def __init__(self, target, condition) -> None: if not isinstance(target, (Label, LabelPlaceholder)): raise TypeError("target should be a Label") if not isinstance(condition, MemoryReference): @@ -496,7 +496,7 @@ class UnaryClassicalInstruction(AbstractInstruction): The abstract class for unary classical instructions. """ - def __init__(self, target): + def __init__(self, target) -> None: if not isinstance(target, MemoryReference): raise TypeError("target operand should be an MemoryReference") self.target = target @@ -525,7 +525,7 @@ class LogicalBinaryOp(AbstractInstruction): """ op = NotImplemented - def __init__(self, left, right): + def __init__(self, left, right) -> None: if not isinstance(left, MemoryReference): raise TypeError("left operand should be an MemoryReference") if not isinstance(right, MemoryReference) and not isinstance(right, int): @@ -570,7 +570,7 @@ class ClassicalOr(ClassicalInclusiveOr): Deprecated class. """ - def __init__(self, left, right): + def __init__(self, left, right) -> None: warn("ClassicalOr has been deprecated. Replacing with " "ClassicalInclusiveOr. Use ClassicalInclusiveOr instead. " "NOTE: The operands to ClassicalInclusiveOr are inverted from " @@ -583,7 +583,7 @@ class ArithmeticBinaryOp(AbstractInstruction): The abstract class for binary arithmetic classical instructions. """ - def __init__(self, left, right): + def __init__(self, left, right) -> None: if not isinstance(left, MemoryReference): raise TypeError("left operand should be an MemoryReference") if not isinstance(right, MemoryReference) and not isinstance(right, int) and not isinstance(right, float): @@ -633,7 +633,7 @@ class ClassicalMove(AbstractInstruction): """ op = "MOVE" - def __init__(self, left, right): + def __init__(self, left, right) -> None: if not isinstance(left, MemoryReference): raise TypeError("Left operand of MOVE should be an MemoryReference. " "Note that the order of the operands in pyQuil 2.0 has reversed from " @@ -653,7 +653,7 @@ class ClassicalFalse(ClassicalMove): Deprecated class. """ - def __init__(self, target): + def __init__(self, target) -> None: super().__init__(target, 0) warn("ClassicalFalse is deprecated in favor of ClassicalMove.") @@ -663,7 +663,7 @@ class ClassicalTrue(ClassicalMove): Deprecated class. """ - def __init__(self, target): + def __init__(self, target) -> None: super().__init__(target, 1) warn("ClassicalTrue is deprecated in favor of ClassicalMove.") @@ -675,7 +675,7 @@ class ClassicalExchange(AbstractInstruction): op = "EXCHANGE" - def __init__(self, left, right): + def __init__(self, left, right) -> None: if not isinstance(left, MemoryReference): raise TypeError("left operand should be an MemoryReference") if not isinstance(right, MemoryReference): @@ -694,7 +694,7 @@ class ClassicalConvert(AbstractInstruction): op = "CONVERT" - def __init__(self, left, right): + def __init__(self, left, right) -> None: if not isinstance(left, MemoryReference): raise TypeError("left operand should be an MemoryReference") if not isinstance(right, MemoryReference): @@ -713,7 +713,7 @@ class ClassicalLoad(AbstractInstruction): op = "LOAD" - def __init__(self, target, left, right): + def __init__(self, target, left, right) -> None: if not isinstance(target, MemoryReference): raise TypeError("target operand should be an MemoryReference") if not isinstance(right, MemoryReference): @@ -733,7 +733,7 @@ class ClassicalStore(AbstractInstruction): op = "STORE" - def __init__(self, target, left, right): + def __init__(self, target, left, right) -> None: if not isinstance(left, MemoryReference): raise TypeError("left operand should be an MemoryReference") if not (isinstance(right, MemoryReference) or isinstance(right, int) @@ -752,7 +752,7 @@ class ClassicalComparison(AbstractInstruction): Abstract class for ternary comparison instructions. """ - def __init__(self, target, left, right): + def __init__(self, target, left, right) -> None: if not isinstance(target, MemoryReference): raise TypeError("target operand should be an MemoryReference") if not isinstance(left, MemoryReference): @@ -810,7 +810,7 @@ class Jump(AbstractInstruction): Representation of an unconditional jump instruction (JUMP). """ - def __init__(self, target): + def __init__(self, target) -> None: if not isinstance(target, (Label, LabelPlaceholder)): raise TypeError("target should be a Label") self.target = target @@ -829,7 +829,7 @@ class Pragma(AbstractInstruction): """ - def __init__(self, command, args=(), freeform_string=""): + def __init__(self, command, args=(), freeform_string="") -> None: if not isinstance(command, string_types): raise TypeError("Pragma's require an identifier.") @@ -871,7 +871,7 @@ class Declare(AbstractInstruction): """ - def __init__(self, name, memory_type, memory_size=1, shared_region=None, offsets=None): + def __init__(self, name, memory_type, memory_size=1, shared_region=None, offsets=None) -> None: self.name = name self.memory_type = memory_type self.memory_size = memory_size @@ -908,7 +908,7 @@ class RawInstr(AbstractInstruction): A raw instruction represented as a string. """ - def __init__(self, instr_str): + def __init__(self, instr_str) -> None: if not isinstance(instr_str, string_types): raise TypeError("Raw instructions require a string.") self.instr = instr_str