From d90d5399f14bc28bde7c184a57264e57fb905578 Mon Sep 17 00:00:00 2001
From: Andrija Paurevic <46359773+andrijapau@users.noreply.github.com>
Date: Wed, 15 Jan 2025 17:21:26 -0500
Subject: [PATCH] Remove `qtape`/`tape` property from `QNode` (#6825)
Completing the deprecation cycle.
No idea why those tests didn't complain in CI before when it was first
deprecated ... weird!
[sc-82149]
---
doc/development/deprecations.rst | 12 +++---
doc/releases/changelog-dev.md | 5 +++
pennylane/workflow/qnode.py | 21 +---------
tests/devices/test_default_clifford.py | 4 +-
tests/ops/functions/test_map_wires.py | 4 +-
tests/test_qnode.py | 56 --------------------------
tests/test_qnode_legacy.py | 15 -------
7 files changed, 16 insertions(+), 101 deletions(-)
diff --git a/doc/development/deprecations.rst b/doc/development/deprecations.rst
index 76d278d0b40..44cfc9150c7 100644
--- a/doc/development/deprecations.rst
+++ b/doc/development/deprecations.rst
@@ -9,12 +9,6 @@ deprecations are listed below.
Pending deprecations
--------------------
-* The ``tape`` and ``qtape`` properties of ``QNode`` have been deprecated.
- Instead, use the ``qml.workflow.construct_tape`` function.
-
- - Deprecated in v0.40
- - Will be removed in v0.41
-
* The ``max_expansion`` argument in :func:`~pennylane.devices.preprocess.decompose` is deprecated.
- Deprecated in v0.40
@@ -68,6 +62,12 @@ for details on how to port your legacy code to the new system. The following fun
Completed deprecation cycles
----------------------------
+* The ``tape`` and ``qtape`` properties of ``QNode`` have been removed.
+ Instead, use the ``qml.workflow.construct_tape`` function.
+
+ - Deprecated in v0.40
+ - Removed in v0.41
+
* The ``gradient_fn`` keyword argument to ``qml.execute`` has been removed. Instead, it has been replaced with ``diff_method``.
- Deprecated in v0.40
diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md
index 878599ca4ca..4399efce503 100644
--- a/doc/releases/changelog-dev.md
+++ b/doc/releases/changelog-dev.md
@@ -17,6 +17,10 @@
Breaking changes 💔
+* The ``tape`` and ``qtape`` properties of ``QNode`` have been removed.
+ Instead, use the ``qml.workflow.construct_tape`` function.
+ [(#6825)](https://github.com/PennyLaneAI/pennylane/pull/6825)
+
* The ``gradient_fn`` keyword argument to ``qml.execute`` has been removed. Instead, it has been replaced with ``diff_method``.
[(#6830)](https://github.com/PennyLaneAI/pennylane/pull/6830)
@@ -46,3 +50,4 @@ This release contains contributions from (in alphabetical order):
Yushao Chen,
Diksha Dhawan,
Christina Lee,
+Andrija Paurevic
diff --git a/pennylane/workflow/qnode.py b/pennylane/workflow/qnode.py
index 9d83024834a..93a9d40874d 100644
--- a/pennylane/workflow/qnode.py
+++ b/pennylane/workflow/qnode.py
@@ -29,7 +29,7 @@
from pennylane.logging import debug_logger
from pennylane.math import Interface, SupportedInterfaceUserInput, get_canonical_interface_name
from pennylane.measurements import MidMeasureMP
-from pennylane.tape import QuantumScript, QuantumTape
+from pennylane.tape import QuantumScript
from pennylane.transforms.core import TransformContainer, TransformDispatcher, TransformProgram
from ._capture_qnode import capture_qnode
@@ -695,25 +695,6 @@ def get_gradient_fn(
f"options are {tuple(get_args(SupportedDiffMethods))}."
)
- @property
- def tape(self) -> QuantumTape:
- """The quantum tape
-
- .. warning::
-
- This property is deprecated in v0.40 and will be removed in v0.41.
- Instead, use the :func:`qml.workflow.construct_tape <.workflow.construct_tape>` function.
- """
-
- warnings.warn(
- "The tape/qtape property is deprecated and will be removed in v0.41. "
- "Instead, use the qml.workflow.construct_tape function.",
- qml.PennyLaneDeprecationWarning,
- )
- return self._tape
-
- qtape = tape # for backwards compatibility
-
@debug_logger
def construct(self, args, kwargs) -> qml.tape.QuantumScript:
"""Call the quantum function with a tape context, ensuring the operations get queued."""
diff --git a/tests/devices/test_default_clifford.py b/tests/devices/test_default_clifford.py
index ad420ee8120..9a26846a261 100644
--- a/tests/devices/test_default_clifford.py
+++ b/tests/devices/test_default_clifford.py
@@ -599,9 +599,9 @@ def circuit_fn():
return qml.expval(qml.PauliZ(0))
qnode_clfrd = qml.QNode(circuit_fn, dev_c)
- qnode_clfrd()
+ tape = qml.workflow.construct_tape(qnode_clfrd)()
- conf_c, tape_c = dev_c.setup_execution_config(), qnode_clfrd.tape
+ conf_c, tape_c = dev_c.setup_execution_config(), tape
with pytest.raises(
NotImplementedError,
diff --git a/tests/ops/functions/test_map_wires.py b/tests/ops/functions/test_map_wires.py
index 8f6abe2f02b..aee65a01920 100644
--- a/tests/ops/functions/test_map_wires.py
+++ b/tests/ops/functions/test_map_wires.py
@@ -198,8 +198,8 @@ def qfunc():
assert isinstance(m_ops[1], Prod)
qml.assert_equal(m_ops[0], mapped_op)
qml.assert_equal(m_ops[1], mapped_op_2)
- assert m_qnode.tape.observables[0].wires == Wires(wire_map[0])
- assert m_qnode.tape.observables[1].wires == Wires(wire_map[1])
+ assert m_tape.observables[0].wires == Wires(wire_map[0])
+ assert m_tape.observables[1].wires == Wires(wire_map[1])
@pytest.mark.jax
def test_jitting_simplified_qfunc(self):
diff --git a/tests/test_qnode.py b/tests/test_qnode.py
index e5a92989e7d..9529df3f6f0 100644
--- a/tests/test_qnode.py
+++ b/tests/test_qnode.py
@@ -31,21 +31,6 @@
from pennylane.typing import PostprocessingFn
-def test_tape_property_is_deprecated():
- """Test that the tape property is deprecated."""
- dev = qml.device("default.qubit")
-
- @qml.qnode(dev)
- def circuit(x):
- qml.RX(x, wires=0)
- return qml.PauliY(0)
-
- with pytest.warns(
- qml.PennyLaneDeprecationWarning, match="The tape/qtape property is deprecated"
- ):
- _ = circuit.tape
-
-
def dummyfunc():
"""dummy func."""
return None
@@ -482,47 +467,6 @@ def circuit():
class TestTapeConstruction:
"""Tests for the tape construction"""
- def test_basic_tape_construction(self, tol):
- """Test that a quantum tape is properly constructed"""
- dev = qml.device("default.qubit", wires=2)
-
- def func(x, y):
- qml.RX(x, wires=0)
- qml.RY(y, wires=1)
- qml.CNOT(wires=[0, 1])
- return qml.expval(qml.PauliZ(0))
-
- qn = QNode(func, dev)
-
- x = pnp.array(0.12, requires_grad=True)
- y = pnp.array(0.54, requires_grad=True)
-
- res = qn(x, y)
- with pytest.warns(
- qml.PennyLaneDeprecationWarning, match="tape/qtape property is deprecated"
- ):
- tape = qn.tape
-
- assert isinstance(tape, QuantumScript)
- assert len(tape.operations) == 3
- assert len(tape.observables) == 1
- assert tape.num_params == 2
- assert tape.shots.total_shots is None
-
- expected = qml.execute([tape], dev, None)
- assert np.allclose(res, expected, atol=tol, rtol=0)
-
- # when called, a new quantum tape is constructed
- old_tape = tape
- res2 = qn(x, y)
- with pytest.warns(
- qml.PennyLaneDeprecationWarning, match="tape/qtape property is deprecated"
- ):
- new_tape = qn.tape
-
- assert np.allclose(res, res2, atol=tol, rtol=0)
- assert new_tape is not old_tape
-
def test_returning_non_measurements(self):
"""Test that an exception is raised if a non-measurement
is returned from the QNode."""
diff --git a/tests/test_qnode_legacy.py b/tests/test_qnode_legacy.py
index 0bcb4bf1134..26c46687934 100644
--- a/tests/test_qnode_legacy.py
+++ b/tests/test_qnode_legacy.py
@@ -32,21 +32,6 @@
from pennylane.typing import PostprocessingFn
-def test_legacy_qtape_property_is_deprecated():
- """Test that the legacy qtape property is deprecated."""
- dev = qml.device("default.qubit")
-
- @qml.qnode(dev)
- def circuit(x):
- qml.RX(x, wires=0)
- return qml.PauliY(0)
-
- with pytest.warns(
- qml.PennyLaneDeprecationWarning, match="The tape/qtape property is deprecated"
- ):
- _ = circuit.qtape
-
-
def dummyfunc():
"""dummy func."""
return None