Repository: PennyLaneAI/pennylane
Pull request #7855 (2025-07-11 17:12:59)

chore: deprecate `QNode.add_transform`
**Context:**

No need for this method as we can just do,
```python
QNode.transform_program.push_back(transform_container=transform_container)
```

**Description of the Change:**

Standard deprecation - added deprecation warning to the docstring documentation,

<img width="841" height="350" alt="image" src="https://github.com/user-attachments/assets/e2ef7a53-66c7-4167-be63-7911634499e2" />


**Benefits:** Better code.

[sc-93020]


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/PennyLaneAI/pennylane/pull/7855?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.68%. Comparing base [(`336a017`)](https://app.codecov.io/gh/PennyLaneAI/pennylane/commit/336a0175afa2fee4a8f7f38c1d4762cce9b5f9eb?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) to head [(`9e6b9f4`)](https://app.codecov.io/gh/PennyLaneAI/pennylane/commit/9e6b9f4aaabdcc77761229c9a203a32fc4591dbe?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI).
> Report is 1 commits behind head on master.

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


```diff
@@           Coverage Diff           @@
##           master    #7855   +/-   ##
=======================================
  Coverage   99.68%   99.68%           
=======================================
  Files         543      543           
  Lines       55314    55315    +1     
=======================================
+ Hits        55140    55141    +1     
  Misses        174      174           
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/PennyLaneAI/pennylane/pull/7855?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 ca4fa0325..e6374a534 100644
--- a/doc/development/deprecations.rst
+++ b/doc/development/deprecations.rst
@@ -9,6 +9,12 @@ deprecations are listed below.
 Pending deprecations
 --------------------
 
+* The ``qml.QNode.add_transform`` method is deprecated and will be removed in v0.43.
+  Instead, please use ``QNode.transform_program.push_back(transform_container=transform_container)``.
+
+  - Deprecated in v0.43
+  - Will be removed in v0.44
+
 * ``qml.operation.Observable`` and the accompanying ``Observable.compare`` methods are deprecated. At this point, ``Observable`` only
   provides a default value of ``is_hermitian=True`` and prevents the object from being processed into a tape. Instead of inheriting from
   ``Observable``, operator developers should manually set ``is_hermitian = True`` and update the ``queue`` function to stop it from being
diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md
index ee22d7233..93e7aeb18 100644
--- a/doc/releases/changelog-dev.md
+++ b/doc/releases/changelog-dev.md
@@ -74,6 +74,10 @@
 
 <h3>Deprecations 👋</h3>
 
+* The `qml.QNode.add_transform` method is deprecated and will be removed in v0.43.
+  Instead, please use `QNode.transform_program.push_back(transform_container=transform_container)`.
+  [(#7855)](https://github.com/PennyLaneAI/pennylane/pull/7855)
+
 <h3>Internal changes ⚙️</h3>
 
 * Added a `dialects` submodule to `qml.compiler.python_compiler` which now houses all the xDSL dialects we create.
diff --git a/pennylane/transforms/add_noise.py b/pennylane/transforms/add_noise.py
index 9b82b9db6..9578c957f 100644
--- a/pennylane/transforms/add_noise.py
+++ b/pennylane/transforms/add_noise.py
@@ -269,7 +269,7 @@ def custom_qnode_wrapper(self, qnode, targs, tkwargs):
     transform_program = qml.workflow.get_transform_program(qnode, level=level)
 
     cqnode._transform_program = transform_program
-    cqnode.add_transform(
+    cqnode.transform_program.push_back(
         TransformContainer(
             self._transform,
             targs,
diff --git a/pennylane/transforms/core/transform_dispatcher.py b/pennylane/transforms/core/transform_dispatcher.py
index e6d843213..4ea43653e 100644
--- a/pennylane/transforms/core/transform_dispatcher.py
+++ b/pennylane/transforms/core/transform_dispatcher.py
@@ -367,7 +367,7 @@ class TransformDispatcher:  # pylint: disable=too-many-instance-attributes
         qnode = copy(qnode)
 
         if self.expand_transform:
-            qnode.add_transform(
+            qnode.transform_program.push_back(
                 TransformContainer(
                     self._expand_transform,
                     args=targs,
@@ -375,7 +375,7 @@ class TransformDispatcher:  # pylint: disable=too-many-instance-attributes
                     use_argnum=self._use_argnum_in_expand,
                 )
             )
-        qnode.add_transform(
+        qnode.transform_program.push_back(
             TransformContainer(
                 self._transform,
                 args=targs,
diff --git a/pennylane/workflow/qnode.py b/pennylane/workflow/qnode.py
index 546ea1af2..aa5e9bc88 100644
--- a/pennylane/workflow/qnode.py
+++ b/pennylane/workflow/qnode.py
@@ -654,8 +654,18 @@ class QNode:
     def add_transform(self, transform_container: TransformContainer):
         """Add a transform (container) to the transform program.
 
+        .. warning::
+
+            This method is deprecated and will be removed in v0.43. Instead, please use :meth:`~.TransformProgram.push_back` on
+            the ``QNode.transform_program`` property to add transforms to the transform program.
+
         .. warning:: This is a developer facing feature and is called when a transform is applied on a QNode.
         """
+        warnings.warn(
+            "The `qml.QNode.add_transform` method is deprecated and will be removed in v0.43. "
+            "Instead, please use `QNode.transform_program.push_back(transform_container=transform_container)`.",
+            PennyLaneDeprecationWarning,
+        )
         self._transform_program.push_back(transform_container=transform_container)
 
     def update(self, **kwargs) -> QNode:


Test patch:
diff --git a/tests/test_qnode.py b/tests/test_qnode.py
index 682454d80..13237b779 100644
--- a/tests/test_qnode.py
+++ b/tests/test_qnode.py
@@ -34,6 +34,25 @@ from pennylane.workflow.qnode import _make_execution_config
 from pennylane.workflow.set_shots import set_shots
 
 
+def test_add_transform_deprecation():
+    """Test that the add_transform method raises a deprecation warning."""
+
+    dev = qml.device("default.qubit", wires=2)
+
+    @qml.qnode(dev)
+    def circuit(x):
+        qml.RX(x, wires=0)
+        return qml.expval(qml.PauliZ(0))
+
+    with pytest.warns(
+        PennyLaneDeprecationWarning,
+        match="The `qml.QNode.add_transform` method is deprecated and will be removed in v0.43",
+    ):
+        circuit.add_transform(
+            qml.transforms.core.TransformContainer(qml.gradients.param_shift.expand_transform)
+        )
+
+
 def dummyfunc():
     """dummy func."""
     return None