Repository: rigetticomputing/pyquil
Pull request #154 (2017-10-22 02:45:13)

ID and ZERO: switch to be defined as a function instead
Rationale: see https://github.com/rigetticomputing/pyquil/pull/153#discussion_r146120458

stevenheidel: Can you make sure the tests are passing?
rht: @stevenheidel test passed ! I also checked that a `PauliTerm` can't be hashed, which doesn't pass the condition of immutability as stated at point 3 in https://stackoverflow.com/a/4374075/595474.
rht: Wait. It's because `__hash__` hasn't been defined for `PauliTerm`. But this PR is for to be on the safe side (construct a new ID or ZERO each time).

Patch:
diff --git a/pyquil/paulis.py b/pyquil/paulis.py
index c2fadc9..d068a9d 100644
--- a/pyquil/paulis.py
+++ b/pyquil/paulis.py
@@ -292,14 +292,18 @@ class PauliTerm(object):
 
 
 # For convenience, a shorthand for several operators.
-ID = PauliTerm("I", 0, 1)
-"""
-The identity Pauli Term.
-"""
-ZERO = PauliTerm("I", 0, 0)
-"""
-The zero Pauli Term.
-"""
+def ID():
+    """
+    The identity Pauli Term.
+    """
+    return PauliTerm("I", 0, 1)
+
+
+def ZERO():
+    """
+    The zero Pauli Term.
+    """
+    return PauliTerm("I", 0, 0)
 
 
 def sI(q):
@@ -375,7 +379,7 @@ class PauliSum(object):
                 all([isinstance(term, PauliTerm) for term in terms])):
             raise ValueError("PauliSum's are currently constructed from Sequences of PauliTerms.")
         if len(terms) == 0:
-            self.terms = [0.0 * ID]
+            self.terms = [0.0 * ID()]
         else:
             self.terms = terms
 
@@ -496,7 +500,7 @@ class PauliSum(object):
         if isinstance(other, PauliTerm):
             other = PauliSum([other])
         elif isinstance(other, Number):
-            other = PauliSum([other * ID])
+            other = PauliSum([other * ID()])
         new_terms = [term.copy() for term in self.terms]
         new_terms.extend(other.terms)
         new_sum = PauliSum(new_terms)


Test patch:
diff --git a/pyquil/tests/test_paulis.py b/pyquil/tests/test_paulis.py
index e762bc1..a14b064 100644
--- a/pyquil/tests/test_paulis.py
+++ b/pyquil/tests/test_paulis.py
@@ -83,13 +83,13 @@ def test_simplify_term_id_1():
 
 
 def test_simplify_term_id_2():
-    term = 0.5 * ID
+    term = 0.5 * ID()
     assert term.id() == ''
     assert term.coefficient == 0.5
 
 
 def test_simplify_term_id_3():
-    s = 0.25 + 0.25 * ID
+    s = 0.25 + 0.25 * ID()
     terms = s.terms
     assert len(terms) == 1
     assert terms[0].id() == ''
@@ -219,7 +219,7 @@ def test_pauli_sum():
 
 
 def test_ps_adds_pt_1():
-    term = ID
+    term = ID()
     b = term + term
     assert str(b) == "(2+0j)*I"
     assert str(b + term) == "(3+0j)*I"
@@ -227,7 +227,7 @@ def test_ps_adds_pt_1():
 
 
 def test_ps_adds_pt_2():
-    term = ID
+    term = ID()
     b = term + 1.0
     assert str(b) == "(2+0j)*I"
     assert str(b + 1.0) == "(3+0j)*I"
@@ -244,7 +244,7 @@ def test_pauliterm_sub():
 
 
 def test_ps_sub():
-    term = 3 * ID
+    term = 3 * ID()
     b = term - 1.0
     assert str(b) == "(2+0j)*I"
     assert str(b - 1.0) == "(1+0j)*I"
@@ -555,12 +555,12 @@ def test_zero_term():
     qubit_id = 0
     coefficient = 10
     ps = sI(qubit_id) + sX(qubit_id)
-    assert coefficient * ZERO == ZERO
-    assert ZERO * coefficient == ZERO
-    assert ZERO * ID == ZERO
-    assert ZERO + ID == ID
-    assert ZERO + ps == ps
-    assert ps + ZERO == ps
+    assert coefficient * ZERO() == ZERO()
+    assert ZERO() * coefficient == ZERO()
+    assert ZERO() * ID() == ZERO()
+    assert ZERO() + ID() == ID()
+    assert ZERO() + ps == ps
+    assert ps + ZERO() == ps
 
 
 def test_from_list():