Repository: PennyLaneAI/pennylane
Pull request #3461 (2022-12-02 16:48:52)

Exp init error if base is not an operator
**Context:**
Running `op=exp(2, base_op)` (coefficient and base_op argument order backwards) creates an Exp where the base operator is a number and the coefficient is an operator, without raising an error. Subsequently calling methods on the created operator either raise errors that are difficult to understand, or return meaningless results.

**Description of the Change:**
Raise a TypeError on initialization if a `base` is passed to `Exp` and the base is not an `Operator`.

**Benefits:**
Given how exponentials are written, trying to put arguments in the order coefficient, operator is an easy mistake to make. Raising an error at initialization avoids confusing error tracebacks or, in certain cases, returning results in the correct format that do not answer the intended question.




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://codecov.io/gh/PennyLaneAI/pennylane/pull/3461?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) Report
> Merging [#3461](https://codecov.io/gh/PennyLaneAI/pennylane/pull/3461?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) (f7afa34) into [master](https://codecov.io/gh/PennyLaneAI/pennylane/commit/79738a10001bff2f205ef36379bc99368edb748d?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) (79738a1) will **decrease** coverage by `0.01%`.
> The diff coverage is `100.00%`.

```diff
@@            Coverage Diff             @@
##           master    #3461      +/-   ##
==========================================
- Coverage   99.70%   99.68%   -0.02%     
==========================================
  Files         299      307       +8     
  Lines       26637    26981     +344     
==========================================
+ Hits        26558    26896     +338     
- Misses         79       85       +6     
```


| [Impacted Files](https://codecov.io/gh/PennyLaneAI/pennylane/pull/3461?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) | Coverage Δ | |
|---|---|---|
| [pennylane/ops/op\_math/exp.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/3461/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL29wcy9vcF9tYXRoL2V4cC5weQ==) | `100.00% <100.00%> (ø)` | |
| [pennylane/transforms/qfunc\_transforms.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/3461/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3RyYW5zZm9ybXMvcWZ1bmNfdHJhbnNmb3Jtcy5weQ==) | `92.85% <0.00%> (-7.15%)` | :arrow_down: |
| [pennylane/queuing.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/3461/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3F1ZXVpbmcucHk=) | `98.85% <0.00%> (-1.15%)` | :arrow_down: |
| [pennylane/tape/tape.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/3461/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3RhcGUvdGFwZS5weQ==) | `97.45% <0.00%> (ø)` | |
| [pennylane/pauli/utils.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/3461/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3BhdWxpL3V0aWxzLnB5) | `100.00% <0.00%> (ø)` | |
| [pennylane/tape/qscript.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/3461/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3RhcGUvcXNjcmlwdC5weQ==) | `100.00% <0.00%> (ø)` | |
| [pennylane/pauli/\_\_init\_\_.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/3461/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3BhdWxpL19faW5pdF9fLnB5) | `100.00% <0.00%> (ø)` | |
| [pennylane/measurements/var.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/3461/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL21lYXN1cmVtZW50cy92YXIucHk=) | `100.00% <0.00%> (ø)` | |
| [pennylane/qinfo/transforms.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/3461/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3FpbmZvL3RyYW5zZm9ybXMucHk=) | `100.00% <0.00%> (ø)` | |
| ... and [40 more](https://codecov.io/gh/PennyLaneAI/pennylane/pull/3461/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) | |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI)

lillian542: [sc-29465]

Patch:
diff --git a/pennylane/ops/op_math/exp.py b/pennylane/ops/op_math/exp.py
index b277f13c7..31fae3216 100644
--- a/pennylane/ops/op_math/exp.py
+++ b/pennylane/ops/op_math/exp.py
@@ -176,6 +176,8 @@ class Exp(ScalarSymbolicOp, Operation):
 
     # pylint: disable=too-many-arguments
     def __init__(self, base, coeff=1, num_steps=None, id=None):
+        if not isinstance(base, Operator):
+            raise TypeError(f"base is expected to be of type Operator, but received {type(base)}")
         super().__init__(base, scalar=coeff, id=id)
         self.grad_recipe = [None]
         self.num_steps = num_steps


Test patch:
diff --git a/tests/ops/op_math/test_exp.py b/tests/ops/op_math/test_exp.py
index dcb1128ff..0eb7579d1 100644
--- a/tests/ops/op_math/test_exp.py
+++ b/tests/ops/op_math/test_exp.py
@@ -99,6 +99,12 @@ class TestInitialization:
         op = constructor(DummyOp(1), 2.312)
         assert op.has_diagonalizing_gates is value
 
+    def test_base_is_not_operator_error(self, constructor):
+        """Test that Exp raises an error if a base is provided that is not an Operator"""
+
+        with pytest.raises(TypeError, match="base is expected to be of type Operator"):
+            constructor(2, qml.PauliX(0))
+
 
 class TestProperties:
     """Test of the properties of the Exp class."""