Repository: PennyLaneAI/pennylane
Pull request #7313 (2025-04-21 13:45:04)

Deprecate `WiresEnum`, `AllWires`, and `AnyWires`
PR https://github.com/PennyLaneAI/pennylane/pull/7312 just does the num_wires = None part of this change and will allow us to update catalyst before merging this PR.

Context:

AllWires and AnyWires are overkill that don't really need to exist. Setting Operator.num_wires = None can sufficiently communicate "I can accept any number of wires". We haven't validated AllWires or done anything special about it for many releases. All these serve to do it tell the default Operator.__init__ to not validate how many wires the user passes in. We can do that with None.

All they really do is make the interface more complicated and cluttered.

Description of the Change:

Deprecate AllWires, AnyWires, and WiresEnum.

Benefits:

Cleaner Operator interface.

Possible Drawbacks:

Deprecations and removals always run the risk of breaking something for someone, but I think this a harmless enough change.

Related GitHub Issues:

[[sc-89159](https://app.shortcut.com/xanaduai/story/89159)]

JerryChen97: Also, we might need to drop their mentions in docstr as well
![image](https://github.com/user-attachments/assets/89583e6b-c295-4a9b-bdbe-bfef17601a17)

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/PennyLaneAI/pennylane/pull/7313?dropdown=coverage&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:
> Project coverage is 99.65%. Comparing base [(`c1d096b`)](https://app.codecov.io/gh/PennyLaneAI/pennylane/commit/c1d096b5fb3fb5d5b930e97daf3e151713f9041e?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) to head [(`c84371f`)](https://app.codecov.io/gh/PennyLaneAI/pennylane/commit/c84371f705418eb8bb9c3b4ab52e046f85cf8c7b?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI).

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


```diff
@@           Coverage Diff           @@
##           master    #7313   +/-   ##
=======================================
  Coverage   99.65%   99.65%           
=======================================
  Files         526      526           
  Lines       50221    50229    +8     
=======================================
+ Hits        50046    50054    +8     
  Misses        175      175           
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/PennyLaneAI/pennylane/pull/7313?dropdown=coverage&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).

<details><summary> :rocket: New features to boost your workflow: </summary>

- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
</details>

Patch:
diff --git a/doc/development/deprecations.rst b/doc/development/deprecations.rst
index c90838bf8..4bc2cbf3f 100644
--- a/doc/development/deprecations.rst
+++ b/doc/development/deprecations.rst
@@ -9,6 +9,13 @@ deprecations are listed below.
 Pending deprecations
 --------------------
 
+* ``qml.operation.WiresEnum``, ``qml.operation.AllWires``, and ``qml.operation.AnyWires`` are deprecated. If an operation can act
+  on any number of wires ``Operator.num_wires = None`` should be used instead. This is the default, and does not need
+  to be overridden unless the operator developer wants to validate that the correct number of wires is passed.
+
+  - Deprecated in v0.42
+  - Will be removed in v0.43
+
 * The :func:`qml.QNode.get_gradient_fn` method is now deprecated. Instead, use :func:`~.workflow.get_best_diff_method` to obtain the differentiation method.
 
   - Deprecated in v0.42
diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md
index e4db2378f..dbc859a75 100644
--- a/doc/releases/changelog-dev.md
+++ b/doc/releases/changelog-dev.md
@@ -201,6 +201,11 @@
 
 <h3>Deprecations 👋</h3>
 
+* `qml.operation.WiresEnum`, `qml.operation.AllWires`, and `qml.operation.AnyWires` are deprecated. To indicate that
+  an operator can act on any number of wires, `Operator.num_wires = None` should be used instead. This is the default
+  and does not need to be overwritten unless the operator developer wants to add wire number validation.
+  [(#7313)](https://github.com/PennyLaneAI/pennylane/pull/7313)
+
 * The :func:`qml.QNode.get_gradient_fn` method is now deprecated. Instead, use :func:`~.workflow.get_best_diff_method` to obtain the differentiation method.
   [(#7323)](https://github.com/PennyLaneAI/pennylane/pull/7323)
 
diff --git a/pennylane/operation.py b/pennylane/operation.py
index 7b9043a85..1449346d8 100644
--- a/pennylane/operation.py
+++ b/pennylane/operation.py
@@ -232,6 +232,7 @@ from scipy.sparse import spmatrix
 
 import pennylane as qml
 from pennylane.capture import ABCCaptureMeta, create_operator_primitive
+from pennylane.exceptions import PennyLaneDeprecationWarning
 from pennylane.math import expand_matrix
 from pennylane.queuing import QueuingManager
 from pennylane.typing import TensorLike
@@ -299,27 +300,38 @@ class ParameterFrequenciesUndefinedError(OperatorPropertyUndefined):
 # =============================================================================
 
 
-class WiresEnum(IntEnum):
+class _WiresEnum(IntEnum):
     """Integer enumeration class
     to represent the number of wires
     an operation acts on.
 
+    .. warning::
+
+        This class is deprecated ``Operator.num_wires=None`` should now be used to indicate
+        that an operator can exist on any number of wires.
+
     """
 
     AnyWires = -1
     """A enumeration that represents that an operator can act on any number of wires.
 
+    .. warning::
+
+        ``AnyWires`` is deprecated ``Operator.num_wires=None`` should now be used to indicate
+        that an operator can exist on any number of wires.
+
     """
 
     AllWires = -2
     """A enumeration that represents that an operator acts on all wires in the system.
 
+    .. warning::
 
-    """
+        ``AllWires`` is deprecated ``Operator.num_wires=None`` should now be used to indicate
+        that an operator can exist on any number of wires.
 
+    """
 
-AnyWires = WiresEnum.AnyWires
-AllWires = WiresEnum.AllWires
 
 # =============================================================================
 # Class property
@@ -971,7 +983,7 @@ class Operator(abc.ABC, metaclass=ABCCaptureMeta):
         """
         raise TermsUndefinedError
 
-    num_wires: Optional[Union[int, WiresEnum]] = None
+    num_wires: Optional[Union[int, _WiresEnum]] = None
     """Number of wires the operator acts on."""
 
     @property
@@ -1135,7 +1147,7 @@ class Operator(abc.ABC, metaclass=ABCCaptureMeta):
         self._wires: Wires = Wires(wires)
 
         # check that the number of wires given corresponds to required number
-        if (self.num_wires is not None and not isinstance(self.num_wires, WiresEnum)) and len(
+        if (self.num_wires is not None and not isinstance(self.num_wires, _WiresEnum)) and len(
             self._wires
         ) != self.num_wires:
             raise ValueError(
@@ -2475,6 +2487,27 @@ def gen_is_multi_term_hamiltonian(obj):
 
 def __getattr__(name):
     """To facilitate StatePrep rename"""
+    if name == "AnyWires":
+        warnings.warn(
+            "AnyWires is deprecated and will be removed in v0.43. "
+            " If your operation accepts any number of wires, set num_wires=None instead.",
+            PennyLaneDeprecationWarning,
+        )
+        return _WiresEnum.AllWires
+    if name == "AllWires":
+        warnings.warn(
+            "AllWires is deprecated and will be removed in v0.43. "
+            " If your operation accepts any number of wires, set num_wires=None instead.",
+            PennyLaneDeprecationWarning,
+        )
+        return _WiresEnum.AllWires
+    if name == "WiresEnum":
+        warnings.warn(
+            "WiresEnum is deprecated and will be removed in v0.43. "
+            " If your operation accepts any number of wires, set num_wires=None instead.",
+            PennyLaneDeprecationWarning,
+        )
+        return _WiresEnum
     if name == "StatePrep":
         return StatePrepBase
     raise AttributeError(f"module 'pennylane.operation' has no attribute '{name}'")
diff --git a/pennylane/templates/subroutines/select_pauli_rot.py b/pennylane/templates/subroutines/select_pauli_rot.py
index 1f7341625..11e769e69 100644
--- a/pennylane/templates/subroutines/select_pauli_rot.py
+++ b/pennylane/templates/subroutines/select_pauli_rot.py
@@ -16,7 +16,7 @@ Contains the SelectPauliRot template.
 """
 
 import pennylane as qml
-from pennylane.operation import AnyWires, Operation
+from pennylane.operation import Operation
 from pennylane.templates.state_preparations.mottonen import _apply_uniform_rotation_dagger
 
 
@@ -79,7 +79,6 @@ class SelectPauliRot(Operation):
          0.        +0.j 0.        +0.j 0.        +0.j 0.        +0.j]
     """
 
-    num_wires = AnyWires
     grad_method = None
     ndim_params = (1,)
 


Test patch:
diff --git a/tests/test_operation.py b/tests/test_operation.py
index 114379fe8..dc8ef6382 100644
--- a/tests/test_operation.py
+++ b/tests/test_operation.py
@@ -41,6 +41,19 @@ CNOT_broadcasted = np.tensordot([1.4], CNOT, axes=0)
 I_broadcasted = I[pnp.newaxis]
 
 
+def test_wires_enum_deprecation():
+    """Test that WiresEnum, AllWires, and AnyWires are deprecated."""
+
+    with pytest.warns(qml.PennyLaneDeprecationWarning, match="is deprecated"):
+        _ = qml.operation.WiresEnum
+
+    with pytest.warns(qml.PennyLaneDeprecationWarning, match="is deprecated"):
+        _ = qml.operation.AllWires
+
+    with pytest.warns(qml.PennyLaneDeprecationWarning, match="is deprecated"):
+        _ = qml.operation.AnyWires
+
+
 class TestOperatorConstruction:
     """Test custom operators' construction."""