Repository: PennyLaneAI/pennylane
Pull request #4915 (2023-12-04 20:30:00)

make the pauli_rep operator property public
**Context:**
The `pauli_rep` property is widely used, and should be made public

**Description of the Change:**
- Introduce the `pauli_rep` read-only property to the `Operator` class
- Change all (read) references to `op._pauli_rep` into `op.pauli_rep` (the public version)

**Benefits:**
We're committing to having `pauli_rep` be part of the public API, making it less scary to lean on while moving forward with other improvements (eg. combining all the hamiltonian expansion transforms)

**Possible Drawbacks:**
We might want to change things related to it again, and it would require more careful work because it's public. I'm not so worried about this because it has existed (and been used) for a while now.

**Related GitHub Issues:**
previously attempted in #4017 
[sc-37494]

github-actions[bot]: Hello. You may have forgotten to update the changelog!
Please edit [`doc/releases/changelog-dev.md`](/PennyLaneAI/pennylane/blob/master/doc/releases/changelog-dev.md) with:
* A one-to-two sentence description of the change. You may include a small working example for new features.
* A link back to this PR.
* Your name (or GitHub username) in the contributors section.
codecov[bot]: ## [Codecov](https://app.codecov.io/gh/PennyLaneAI/pennylane/pull/4915?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Comparison is base [(`73d2b28`)](https://app.codecov.io/gh/PennyLaneAI/pennylane/commit/73d2b2831d2e47a9ba4e5c962d754fbddc06da61?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) 99.66% compared to head [(`c9d11e0`)](https://app.codecov.io/gh/PennyLaneAI/pennylane/pull/4915?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) 99.64%.


<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master    #4915      +/-   ##
==========================================
- Coverage   99.66%   99.64%   -0.02%     
==========================================
  Files         387      387              
  Lines       35029    34767     -262     
==========================================
- Hits        34910    34645     -265     
- Misses        119      122       +3     
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/PennyLaneAI/pennylane/pull/4915?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI).

trbromley: Thanks @timmysilv, no concerns from my side!

Patch:
diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md
index 93028f61e..dbbdfac53 100644
--- a/doc/releases/changelog-dev.md
+++ b/doc/releases/changelog-dev.md
@@ -284,6 +284,10 @@
 *   `TRX`, `TRY`, and `TRZ` are now differentiable via backprop on `default.qutrit`
   [(#4790)](https://github.com/PennyLaneAI/pennylane/pull/4790)
 
+* Operators now define a `pauli_rep` property, an instance of `PauliSentence`, defaulting
+  to `None` if the operator has not defined it (or has no definition in the pauli basis).
+  [(#4915)](https://github.com/PennyLaneAI/pennylane/pull/4915)
+
 <h3>Breaking changes 💔</h3>
 
 * The transforms submodule `qml.transforms.qcut` becomes its own module `qml.qcut`.
diff --git a/pennylane/devices/qubit/adjoint_jacobian.py b/pennylane/devices/qubit/adjoint_jacobian.py
index 1b8fa68a6..7258c78a0 100644
--- a/pennylane/devices/qubit/adjoint_jacobian.py
+++ b/pennylane/devices/qubit/adjoint_jacobian.py
@@ -231,8 +231,8 @@ def adjoint_vjp(tape: QuantumTape, cotangents: Tuple[Number], state=None):
     if len(new_cotangents) == 0:
         return tuple(0.0 for _ in tape.trainable_params)
     obs = qml.dot(new_cotangents, new_observables)
-    if obs._pauli_rep is not None:
-        flat_bra = obs._pauli_rep.dot(ket.flatten(), wire_order=list(range(tape.num_wires)))
+    if obs.pauli_rep is not None:
+        flat_bra = obs.pauli_rep.dot(ket.flatten(), wire_order=list(range(tape.num_wires)))
         bra = flat_bra.reshape(ket.shape)
     else:
         bra = apply_operation(obs, ket)
diff --git a/pennylane/operation.py b/pennylane/operation.py
index eab7d266a..462d227cc 100644
--- a/pennylane/operation.py
+++ b/pennylane/operation.py
@@ -1222,6 +1222,11 @@ class Operator(abc.ABC):
         self._hyperparameters = {}
         return self._hyperparameters
 
+    @property
+    def pauli_rep(self):
+        """A :class:`~.PauliSentence` representation of the Operator, or ``None`` if it doesn't have one."""
+        return self._pauli_rep
+
     @property
     def is_hermitian(self):
         """This property determines if an operator is hermitian."""
@@ -1467,7 +1472,7 @@ class Operator(abc.ABC):
         """
         new_op = copy.copy(self)
         new_op._wires = Wires([wire_map.get(wire, wire) for wire in self.wires])
-        if (p_rep := new_op._pauli_rep) is not None:
+        if (p_rep := new_op.pauli_rep) is not None:
             new_op._pauli_rep = p_rep.map_wires(wire_map)
         return new_op
 
diff --git a/pennylane/ops/op_math/composite.py b/pennylane/ops/op_math/composite.py
index f319bda29..f38bc930a 100644
--- a/pennylane/ops/op_math/composite.py
+++ b/pennylane/ops/op_math/composite.py
@@ -352,7 +352,7 @@ class CompositeOp(Operator):
         for attr, value in vars(self).items():
             if attr not in {"data", "operands", "_wires"}:
                 setattr(new_op, attr, value)
-        if (p_rep := new_op._pauli_rep) is not None:
+        if (p_rep := new_op.pauli_rep) is not None:
             new_op._pauli_rep = p_rep.map_wires(wire_map)
 
         return new_op
diff --git a/pennylane/ops/op_math/pow.py b/pennylane/ops/op_math/pow.py
index 06e04ce07..089bb93fe 100644
--- a/pennylane/ops/op_math/pow.py
+++ b/pennylane/ops/op_math/pow.py
@@ -357,7 +357,7 @@ class Pow(ScalarSymbolicOp):
 
     def simplify(self) -> Union["Pow", Identity]:
         # try using pauli_rep:
-        if pr := self._pauli_rep:
+        if pr := self.pauli_rep:
             pr.simplify()
             return pr.operation(wire_order=self.wires)
 
diff --git a/pennylane/ops/op_math/prod.py b/pennylane/ops/op_math/prod.py
index bff36d606..50307501e 100644
--- a/pennylane/ops/op_math/prod.py
+++ b/pennylane/ops/op_math/prod.py
@@ -308,8 +308,8 @@ class Prod(CompositeOp):
         return math.expand_matrix(full_mat, self.wires, wire_order=wire_order)
 
     def sparse_matrix(self, wire_order=None):
-        if self._pauli_rep:  # Get the sparse matrix from the PauliSentence representation
-            return self._pauli_rep.to_mat(wire_order=wire_order or self.wires, format="csr")
+        if self.pauli_rep:  # Get the sparse matrix from the PauliSentence representation
+            return self.pauli_rep.to_mat(wire_order=wire_order or self.wires, format="csr")
 
         if self.has_overlapping_wires or self.num_wires > MAX_NUM_WIRES_KRON_PRODUCT:
             gen = ((op.sparse_matrix(), op.wires) for op in self)
@@ -353,11 +353,7 @@ class Prod(CompositeOp):
 
     def _build_pauli_rep(self):
         """PauliSentence representation of the Product of operations."""
-        if all(
-            operand_pauli_reps := [
-                op._pauli_rep for op in self.operands  # pylint: disable=protected-access
-            ]
-        ):
+        if all(operand_pauli_reps := [op.pauli_rep for op in self.operands]):
             return reduce(lambda a, b: a * b, operand_pauli_reps)
         return None
 
@@ -378,7 +374,7 @@ class Prod(CompositeOp):
 
     def simplify(self) -> Union["Prod", Sum]:
         # try using pauli_rep:
-        if pr := self._pauli_rep:
+        if pr := self.pauli_rep:
             pr.simplify()
             return pr.operation(wire_order=self.wires)
 
diff --git a/pennylane/ops/op_math/sprod.py b/pennylane/ops/op_math/sprod.py
index a9feeb45d..9c39245c5 100644
--- a/pennylane/ops/op_math/sprod.py
+++ b/pennylane/ops/op_math/sprod.py
@@ -244,8 +244,8 @@ class SProd(ScalarSymbolicOp):
         Returns:
             :class:`scipy.sparse._csr.csr_matrix`: sparse matrix representation
         """
-        if self._pauli_rep:  # Get the sparse matrix from the PauliSentence representation
-            return self._pauli_rep.to_mat(wire_order=wire_order or self.wires, format="csr")
+        if self.pauli_rep:  # Get the sparse matrix from the PauliSentence representation
+            return self.pauli_rep.to_mat(wire_order=wire_order or self.wires, format="csr")
         mat = self.base.sparse_matrix(wire_order=wire_order).multiply(self.scalar)
         mat.eliminate_zeros()
         return mat
@@ -293,7 +293,7 @@ class SProd(ScalarSymbolicOp):
             .Operator: simplified operator
         """
         # try using pauli_rep:
-        if pr := self._pauli_rep:
+        if pr := self.pauli_rep:
             pr.simplify()
             return pr.operation(wire_order=self.wires)
 
diff --git a/pennylane/ops/op_math/sum.py b/pennylane/ops/op_math/sum.py
index b0c52f7ba..7816d08e8 100644
--- a/pennylane/ops/op_math/sum.py
+++ b/pennylane/ops/op_math/sum.py
@@ -168,8 +168,8 @@ class Sum(CompositeOp):
     @property
     def is_hermitian(self):
         """If all of the terms in the sum are hermitian, then the Sum is hermitian."""
-        if self._pauli_rep is not None:
-            coeffs_list = list(self._pauli_rep.values())
+        if self.pauli_rep is not None:
+            coeffs_list = list(self.pauli_rep.values())
             if not math.is_abstract(coeffs_list[0]):
                 return not any(math.iscomplex(c) for c in coeffs_list)
 
@@ -221,8 +221,8 @@ class Sum(CompositeOp):
         return math.expand_matrix(reduced_mat, sum_wires, wire_order=wire_order)
 
     def sparse_matrix(self, wire_order=None):
-        if self._pauli_rep:  # Get the sparse matrix from the PauliSentence representation
-            return self._pauli_rep.to_mat(wire_order=wire_order or self.wires, format="csr")
+        if self.pauli_rep:  # Get the sparse matrix from the PauliSentence representation
+            return self.pauli_rep.to_mat(wire_order=wire_order or self.wires, format="csr")
 
         gen = ((op.sparse_matrix(), op.wires) for op in self)
 
@@ -252,11 +252,7 @@ class Sum(CompositeOp):
 
     def _build_pauli_rep(self):
         """PauliSentence representation of the Sum of operations."""
-        if all(
-            operand_pauli_reps := [
-                op._pauli_rep for op in self.operands  # pylint: disable=protected-access
-            ]
-        ):
+        if all(operand_pauli_reps := [op.pauli_rep for op in self.operands]):
             new_rep = qml.pauli.PauliSentence()
             for operand_rep in operand_pauli_reps:
                 for pw, coeff in operand_rep.items():
@@ -295,7 +291,7 @@ class Sum(CompositeOp):
 
     def simplify(self, cutoff=1.0e-12) -> "Sum":  # pylint: disable=arguments-differ
         # try using pauli_rep:
-        if pr := self._pauli_rep:
+        if pr := self.pauli_rep:
             pr.simplify()
             return pr.operation(wire_order=self.wires)
 
diff --git a/pennylane/ops/op_math/symbolicop.py b/pennylane/ops/op_math/symbolicop.py
index 916bbc8a4..34a137af2 100644
--- a/pennylane/ops/op_math/symbolicop.py
+++ b/pennylane/ops/op_math/symbolicop.py
@@ -139,11 +139,10 @@ class SymbolicOp(Operator):
         )
 
     def map_wires(self, wire_map: dict):
-        # pylint:disable=protected-access
         new_op = copy(self)
         new_op.hyperparameters["base"] = self.base.map_wires(wire_map=wire_map)
-        if (p_rep := new_op._pauli_rep) is not None:
-            new_op._pauli_rep = p_rep.map_wires(wire_map)
+        if (p_rep := new_op.pauli_rep) is not None:
+            new_op._pauli_rep = p_rep.map_wires(wire_map)  # pylint:disable=protected-access
         return new_op
 
 
diff --git a/pennylane/pauli/conversion.py b/pennylane/pauli/conversion.py
index 56f5db463..9944deb07 100644
--- a/pennylane/pauli/conversion.py
+++ b/pennylane/pauli/conversion.py
@@ -340,7 +340,7 @@ def pauli_sentence(op):
     Returns:
         .PauliSentence: the PauliSentence representation of an arithmetic operator or Hamiltonian
     """
-    if (ps := op._pauli_rep) is not None:  # pylint: disable=protected-access
+    if (ps := op.pauli_rep) is not None:
         return ps
 
     return _pauli_sentence(op)
@@ -348,7 +348,7 @@ def pauli_sentence(op):
 
 def is_pauli_sentence(op):
     """Returns True of the operator is a PauliSentence and False otherwise."""
-    if op._pauli_rep is not None:  # pylint: disable=protected-access
+    if op.pauli_rep is not None:
         return True
     if isinstance(op, Hamiltonian):
         return all(is_pauli_word(o) for o in op.ops)
diff --git a/pennylane/pauli/pauli_interface.py b/pennylane/pauli/pauli_interface.py
index 19574753f..4a5f37fbd 100644
--- a/pennylane/pauli/pauli_interface.py
+++ b/pennylane/pauli/pauli_interface.py
@@ -82,7 +82,7 @@ def _pw_prefactor_ham(observable: Hamiltonian):
 @_pauli_word_prefactor.register(Prod)
 @_pauli_word_prefactor.register(SProd)
 def _pw_prefactor_prod_sprod(observable: Union[Prod, SProd]):
-    ps = observable._pauli_rep  # pylint:disable=protected-access
+    ps = observable.pauli_rep
     if ps is not None and len(ps) == 1:
         return list(ps.values())[0]
 
diff --git a/pennylane/qchem/convert.py b/pennylane/qchem/convert.py
index 2648aaebc..e1a8d00aa 100644
--- a/pennylane/qchem/convert.py
+++ b/pennylane/qchem/convert.py
@@ -17,7 +17,7 @@ This module contains the functions for converting an external operator to a Penn
 import warnings
 from itertools import product
 
-# pylint: disable= import-outside-toplevel
+# pylint: disable= import-outside-toplevel,no-member
 import pennylane as qml
 from pennylane import numpy as np
 from pennylane.operation import Tensor, active_new_opmath
@@ -259,7 +259,7 @@ def _pennylane_to_openfermion(coeffs, ops, wires=None):
                     f"but got {op}."
                 ) from e
 
-        elif (ps := op._pauli_rep) is None:  # pylint: disable=protected-access
+        elif (ps := op.pauli_rep) is None:
             raise ValueError(
                 f"Expected a Pennylane operator with a valid Pauli word representation, but got {op}."
             )


Test patch:
diff --git a/tests/devices/default_qubit/test_default_qubit.py b/tests/devices/default_qubit/test_default_qubit.py
index 2722b5b9e..6d4f2cfe9 100644
--- a/tests/devices/default_qubit/test_default_qubit.py
+++ b/tests/devices/default_qubit/test_default_qubit.py
@@ -798,7 +798,7 @@ class TestSumOfTermsDifferentiability:
         t2 = 6.2 * qml.prod(*(qml.PauliY(i) for i in range(n_wires)))
         H = t1 + t2
         if style == "hamiltonian":
-            H = H._pauli_rep.hamiltonian()  # pylint: disable=protected-access
+            H = H.pauli_rep.hamiltonian()
         elif style == "hermitian":
             H = qml.Hermitian(H.matrix(), wires=H.wires)
         qs = qml.tape.QuantumScript(ops, [qml.expval(H)])
@@ -813,7 +813,7 @@ class TestSumOfTermsDifferentiability:
         t2 = 6.2 * qml.prod(*(qml.PauliY(i) for i in range(n_wires)))
         H = t1 + t2
         if style == "hamiltonian":
-            H = H._pauli_rep.hamiltonian()  # pylint: disable=protected-access
+            H = H.pauli_rep.hamiltonian()
         elif style == "hermitian":
             H = qml.Hermitian(H.matrix(), wires=H.wires)
         qs = qml.tape.QuantumScript(ops, [qml.expval(H)])
diff --git a/tests/ops/op_math/test_composite.py b/tests/ops/op_math/test_composite.py
index f974ef3dc..7ffd93e5d 100644
--- a/tests/ops/op_math/test_composite.py
+++ b/tests/ops/op_math/test_composite.py
@@ -200,8 +200,8 @@ class TestConstruction:
         assert mapped_op.wires == Wires([5, 7])
         assert mapped_op[0].wires == Wires(5)
         assert mapped_op[1].wires == Wires(7)
-        assert mapped_op._pauli_rep is not diag_op._pauli_rep
-        assert mapped_op._pauli_rep == qml.pauli.PauliSentence(
+        assert mapped_op.pauli_rep is not diag_op.pauli_rep
+        assert mapped_op.pauli_rep == qml.pauli.PauliSentence(
             {qml.pauli.PauliWord({5: "X", 7: "Y"}): 1}
         )
 
diff --git a/tests/ops/op_math/test_pow_op.py b/tests/ops/op_math/test_pow_op.py
index 828f453b7..415b283b8 100644
--- a/tests/ops/op_math/test_pow_op.py
+++ b/tests/ops/op_math/test_pow_op.py
@@ -390,7 +390,7 @@ class TestProperties:
     def test_pauli_rep(self, base, exp, rep, power_method):
         """Test the pauli rep is produced as expected."""
         op = power_method(base, exp)
-        assert op._pauli_rep == rep  # pylint: disable=protected-access
+        assert op.pauli_rep == rep
 
     def test_pauli_rep_is_none_for_bad_exponents(self, power_method):
         """Test that the _pauli_rep is None if the exponent is not positive or non integer."""
@@ -399,13 +399,13 @@ class TestProperties:
 
         for exponent in exponents:
             op = power_method(base, z=exponent)
-            assert op._pauli_rep is None  # pylint: disable=protected-access
+            assert op.pauli_rep is None
 
     def test_pauli_rep_none_if_base_pauli_rep_none(self, power_method):
         """Test that None is produced if the base op does not have a pauli rep"""
         base = qml.RX(1.23, wires=0)
         op = power_method(base, z=2)
-        assert op._pauli_rep is None  # pylint: disable=protected-access
+        assert op.pauli_rep is None
 
 
 class TestSimplify:
diff --git a/tests/ops/op_math/test_prod.py b/tests/ops/op_math/test_prod.py
index 074ec74fc..31bf1242c 100644
--- a/tests/ops/op_math/test_prod.py
+++ b/tests/ops/op_math/test_prod.py
@@ -894,12 +894,12 @@ class TestProperties:
     @pytest.mark.parametrize("op, rep", op_pauli_reps)
     def test_pauli_rep(self, op, rep):
         """Test that the pauli rep gives the expected result."""
-        assert op._pauli_rep == rep
+        assert op.pauli_rep == rep
 
     def test_pauli_rep_none(self):
         """Test that None is produced if any of the terms don't have a _pauli_rep property."""
         op = qml.prod(qml.PauliX(wires=0), qml.RX(1.23, wires=1))
-        assert op._pauli_rep is None
+        assert op.pauli_rep is None
 
     op_pauli_reps_nested = (
         (
@@ -926,7 +926,7 @@ class TestProperties:
     @pytest.mark.parametrize("op, rep", op_pauli_reps_nested)
     def test_pauli_rep_nested(self, op, rep):
         """Test that the pauli rep gives the expected result."""
-        assert op._pauli_rep == rep
+        assert op.pauli_rep == rep
 
 
 class TestSimplify:
diff --git a/tests/ops/op_math/test_sprod.py b/tests/ops/op_math/test_sprod.py
index bc219a491..8ea66dfc6 100644
--- a/tests/ops/op_math/test_sprod.py
+++ b/tests/ops/op_math/test_sprod.py
@@ -742,13 +742,13 @@ class TestProperties:
     @pytest.mark.parametrize("op, rep", op_pauli_reps)
     def test_pauli_rep(self, op, rep):
         """Test the pauli rep is produced as expected."""
-        assert op._pauli_rep == rep  # pylint: disable=protected-access
+        assert op.pauli_rep == rep
 
     def test_pauli_rep_none_if_base_pauli_rep_none(self):
         """Test that None is produced if the base op does not have a pauli rep"""
         base = qml.RX(1.23, wires=0)
         op = qml.s_prod(2, base)
-        assert op._pauli_rep is None  # pylint: disable=protected-access
+        assert op.pauli_rep is None
 
     def test_batching_properties(self):
         """Test the batching properties and methods."""
diff --git a/tests/ops/op_math/test_sum.py b/tests/ops/op_math/test_sum.py
index e869f49dc..850c72df0 100644
--- a/tests/ops/op_math/test_sum.py
+++ b/tests/ops/op_math/test_sum.py
@@ -546,12 +546,12 @@ class TestProperties:
     @pytest.mark.parametrize("op, rep", op_pauli_reps)
     def test_pauli_rep(self, op, rep):
         """Test that the pauli rep gives the expected result."""
-        assert op._pauli_rep == rep  # pylint: disable=protected-access
+        assert op.pauli_rep == rep
 
     def test_pauli_rep_none(self):
         """Test that None is produced if any of the summands don't have a _pauli_rep."""
         op = qml.sum(qml.PauliX(wires=0), qml.RX(1.23, wires=1))
-        assert op._pauli_rep is None  # pylint: disable=protected-access
+        assert op.pauli_rep is None
 
     op_pauli_reps_nested = (
         (
@@ -646,7 +646,7 @@ class TestProperties:
     @pytest.mark.parametrize("op, rep", op_pauli_reps_nested)
     def test_pauli_rep_nested(self, op, rep):
         """Test that the pauli rep gives the expected result."""
-        assert op._pauli_rep == rep  # pylint: disable=protected-access
+        assert op.pauli_rep == rep
 
 
 class TestSimplify:
diff --git a/tests/ops/op_math/test_symbolic_op.py b/tests/ops/op_math/test_symbolic_op.py
index dc86a30a2..3608c1596 100644
--- a/tests/ops/op_math/test_symbolic_op.py
+++ b/tests/ops/op_math/test_symbolic_op.py
@@ -84,8 +84,8 @@ def test_map_wires():
     assert op.base.wires == Wires("a")
     assert mapped_op.wires == Wires(5)
     assert mapped_op.base.wires == Wires(5)
-    assert mapped_op._pauli_rep is not op._pauli_rep
-    assert mapped_op._pauli_rep == qml.pauli.PauliSentence({qml.pauli.PauliWord({5: "X"}): 1})
+    assert mapped_op.pauli_rep is not op.pauli_rep
+    assert mapped_op.pauli_rep == qml.pauli.PauliSentence({qml.pauli.PauliWord({5: "X"}): 1})
 
 
 class TestProperties:
@@ -189,7 +189,7 @@ class TestProperties:
         """Test that pauli_rep is None by default"""
         base = Operator("a")
         op = SymbolicOp(base)
-        assert op._pauli_rep is None  # pylint:disable=protected-access
+        assert op.pauli_rep is None
 
 
 class TestQueuing:
diff --git a/tests/ops/qubit/test_non_parametric_ops.py b/tests/ops/qubit/test_non_parametric_ops.py
index 55786fcae..775de28f4 100644
--- a/tests/ops/qubit/test_non_parametric_ops.py
+++ b/tests/ops/qubit/test_non_parametric_ops.py
@@ -1240,4 +1240,4 @@ op_pauli_rep = (
 @pytest.mark.parametrize("op, rep", op_pauli_rep)
 def test_pauli_rep(op, rep):
     # pylint: disable=protected-access
-    assert op._pauli_rep == rep
+    assert op.pauli_rep == rep
diff --git a/tests/pauli/test_conversion.py b/tests/pauli/test_conversion.py
index ca6bf3ee8..435ff74b7 100644
--- a/tests/pauli/test_conversion.py
+++ b/tests/pauli/test_conversion.py
@@ -510,7 +510,7 @@ class TestPauliSentence:
     @pytest.mark.parametrize("op, ps", operator_ps)
     def test_operator_private_ps(self, op, ps):
         """Test that a correct pauli sentence is computed when passing an arithmetic operator and not
-        relying on the saved op._pauli_rep attribute."""
+        relying on the saved op.pauli_rep attribute."""
         assert qml.pauli.conversion._pauli_sentence(op) == ps  # pylint: disable=protected-access
 
     error_ps = (
diff --git a/tests/test_operation.py b/tests/test_operation.py
index 038ae960b..bf4c7561e 100644
--- a/tests/test_operation.py
+++ b/tests/test_operation.py
@@ -204,7 +204,7 @@ class TestOperatorConstruction:
             num_wires = 1
 
         op = DummyOp(wires=0)
-        assert op._pauli_rep is None
+        assert op.pauli_rep is None
 
     def test_list_or_tuple_params_casted_into_numpy_array(self):
         """Test that list parameters are casted into numpy arrays."""
@@ -691,8 +691,8 @@ class TestModificationMethods:
         assert op is not mapped_op
         assert op.wires == Wires([0, 1, 2])
         assert mapped_op.wires == Wires([10, 11, 12])
-        assert mapped_op._pauli_rep is not op._pauli_rep
-        assert mapped_op._pauli_rep == qml.pauli.PauliSentence(
+        assert mapped_op.pauli_rep is not op.pauli_rep
+        assert mapped_op.pauli_rep == qml.pauli.PauliSentence(
             {
                 qml.pauli.PauliWord({10: "X", 11: "Y", 12: "Z"}): 1.1,
                 qml.pauli.PauliWord({10: "Z", 11: "X", 12: "Y"}): 2.2,
@@ -1453,7 +1453,7 @@ class TestTensor:
         X = qml.PauliX(0)
         Y = qml.PauliY(2)
         t = Tensor(X, Y)
-        assert t._pauli_rep is None
+        assert t.pauli_rep is None
 
     def test_has_matrix(self):
         """Test that the Tensor class has a ``has_matrix`` static attribute set to True."""