Skip to content

Commit

Permalink
Satisfy mypy --strict about pyquil.quilatom type hints
Browse files Browse the repository at this point in the history
  • Loading branch information
appleby committed Sep 23, 2019
1 parent 394f076 commit 1bf76e3
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 36 deletions.
30 changes: 17 additions & 13 deletions pyquil/quilatom.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()


Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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':
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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]


Expand Down Expand Up @@ -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
Expand All @@ -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)


Expand All @@ -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):
Expand All @@ -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:
Expand Down
46 changes: 23 additions & 23 deletions pyquil/quilbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")

Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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
Expand All @@ -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")

Expand Down Expand Up @@ -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")

Expand Down Expand Up @@ -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
Expand All @@ -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):
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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 "
Expand All @@ -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):
Expand Down Expand Up @@ -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 "
Expand All @@ -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.")

Expand All @@ -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.")

Expand All @@ -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):
Expand All @@ -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):
Expand All @@ -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):
Expand All @@ -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)
Expand All @@ -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):
Expand Down Expand Up @@ -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
Expand All @@ -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.")

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 1bf76e3

Please sign in to comment.