Repository: PennyLaneAI/pennylane
Pull request #7484 (2025-05-26 04:04:11)

Update stable dependency files
Automatic update of stable requirement files to snapshot valid python environments.

Because bots are not able to trigger CI on their own, please do so by pushing an empty commit to this branch using the following command:

```
git commit --allow-empty -m 'trigger ci'
```



Patch:
diff --git a/.github/stable/all_interfaces.txt b/.github/stable/all_interfaces.txt
index a622464f3..22f588cc5 100644
--- a/.github/stable/all_interfaces.txt
+++ b/.github/stable/all_interfaces.txt
@@ -5,14 +5,16 @@ astunparse==1.6.3
 autograd==1.8.0
 autoray==0.7.1
 black==25.1.0
-cachetools==5.5.2
+build==1.2.2.post1
+cachetools==6.0.0
 certifi==2025.4.26
+cffi==1.17.1
 cfgv==3.4.0
 charset-normalizer==3.4.2
-clarabel==0.10.0
-click==8.2.0
+clarabel==0.11.0
+click==8.2.1
 contourpy==1.3.2
-coverage==7.8.0
+coverage==7.8.2
 cvxopt==1.3.2
 cvxpy==1.6.5
 cycler==0.12.1
@@ -24,22 +26,22 @@ filelock==3.18.0
 flaky==3.8.1
 flatbuffers==25.2.10
 fonttools==4.58.0
-fsspec==2025.3.2
+fsspec==2025.5.1
 gast==0.6.0
 gitdb==4.0.12
 GitPython==3.1.44
 google-pasta==0.2.0
 grpcio==1.71.0
 h5py==3.13.0
-identify==2.6.10
+identify==2.6.12
 idna==3.10
 iniconfig==2.1.0
 isort==5.13.2
-jax==0.5.3
-jaxlib==0.5.3
+jax==0.6.0
+jaxlib==0.6.0
 Jinja2==3.1.6
-joblib==1.5.0
-keras==3.9.2
+joblib==1.5.1
+keras==3.10.0
 kiwisolver==1.4.8
 lazy-object-proxy==1.11.0
 libclang==18.1.1
@@ -74,19 +76,21 @@ osqp==1.0.4
 packaging==25.0
 pandas==2.2.3
 pathspec==0.12.1
-PennyLane_Lightning==0.42.0.dev14
+PennyLane_Lightning==0.42.0.dev22
 pillow==11.2.1
 platformdirs==4.3.8
-pluggy==1.5.0
+pluggy==1.6.0
 pre_commit==4.2.0
 prompt_toolkit==3.0.51
 protobuf==5.29.4
 py==1.11.0
 py-cpuinfo==9.0.0
+pycparser==2.22
 pydot==3.0.4
 Pygments==2.19.1
 pylint==2.7.4
 pyparsing==3.2.3
+pyproject_hooks==1.2.0
 pytest==8.3.5
 pytest-benchmark==5.1.0
 pytest-cov==6.1.1
@@ -94,7 +98,6 @@ pytest-forked==1.6.0
 pytest-mock==3.14.0
 pytest-rng==1.0.0
 pytest-split==0.10.0
-pytest-timeout==2.4.0
 pytest-xdist==3.6.1
 python-dateutil==2.9.0.post0
 pytz==2025.2
@@ -103,7 +106,7 @@ requests==2.32.3
 rich==13.9.4
 rustworkx==0.16.0
 scipy==1.15.3
-scipy-openblas32==0.3.29.0.0
+scipy-openblas32==0.3.29.265.0
 scs==3.2.7.post2
 six==1.17.0
 smmap==5.0.2
diff --git a/.github/stable/core.txt b/.github/stable/core.txt
index cfd0f6e7d..c285968dd 100644
--- a/.github/stable/core.txt
+++ b/.github/stable/core.txt
@@ -4,14 +4,16 @@ astunparse==1.6.3
 autograd==1.8.0
 autoray==0.7.1
 black==25.1.0
-cachetools==5.5.2
+build==1.2.2.post1
+cachetools==6.0.0
 certifi==2025.4.26
+cffi==1.17.1
 cfgv==3.4.0
 charset-normalizer==3.4.2
-clarabel==0.10.0
-click==8.2.0
+clarabel==0.11.0
+click==8.2.1
 contourpy==1.3.2
-coverage==7.8.0
+coverage==7.8.2
 cvxopt==1.3.2
 cvxpy==1.6.5
 cycler==0.12.1
@@ -25,12 +27,12 @@ fonttools==4.58.0
 gast==0.6.0
 gitdb==4.0.12
 GitPython==3.1.44
-identify==2.6.10
+identify==2.6.12
 idna==3.10
 iniconfig==2.1.0
 isort==5.13.2
 Jinja2==3.1.6
-joblib==1.5.0
+joblib==1.5.1
 kiwisolver==1.4.8
 lazy-object-proxy==1.11.0
 markdown-it-py==3.0.0
@@ -41,23 +43,25 @@ mdurl==0.1.2
 mypy_extensions==1.1.0
 networkx==3.4.2
 nodeenv==1.9.1
-numpy==2.2.5
+numpy==2.2.6
 osqp==1.0.4
 packaging==25.0
 pandas==2.2.3
 pathspec==0.12.1
-PennyLane_Lightning==0.42.0.dev14
+PennyLane_Lightning==0.42.0.dev22
 pillow==11.2.1
 platformdirs==4.3.8
-pluggy==1.5.0
+pluggy==1.6.0
 pre_commit==4.2.0
 prompt_toolkit==3.0.51
 py==1.11.0
 py-cpuinfo==9.0.0
+pycparser==2.22
 pydot==3.0.4
 Pygments==2.19.1
 pylint==2.7.4
 pyparsing==3.2.3
+pyproject_hooks==1.2.0
 pytest==8.3.5
 pytest-benchmark==5.1.0
 pytest-cov==6.1.1
@@ -65,7 +69,6 @@ pytest-forked==1.6.0
 pytest-mock==3.14.0
 pytest-rng==1.0.0
 pytest-split==0.10.0
-pytest-timeout==2.4.0
 pytest-xdist==3.6.1
 python-dateutil==2.9.0.post0
 pytz==2025.2
@@ -74,7 +77,7 @@ requests==2.32.3
 rich==13.9.4
 rustworkx==0.16.0
 scipy==1.15.3
-scipy-openblas32==0.3.29.0.0
+scipy-openblas32==0.3.29.265.0
 scs==3.2.7.post2
 six==1.17.0
 smmap==5.0.2
diff --git a/.github/stable/external.txt b/.github/stable/external.txt
index 7061e9d46..52fc49beb 100644
--- a/.github/stable/external.txt
+++ b/.github/stable/external.txt
@@ -19,20 +19,21 @@ beautifulsoup4==4.13.4
 black==25.1.0
 bleach==6.2.0
 blinker==1.9.0
-cachetools==5.5.2
+build==1.2.2.post1
+cachetools==6.0.0
 certifi==2025.4.26
 cffi==1.17.1
 cfgv==3.4.0
 charset-normalizer==3.4.2
 chex==0.1.89
 cirq-core==1.4.0
-clarabel==0.10.0
-click==8.2.0
+clarabel==0.11.0
+click==8.2.1
 comm==0.2.2
 contourpy==1.3.2
-cotengra==0.7.2
-coverage==7.8.0
-cryptography==44.0.3
+cotengra==0.7.4
+coverage==7.8.2
+cryptography==45.0.3
 cvxopt==1.3.2
 cvxpy==1.6.5
 cycler==0.12.1
@@ -69,8 +70,8 @@ h5py==3.13.0
 httpcore==1.0.9
 httpx==0.28.1
 ibm-cloud-sdk-core==3.23.0
-ibm-platform-services==0.65.0
-identify==2.6.10
+ibm-platform-services==0.66.0
+identify==2.6.12
 idna==3.10
 immutabledict==4.2.1
 importlib_metadata==8.7.0
@@ -81,11 +82,11 @@ ipywidgets==8.1.7
 isoduration==20.11.0
 isort==5.13.2
 itsdangerous==2.2.0
-jax==0.5.3
-jaxlib==0.5.3
+jax==0.6.0
+jaxlib==0.6.0
 jedi==0.19.2
 Jinja2==3.1.6
-joblib==1.5.0
+joblib==1.5.1
 json5==0.12.0
 jsonpointer==3.0.0
 jsonschema==4.23.0
@@ -94,13 +95,13 @@ jupyter-events==0.12.0
 jupyter-lsp==2.2.5
 jupyter_client==8.6.3
 jupyter_core==5.7.2
-jupyter_server==2.15.0
+jupyter_server==2.16.0
 jupyter_server_terminals==0.5.3
 jupyterlab==4.4.2
 jupyterlab_pygments==0.3.0
 jupyterlab_server==2.27.3
 jupyterlab_widgets==3.0.15
-keras==3.9.2
+keras==3.10.0
 kiwisolver==1.4.8
 lark==1.2.2
 lazy-object-proxy==1.11.0
@@ -119,7 +120,7 @@ ml_dtypes==0.5.1
 mpmath==1.3.0
 mypy_extensions==1.1.0
 namex==0.0.9
-narwhals==1.38.2
+narwhals==1.40.0
 nbclient==0.10.2
 nbconvert==7.16.6
 nbformat==5.10.4
@@ -142,18 +143,18 @@ pandocfilters==1.5.1
 parso==0.8.4
 pathspec==0.12.1
 pbr==6.1.1
-PennyLane-Catalyst==0.12.0.dev28
-PennyLane-qiskit @ git+https://github.com/PennyLaneAI/pennylane-qiskit.git@129a38dd3374870715939391780f870672c2690f
-PennyLane_Lightning==0.42.0.dev11
-PennyLane_Lightning_Kokkos==0.42.0.dev11
+PennyLane-Catalyst==0.12.0.dev40
+PennyLane-qiskit @ git+https://github.com/PennyLaneAI/pennylane-qiskit.git@1c51db6e05ce9dd55370bb4b97c6666571cd572c
+PennyLane_Lightning==0.42.0.dev16
+PennyLane_Lightning_Kokkos==0.42.0.dev16
 pexpect==4.9.0
 pillow==11.2.1
 platformdirs==4.3.8
-plotly==6.0.1
-pluggy==1.5.0
+plotly==6.1.1
+pluggy==1.6.0
 ply==3.11
 pre_commit==4.2.0
-prometheus_client==0.21.1
+prometheus_client==0.22.0
 prompt_toolkit==3.0.51
 protobuf==5.29.4
 psutil==7.0.0
@@ -163,7 +164,7 @@ pure_eval==0.2.3
 py==1.11.0
 py-cpuinfo==9.0.0
 pycparser==2.22
-pydantic==2.11.4
+pydantic==2.11.5
 pydantic_core==2.33.2
 pydot==3.0.4
 Pygments==2.19.1
@@ -171,6 +172,7 @@ PyJWT==2.10.1
 pylint==2.7.4
 pyparsing==3.1.4
 pyperclip==1.9.0
+pyproject_hooks==1.2.0
 pyspnego==0.11.2
 pytest==8.3.5
 pytest-benchmark==5.1.0
@@ -179,7 +181,6 @@ pytest-forked==1.6.0
 pytest-mock==3.14.0
 pytest-rng==1.0.0
 pytest-split==0.10.0
-pytest-timeout==2.4.0
 pytest-xdist==3.6.1
 python-dateutil==2.9.0.post0
 python-json-logger==3.3.0
@@ -195,7 +196,7 @@ qref==0.9.0
 qsharp==1.16.0
 qsharp-widgets==1.16.0
 qualtran==0.6.1
-quimb==1.10.0
+quimb==1.11.0
 referencing==0.36.2
 requests==2.32.3
 requests_ntlm==1.3.0
@@ -203,10 +204,10 @@ retrying==1.3.4
 rfc3339-validator==0.1.4
 rfc3986-validator==0.1.1
 rich==13.9.4
-rpds-py==0.24.0
+rpds-py==0.25.1
 rustworkx==0.16.0
 scipy==1.15.2
-scipy-openblas32==0.3.29.0.0
+scipy-openblas32==0.3.29.265.0
 scs==3.2.7.post2
 Send2Trash==1.8.3
 six==1.17.0
@@ -234,11 +235,11 @@ tomli==2.2.1
 tomli_w==1.2.0
 tomlkit==0.13.2
 toolz==1.0.0
-tornado==6.4.2
+tornado==6.5.1
 tqdm==4.67.1
 traitlets==5.14.3
-types-python-dateutil==2.9.0.20241206
-typing-inspection==0.4.0
+types-python-dateutil==2.9.0.20250516
+typing-inspection==0.4.1
 typing_extensions==4.13.2
 tzdata==2025.2
 uri-template==1.3.0
@@ -252,5 +253,5 @@ websockets==15.0.1
 Werkzeug==3.0.6
 widgetsnbextension==4.0.14
 wrapt==1.12.1
-xdsl==0.37.0
+xdsl==0.38.1
 zipp==3.21.0
diff --git a/.github/stable/jax.txt b/.github/stable/jax.txt
index 55718be3e..7512a612e 100644
--- a/.github/stable/jax.txt
+++ b/.github/stable/jax.txt
@@ -4,14 +4,16 @@ astunparse==1.6.3
 autograd==1.8.0
 autoray==0.7.1
 black==25.1.0
-cachetools==5.5.2
+build==1.2.2.post1
+cachetools==6.0.0
 certifi==2025.4.26
+cffi==1.17.1
 cfgv==3.4.0
 charset-normalizer==3.4.2
-clarabel==0.10.0
-click==8.2.0
+clarabel==0.11.0
+click==8.2.1
 contourpy==1.3.2
-coverage==7.8.0
+coverage==7.8.2
 cvxopt==1.3.2
 cvxpy==1.6.5
 cycler==0.12.1
@@ -25,14 +27,14 @@ fonttools==4.58.0
 gast==0.6.0
 gitdb==4.0.12
 GitPython==3.1.44
-identify==2.6.10
+identify==2.6.12
 idna==3.10
 iniconfig==2.1.0
 isort==5.13.2
-jax==0.5.3
-jaxlib==0.5.3
+jax==0.6.0
+jaxlib==0.6.0
 Jinja2==3.1.6
-joblib==1.5.0
+joblib==1.5.1
 kiwisolver==1.4.8
 lazy-object-proxy==1.11.0
 markdown-it-py==3.0.0
@@ -44,24 +46,26 @@ ml_dtypes==0.5.1
 mypy_extensions==1.1.0
 networkx==3.4.2
 nodeenv==1.9.1
-numpy==2.2.5
+numpy==2.2.6
 opt_einsum==3.4.0
 osqp==1.0.4
 packaging==25.0
 pandas==2.2.3
 pathspec==0.12.1
-PennyLane_Lightning==0.42.0.dev14
+PennyLane_Lightning==0.42.0.dev22
 pillow==11.2.1
 platformdirs==4.3.8
-pluggy==1.5.0
+pluggy==1.6.0
 pre_commit==4.2.0
 prompt_toolkit==3.0.51
 py==1.11.0
 py-cpuinfo==9.0.0
+pycparser==2.22
 pydot==3.0.4
 Pygments==2.19.1
 pylint==2.7.4
 pyparsing==3.2.3
+pyproject_hooks==1.2.0
 pytest==8.3.5
 pytest-benchmark==5.1.0
 pytest-cov==6.1.1
@@ -69,7 +73,6 @@ pytest-forked==1.6.0
 pytest-mock==3.14.0
 pytest-rng==1.0.0
 pytest-split==0.10.0
-pytest-timeout==2.4.0
 pytest-xdist==3.6.1
 python-dateutil==2.9.0.post0
 pytz==2025.2
@@ -78,7 +81,7 @@ requests==2.32.3
 rich==13.9.4
 rustworkx==0.16.0
 scipy==1.15.3
-scipy-openblas32==0.3.29.0.0
+scipy-openblas32==0.3.29.265.0
 scs==3.2.7.post2
 six==1.17.0
 smmap==5.0.2
diff --git a/.github/stable/tf.txt b/.github/stable/tf.txt
index 6f61d935b..ad56d8aee 100644
--- a/.github/stable/tf.txt
+++ b/.github/stable/tf.txt
@@ -5,14 +5,16 @@ astunparse==1.6.3
 autograd==1.8.0
 autoray==0.7.1
 black==25.1.0
-cachetools==5.5.2
+build==1.2.2.post1
+cachetools==6.0.0
 certifi==2025.4.26
+cffi==1.17.1
 cfgv==3.4.0
 charset-normalizer==3.4.2
-clarabel==0.10.0
-click==8.2.0
+clarabel==0.11.0
+click==8.2.1
 contourpy==1.3.2
-coverage==7.8.0
+coverage==7.8.2
 cvxopt==1.3.2
 cvxpy==1.6.5
 cycler==0.12.1
@@ -30,13 +32,13 @@ GitPython==3.1.44
 google-pasta==0.2.0
 grpcio==1.71.0
 h5py==3.13.0
-identify==2.6.10
+identify==2.6.12
 idna==3.10
 iniconfig==2.1.0
 isort==5.13.2
 Jinja2==3.1.6
-joblib==1.5.0
-keras==3.9.2
+joblib==1.5.1
+keras==3.10.0
 kiwisolver==1.4.8
 lazy-object-proxy==1.11.0
 libclang==18.1.1
@@ -58,19 +60,21 @@ osqp==1.0.4
 packaging==25.0
 pandas==2.2.3
 pathspec==0.12.1
-PennyLane_Lightning==0.42.0.dev14
+PennyLane_Lightning==0.42.0.dev22
 pillow==11.2.1
 platformdirs==4.3.8
-pluggy==1.5.0
+pluggy==1.6.0
 pre_commit==4.2.0
 prompt_toolkit==3.0.51
 protobuf==5.29.4
 py==1.11.0
 py-cpuinfo==9.0.0
+pycparser==2.22
 pydot==3.0.4
 Pygments==2.19.1
 pylint==2.7.4
 pyparsing==3.2.3
+pyproject_hooks==1.2.0
 pytest==8.3.5
 pytest-benchmark==5.1.0
 pytest-cov==6.1.1
@@ -78,7 +82,6 @@ pytest-forked==1.6.0
 pytest-mock==3.14.0
 pytest-rng==1.0.0
 pytest-split==0.10.0
-pytest-timeout==2.4.0
 pytest-xdist==3.6.1
 python-dateutil==2.9.0.post0
 pytz==2025.2
@@ -87,7 +90,7 @@ requests==2.32.3
 rich==13.9.4
 rustworkx==0.16.0
 scipy==1.15.3
-scipy-openblas32==0.3.29.0.0
+scipy-openblas32==0.3.29.265.0
 scs==3.2.7.post2
 six==1.17.0
 smmap==5.0.2
diff --git a/.github/stable/torch.txt b/.github/stable/torch.txt
index 2f7727fad..2f093367c 100644
--- a/.github/stable/torch.txt
+++ b/.github/stable/torch.txt
@@ -4,14 +4,16 @@ astunparse==1.6.3
 autograd==1.8.0
 autoray==0.7.1
 black==25.1.0
-cachetools==5.5.2
+build==1.2.2.post1
+cachetools==6.0.0
 certifi==2025.4.26
+cffi==1.17.1
 cfgv==3.4.0
 charset-normalizer==3.4.2
-clarabel==0.10.0
-click==8.2.0
+clarabel==0.11.0
+click==8.2.1
 contourpy==1.3.2
-coverage==7.8.0
+coverage==7.8.2
 cvxopt==1.3.2
 cvxpy==1.6.5
 cycler==0.12.1
@@ -22,16 +24,16 @@ execnet==2.1.1
 filelock==3.18.0
 flaky==3.8.1
 fonttools==4.58.0
-fsspec==2025.3.2
+fsspec==2025.5.1
 gast==0.6.0
 gitdb==4.0.12
 GitPython==3.1.44
-identify==2.6.10
+identify==2.6.12
 idna==3.10
 iniconfig==2.1.0
 isort==5.13.2
 Jinja2==3.1.6
-joblib==1.5.0
+joblib==1.5.1
 kiwisolver==1.4.8
 lazy-object-proxy==1.11.0
 markdown-it-py==3.0.0
@@ -43,7 +45,7 @@ mpmath==1.3.0
 mypy_extensions==1.1.0
 networkx==3.4.2
 nodeenv==1.9.1
-numpy==2.2.5
+numpy==2.2.6
 nvidia-cublas-cu12==12.4.5.8
 nvidia-cuda-cupti-cu12==12.4.127
 nvidia-cuda-nvrtc-cu12==12.4.127
@@ -60,18 +62,20 @@ osqp==1.0.4
 packaging==25.0
 pandas==2.2.3
 pathspec==0.12.1
-PennyLane_Lightning==0.42.0.dev14
+PennyLane_Lightning==0.42.0.dev22
 pillow==11.2.1
 platformdirs==4.3.8
-pluggy==1.5.0
+pluggy==1.6.0
 pre_commit==4.2.0
 prompt_toolkit==3.0.51
 py==1.11.0
 py-cpuinfo==9.0.0
+pycparser==2.22
 pydot==3.0.4
 Pygments==2.19.1
 pylint==2.7.4
 pyparsing==3.2.3
+pyproject_hooks==1.2.0
 pytest==8.3.5
 pytest-benchmark==5.1.0
 pytest-cov==6.1.1
@@ -79,7 +83,6 @@ pytest-forked==1.6.0
 pytest-mock==3.14.0
 pytest-rng==1.0.0
 pytest-split==0.10.0
-pytest-timeout==2.4.0
 pytest-xdist==3.6.1
 python-dateutil==2.9.0.post0
 pytz==2025.2
@@ -88,7 +91,7 @@ requests==2.32.3
 rich==13.9.4
 rustworkx==0.16.0
 scipy==1.15.3
-scipy-openblas32==0.3.29.0.0
+scipy-openblas32==0.3.29.265.0
 scs==3.2.7.post2
 six==1.17.0
 smmap==5.0.2
diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md
index 80049ef63..bc68705e4 100644
--- a/doc/releases/changelog-dev.md
+++ b/doc/releases/changelog-dev.md
@@ -6,6 +6,7 @@
 
 * A new QNode transform called :func:`~.transforms.set_shots` has been added to set or update the number of shots to be performed, overriding shots specified in the device.
   [(#7337)](https://github.com/PennyLaneAI/pennylane/pull/7337)
+  [(#7358)](https://github.com/PennyLaneAI/pennylane/pull/7358)
 
   The :func:`~.transforms.set_shots` transform can be used as a decorator:
 
@@ -287,6 +288,11 @@
 
 <h3>Improvements 🛠</h3>
 
+* Setting up the configuration of a workflow, including the determination of the best diff
+  method, is now done *after* user transforms have been applied. This allows transforms to
+  update the shots and change measurement processes with fewer issues.
+  [(#7358)](https://github.com/PennyLaneAI/pennylane/pull/7358)
+
 * The decomposition of `DiagonalQubitUnitary` has been updated to a recursive decomposition
   into a smaller `DiagonalQubitUnitary` and a `SelectPauliRot` operation. This is a known
   decomposition [Theorem 7 in Shende et al.](https://arxiv.org/abs/quant-ph/0406176)
@@ -464,6 +470,9 @@ Here's a list of deprecations made this release. For a more detailed breakdown o
 
 <h3>Internal changes ⚙️</h3>
 
+* `DefaultQubit` now implements `preprocess_transforms` and `setup_execution_config` instead of `preprocess`.
+  [(#7468)](https://github.com/PennyLaneAI/pennylane/pull/7468)
+
 * Fix subset of `pylint` errors in the `tests` folder.
   [(#7446)](https://github.com/PennyLaneAI/pennylane/pull/7446)
 
diff --git a/pennylane/devices/default_qubit.py b/pennylane/devices/default_qubit.py
index 694a1baf2..ec7e3dc3b 100644
--- a/pennylane/devices/default_qubit.py
+++ b/pennylane/devices/default_qubit.py
@@ -531,25 +531,20 @@ class DefaultQubit(Device):
         return False
 
     @debug_logger
-    def preprocess(
-        self,
-        execution_config: ExecutionConfig = DefaultExecutionConfig,
-    ) -> tuple[TransformProgram, ExecutionConfig]:
+    def preprocess_transforms(
+        self, execution_config: Optional[ExecutionConfig] = None
+    ) -> TransformProgram:
         """This function defines the device transform program to be applied and an updated device configuration.
 
         Args:
-            execution_config (Union[ExecutionConfig, Sequence[ExecutionConfig]]): A data structure describing the
+            execution_config (Optional[ExecutionConfig]): A data structure describing the
                 parameters needed to fully describe the execution.
 
         Returns:
-            TransformProgram, ExecutionConfig: A transform program that when called returns QuantumTapes that the device
-            can natively execute as well as a postprocessing function to be called after execution, and a configuration with
-            unset specifications filled in.
-
-        This device supports any qubit operations that provide a matrix
+            TransformProgram:
 
         """
-        config = self._setup_execution_config(execution_config)
+        config = execution_config or ExecutionConfig()
         transform_program = TransformProgram()
 
         if qml.capture.enabled():
@@ -558,7 +553,7 @@ class DefaultQubit(Device):
                 transform_program.add_transform(qml.defer_measurements, num_wires=len(self.wires))
             transform_program.add_transform(qml.transforms.decompose, gate_set=stopping_condition)
 
-            return transform_program, config
+            return transform_program
 
         if config.interface == qml.math.Interface.JAX_JIT:
             transform_program.add_transform(no_counts)
@@ -595,29 +590,24 @@ class DefaultQubit(Device):
                 transform_program, device_vjp=config.use_device_jacobian_product
             )
 
-        return transform_program, config
+        return transform_program
 
     # pylint: disable = too-many-branches
-    def _setup_execution_config(self, execution_config: ExecutionConfig) -> ExecutionConfig:
-        """This is a private helper for ``preprocess`` that sets up the execution config.
-
-        Args:
-            execution_config (ExecutionConfig)
-
-        Returns:
-            ExecutionConfig: a preprocessed execution config
-
-        """
+    @debug_logger
+    def setup_execution_config(
+        self, config: Optional[ExecutionConfig] = None, circuit: Optional[QuantumScript] = None
+    ) -> ExecutionConfig:
+        config = config or ExecutionConfig()
         updated_values = {}
 
         # uncomment once compilation overhead with jitting improved
         # TODO: [sc-82874]
         # jax_interfaces = {qml.math.Interface.JAX, qml.math.Interface.JAX_JIT}
         # updated_values["convert_to_numpy"] = (
-        #    execution_config.interface not in jax_interfaces
-        #    or execution_config.gradient_method == "adjoint"
+        #    config.interface not in jax_interfaces
+        #    or config.gradient_method == "adjoint"
         #    # need numpy to use caching, and need caching higher order derivatives
-        #    or execution_config.derivative_order > 1
+        #    or config.derivative_order > 1
         # )
 
         # If PRNGKey is present, we can't use a pure_callback, because that would cause leaked tracers
@@ -627,14 +617,14 @@ class DefaultQubit(Device):
             updated_values["convert_to_numpy"] = not (
                 (
                     self._prng_key is not None
-                    and execution_config.interface in jax_interfaces
-                    and execution_config.gradient_method != "adjoint"
+                    and config.interface in jax_interfaces
+                    and config.gradient_method != "adjoint"
                     # need numpy to use caching, and need caching higher order derivatives
-                    and execution_config.derivative_order == 1
+                    and config.derivative_order == 1
                 )
             )
 
-        for option, value in execution_config.device_options.items():
+        for option, value in config.device_options.items():
             if option not in self._device_options:
                 raise DeviceError(f"device option {option} not present on {self}")
 
@@ -642,31 +632,31 @@ class DefaultQubit(Device):
                 if option == "max_workers" and value is not None:
                     raise DeviceError("Cannot set 'max_workers' if program capture is enabled.")
 
-        gradient_method = execution_config.gradient_method
-        if execution_config.gradient_method == "best":
+        gradient_method = config.gradient_method
+        if config.gradient_method == "best":
             no_max_workers = (
-                execution_config.device_options.get("max_workers", self._max_workers) is None
+                config.device_options.get("max_workers", self._max_workers) is None
             ) or qml.capture.enabled()
             gradient_method = "backprop" if no_max_workers else "adjoint"
             updated_values["gradient_method"] = gradient_method
 
-        if execution_config.use_device_gradient is None:
+        if config.use_device_gradient is None:
             updated_values["use_device_gradient"] = gradient_method in {
                 "adjoint",
                 "backprop",
             }
-        if execution_config.use_device_jacobian_product is None:
+        if config.use_device_jacobian_product is None:
             updated_values["use_device_jacobian_product"] = gradient_method == "adjoint"
-        if execution_config.grad_on_execution is None:
+        if config.grad_on_execution is None:
             updated_values["grad_on_execution"] = gradient_method == "adjoint"
 
-        updated_values["device_options"] = dict(execution_config.device_options)  # copy
+        updated_values["device_options"] = dict(config.device_options)  # copy
         for option in self._device_options:
             if option not in updated_values["device_options"]:
                 updated_values["device_options"][option] = getattr(self, f"_{option}")
 
         if qml.capture.enabled():
-            mcm_config = execution_config.mcm_config
+            mcm_config = config.mcm_config
             mcm_updated_values = {}
             if (mcm_method := mcm_config.mcm_method) not in (
                 "deferred",
@@ -689,7 +679,7 @@ class DefaultQubit(Device):
                 mcm_updated_values["mcm_method"] = "deferred"
             updated_values["mcm_config"] = replace(mcm_config, **mcm_updated_values)
 
-        return replace(execution_config, **updated_values)
+        return replace(config, **updated_values)
 
     @debug_logger
     def execute(
diff --git a/pennylane/devices/device_constructor.py b/pennylane/devices/device_constructor.py
index 3771267eb..74696167f 100644
--- a/pennylane/devices/device_constructor.py
+++ b/pennylane/devices/device_constructor.py
@@ -273,11 +273,18 @@ def device(name, *args, **kwargs):
                     custom_decomps, dev
                 )
                 dev.custom_expand(custom_decomp_expand_fn)
+
             else:
-                custom_decomp_preprocess = qml.transforms.tape_expand._create_decomp_preprocessing(
-                    custom_decomps, dev
+                override_method = (
+                    "preprocess_transforms"
+                    if type(dev).preprocess == qml.devices.Device.preprocess
+                    else "preprocess"
+                )
+
+                new_method = qml.transforms.tape_expand._create_decomp_preprocessing(
+                    custom_decomps, dev, override_method=override_method
                 )
-                dev.preprocess = custom_decomp_preprocess
+                setattr(dev, override_method, new_method)
 
         if isinstance(dev, qml.devices.LegacyDevice):
             dev = qml.devices.LegacyDeviceFacade(dev)
diff --git a/pennylane/devices/null_qubit.py b/pennylane/devices/null_qubit.py
index c849edb2d..86fdb54d1 100644
--- a/pennylane/devices/null_qubit.py
+++ b/pennylane/devices/null_qubit.py
@@ -345,7 +345,7 @@ class NullQubit(Device):
     def preprocess(
         self, execution_config=DefaultExecutionConfig
     ) -> tuple[TransformProgram, ExecutionConfig]:
-        program, _ = DefaultQubit.preprocess(self, execution_config)
+        program = DefaultQubit.preprocess_transforms(self, execution_config)
         for t in program:
             if t.transform == decompose.transform:
                 original_stopping_condition = t.kwargs["stopping_condition"]
diff --git a/pennylane/transforms/core/transform_dispatcher.py b/pennylane/transforms/core/transform_dispatcher.py
index 1e507df18..8720bba9e 100644
--- a/pennylane/transforms/core/transform_dispatcher.py
+++ b/pennylane/transforms/core/transform_dispatcher.py
@@ -94,6 +94,74 @@ def _register_primitive_for_expansion(primitive, plxpr_transform):
         return copy(self).eval(jaxpr.jaxpr, jaxpr.consts, *args)
 
 
+def _preprocess_device(original_device, transform, targs, tkwargs):
+    class TransformedDevice(type(original_device)):
+        """A transformed device with updated preprocess method."""
+
+        def __init__(self, original_device, transform, targs, tkwargs):
+            for key, value in original_device.__dict__.items():
+                self.__setattr__(key, value)
+            self.transform = transform
+            self.targs = targs
+            self.tkwargs = tkwargs
+            self._original_device = original_device
+
+        def __repr__(self):
+            return f"Transformed Device({original_device.__repr__()} with additional preprocess transform {self.transform})"
+
+        def preprocess(
+            self,
+            execution_config: qml.devices.ExecutionConfig = qml.devices.DefaultExecutionConfig,
+        ):
+            """This function updates the original device transform program to be applied."""
+            program, config = self.original_device.preprocess(execution_config)
+            program.push_back(
+                TransformContainer(self.transform, args=self.targs, kwargs=self.tkwargs)
+            )
+            return program, config
+
+        @property
+        def original_device(self):
+            """Return the original device."""
+            return self._original_device
+
+    return TransformedDevice(original_device, transform, targs, tkwargs)
+
+
+def _preprocess_transforms_device(original_device, transform, targs, tkwargs):
+    class TransformedDevice(type(original_device)):
+        """A transformed device with updated preprocess method."""
+
+        def __init__(self, original_device, transform, targs, tkwargs):
+            for key, value in original_device.__dict__.items():
+                self.__setattr__(key, value)
+            self.transform = transform
+            self.targs = targs
+            self.tkwargs = tkwargs
+            self._original_device = original_device
+
+        def __repr__(self):
+            return f"Transformed Device({original_device.__repr__()} with additional preprocess transform {self.transform})"
+
+        def preprocess_transforms(
+            self,
+            execution_config: qml.devices.ExecutionConfig = qml.devices.DefaultExecutionConfig,
+        ):
+            """This function updates the original device transform program to be applied."""
+            program = self.original_device.preprocess_transforms(execution_config)
+            program.push_back(
+                TransformContainer(self.transform, args=self.targs, kwargs=self.tkwargs)
+            )
+            return program
+
+        @property
+        def original_device(self):
+            """Return the original device."""
+            return self._original_device
+
+    return TransformedDevice(original_device, transform, targs, tkwargs)
+
+
 class TransformDispatcher:  # pylint: disable=too-many-instance-attributes
     r"""Converts a transform that has the signature ``(tape -> Sequence(tape), fn)`` to a transform dispatcher
     that can act on :class:`pennylane.tape.QuantumTape`, quantum function, :class:`pennylane.QNode`,
@@ -404,33 +472,10 @@ class TransformDispatcher:  # pylint: disable=too-many-instance-attributes
         if self._final_transform:
             raise TransformError("Device transform does not support final transforms.")
 
-        class TransformedDevice(type(original_device)):
-            """A transformed device with updated preprocess method."""
-
-            def __init__(self, original_device, transform):
-                for key, value in original_device.__dict__.items():
-                    self.__setattr__(key, value)
-                self.transform = transform
-                self._original_device = original_device
-
-            def __repr__(self):
-                return f"Transformed Device({original_device.__repr__()} with additional preprocess transform {self.transform})"
-
-            def preprocess(
-                self,
-                execution_config: qml.devices.ExecutionConfig = qml.devices.DefaultExecutionConfig,
-            ):
-                """This function updates the original device transform program to be applied."""
-                program, config = self.original_device.preprocess(execution_config)
-                program.push_back(TransformContainer(self.transform, args=targs, kwargs=tkwargs))
-                return program, config
-
-            @property
-            def original_device(self):
-                """Return the original device."""
-                return self._original_device
-
-        return TransformedDevice(original_device, self._transform)
+        if type(original_device).preprocess != qml.devices.Device.preprocess:
+            return _preprocess_device(original_device, self.transform, targs, tkwargs)
+
+        return _preprocess_transforms_device(original_device, self.transform, targs, tkwargs)
 
     def _batch_transform(self, original_batch, targs, tkwargs):
         """Apply the transform on a batch of tapes."""
diff --git a/pennylane/transforms/tape_expand.py b/pennylane/transforms/tape_expand.py
index 96fdc2d61..abe5c9f15 100644
--- a/pennylane/transforms/tape_expand.py
+++ b/pennylane/transforms/tape_expand.py
@@ -15,11 +15,9 @@
 generate such functions from."""
 # pylint: disable=unused-argument,invalid-unary-operand-type
 import contextlib
-import warnings
 
 import pennylane as qml
 from pennylane import math
-from pennylane.exceptions import PennyLaneDeprecationWarning
 from pennylane.measurements import MeasurementProcess
 
 
@@ -359,7 +357,41 @@ def create_decomp_expand_fn(custom_decomps, dev, decomp_depth=None):
     return custom_decomp_expand
 
 
-def _create_decomp_preprocessing(custom_decomps, dev, decomp_depth=None):
+def _modify_program(program, custom_decomps):
+    def decomposer(op):
+        if isinstance(op, qml.ops.Controlled) and type(op.base) in custom_decomps:
+            op.base.compute_decomposition = custom_decomps[type(op.base)]
+            return op.decomposition()
+        if op.name in custom_decomps:
+            return custom_decomps[op.name](*op.data, wires=op.wires, **op.hyperparameters)
+        if type(op) in custom_decomps:
+            return custom_decomps[type(op)](*op.data, wires=op.wires, **op.hyperparameters)
+        return op.decomposition()
+
+    for container in program:
+        if container.transform == qml.devices.preprocess.decompose.transform:
+            container.kwargs["decomposer"] = decomposer
+
+            for cond in ["stopping_condition", "stopping_condition_shots"]:
+                # Devices that do not support native mid-circuit measurements
+                # will not have "stopping_condition_shots".
+                if cond in container.kwargs:
+                    original_stopping_condition = container.kwargs[cond]
+
+                    def stopping_condition(obj):
+                        if obj.name in custom_decomps or type(obj) in custom_decomps:
+                            return False
+                        # pylint: disable=cell-var-from-loop
+                        return original_stopping_condition(obj)
+
+                    container.kwargs[cond] = stopping_condition
+
+            break
+
+    return program
+
+
+def _create_decomp_preprocess(custom_decomps, dev):
     """Creates a custom preprocessing method for a device that applies
     a set of specified custom decompositions.
 
@@ -396,44 +428,29 @@ def _create_decomp_preprocessing(custom_decomps, dev, decomp_depth=None):
     >>> dev.preprocess = new_preprocessing
     """
 
-    def decomposer(op):
-        if isinstance(op, qml.ops.Controlled) and type(op.base) in custom_decomps:
-            op.base.compute_decomposition = custom_decomps[type(op.base)]
-            return op.decomposition()
-        if op.name in custom_decomps:
-            return custom_decomps[op.name](*op.data, wires=op.wires, **op.hyperparameters)
-        if type(op) in custom_decomps:
-            return custom_decomps[type(op)](*op.data, wires=op.wires, **op.hyperparameters)
-        return op.decomposition()
-
     original_preprocess = dev.preprocess
 
-    # pylint: disable=cell-var-from-loop
     def new_preprocess(execution_config=qml.devices.DefaultExecutionConfig):
         program, config = original_preprocess(execution_config)
+        return _modify_program(program, custom_decomps), config
 
-        for container in program:
-            if container.transform == qml.devices.preprocess.decompose.transform:
-                container.kwargs["decomposer"] = decomposer
+    return new_preprocess
 
-                for cond in ["stopping_condition", "stopping_condition_shots"]:
-                    # Devices that do not support native mid-circuit measurements
-                    # will not have "stopping_condition_shots".
-                    if cond in container.kwargs:
-                        original_stopping_condition = container.kwargs[cond]
 
-                        def stopping_condition(obj):
-                            if obj.name in custom_decomps or type(obj) in custom_decomps:
-                                return False
-                            return original_stopping_condition(obj)
+def _create_decomp_preprocess_transforms(custom_decomps, dev):
+    original_preprocess_transforms = dev.preprocess_transforms
 
-                        container.kwargs[cond] = stopping_condition
+    def new_preprocess_transforms(execution_config=qml.devices.DefaultExecutionConfig):
+        program = original_preprocess_transforms(execution_config)
+        return _modify_program(program, custom_decomps)
 
-                break
+    return new_preprocess_transforms
 
-        return program, config
 
-    return new_preprocess
+def _create_decomp_preprocessing(custom_decomps, dev, override_method):
+    if override_method == "preprocess":
+        return _create_decomp_preprocess(custom_decomps, dev)
+    return _create_decomp_preprocess_transforms(custom_decomps, dev)
 
 
 @contextlib.contextmanager
@@ -504,18 +521,18 @@ def set_decomposition(custom_decomps, dev):
             dev.custom_expand_fn = original_custom_expand_fn
 
     else:
-        with warnings.catch_warnings():
-            warnings.filterwarnings(
-                action="ignore",
-                message=r"max_expansion argument is deprecated",
-                category=PennyLaneDeprecationWarning,
-            )
-            original_preprocess = dev.preprocess
-            new_preprocess = _create_decomp_preprocessing(custom_decomps, dev)
-
-            try:
-                dev.preprocess = new_preprocess
-                yield
-
-            finally:
-                dev.preprocess = original_preprocess
+        override_method = (
+            "preprocess_transforms"
+            if type(dev).preprocess == qml.devices.Device.preprocess
+            else "preprocess"
+        )
+
+        original_method = getattr(dev, override_method)
+
+        new_method = _create_decomp_preprocessing(custom_decomps, dev, override_method)
+        try:
+            setattr(dev, override_method, new_method)
+            yield
+
+        finally:
+            setattr(dev, override_method, original_method)
diff --git a/pennylane/workflow/_setup_transform_program.py b/pennylane/workflow/_setup_transform_program.py
index ffa570227..fd1ba0c3c 100644
--- a/pennylane/workflow/_setup_transform_program.py
+++ b/pennylane/workflow/_setup_transform_program.py
@@ -13,7 +13,6 @@
 # limitations under the License.
 """Contains a function for setting up the inner and outer transform programs for execution of a QNode."""
 
-import warnings
 
 from cachetools import LRUCache
 
@@ -48,21 +47,10 @@ def _prune_dynamic_transform(outer_transform, inner_transform):
     inner_contains_one_shot = inner_transform.prune_dynamic_transform(type_to_keep)
     if inner_contains_one_shot:
         type_to_keep = 0
-    original_len = len(outer_transform)
     outer_transform.prune_dynamic_transform(type_to_keep)
-    outer_contained_one_shot = len(outer_transform) < original_len
-    if inner_contains_one_shot and outer_contained_one_shot:
-        warnings.warn(
-            "A dynamic_one_shot transform already exists in the preprocessing program of the "
-            "device. Therefore, the dynamic_one_shot applied on the qnode will be ignored. "
-            "See https://docs.pennylane.ai/en/stable/code/api/pennylane.dynamic_one_shot.html "
-            "for more information on the recommended way to use dynamic_one_shot.",
-            UserWarning,
-        )
 
 
 def _setup_transform_program(
-    user_transform_program: TransformProgram,
     device: "qml.devices.Device",
     resolved_execution_config: "qml.devices.ExecutionConfig",
     cache=None,
@@ -84,24 +72,22 @@ def _setup_transform_program(
 
     device_transform_program = device.preprocess_transforms(resolved_execution_config)
 
-    full_transform_program = qml.transforms.core.TransformProgram(
-        user_transform_program, cotransform_cache=user_transform_program.cotransform_cache
-    )
+    outer_transform_program = qml.transforms.core.TransformProgram()
     inner_transform_program = qml.transforms.core.TransformProgram()
 
     # Add the gradient expand to the program if necessary
     if getattr(resolved_execution_config.gradient_method, "expand_transform", False):
-        full_transform_program.add_transform(
+        outer_transform_program.add_transform(
             qml.transform(resolved_execution_config.gradient_method.expand_transform),
             **resolved_execution_config.gradient_keyword_arguments,
         )
     if resolved_execution_config.use_device_gradient:
-        full_transform_program += device_transform_program
+        outer_transform_program += device_transform_program
     else:
         inner_transform_program += device_transform_program
 
     # Making sure dynamic_one_shot occurs at most once between the inner and outer transform programs
-    _prune_dynamic_transform(full_transform_program, inner_transform_program)
+    _prune_dynamic_transform(outer_transform_program, inner_transform_program)
 
     # If caching is desired but an explicit cache is not provided, use an ``LRUCache``.
     if cache is True:
@@ -123,4 +109,4 @@ def _setup_transform_program(
     if cache is not None:
         inner_transform_program.add_transform(_cache_transform, cache=cache)
 
-    return full_transform_program, inner_transform_program
+    return outer_transform_program, inner_transform_program
diff --git a/pennylane/workflow/construct_execution_config.py b/pennylane/workflow/construct_execution_config.py
index 4b0577501..c5dcaccf4 100644
--- a/pennylane/workflow/construct_execution_config.py
+++ b/pennylane/workflow/construct_execution_config.py
@@ -17,7 +17,6 @@ import functools
 import pennylane as qml
 from pennylane.math import Interface
 
-from .construct_tape import construct_tape
 from .resolution import _resolve_execution_config
 
 
@@ -102,13 +101,17 @@ def construct_execution_config(qnode: "qml.QNode", resolve: bool = True):
             gradient_keyword_arguments=qnode.gradient_kwargs,
             mcm_config=mcm_config,
         )
-
         if resolve:
-            tape = construct_tape(qnode, level=0)(*args, **kwargs)
-            # pylint:disable=protected-access
-            config = _resolve_execution_config(
-                config, qnode.device, (tape,), qnode._transform_program
-            )
+            if type(qnode).__name__ == "TorchLayer":
+                # avoid triggering import of torch if its not needed.
+                x = args[0]
+                kwargs = {
+                    **{arg: weight.to(x) for arg, weight in qnode.qnode_weights.items()},
+                }
+            shots = kwargs.pop("shots", None)
+            tape = qml.tape.make_qscript(qnode.func, shots=shots)(*args, **kwargs)
+            batch, _ = qnode.transform_program((tape,))
+            config = _resolve_execution_config(config, qnode.device, batch)
 
         return config
 
diff --git a/pennylane/workflow/execution.py b/pennylane/workflow/execution.py
index d39ff6a6d..d5099fa5f 100644
--- a/pennylane/workflow/execution.py
+++ b/pennylane/workflow/execution.py
@@ -186,7 +186,16 @@ def execute(
     if not tapes:
         return ()
 
-    ### Specifying and preprocessing variables ####
+    ### Apply the user transforms ####
+    transform_program = transform_program or TransformProgram()
+    tapes, user_post_processing = transform_program(tapes)
+    if transform_program.is_informative:
+        return user_post_processing(tapes)
+
+    if not tapes:
+        return user_post_processing(())
+
+    ### Specifying and preprocessing variables ###
 
     interface = _resolve_interface(interface, tapes)
 
@@ -200,18 +209,14 @@ def execute(
         derivative_order=max_diff,
         executor_backend=executor_backend,
     )
-    config = _resolve_execution_config(config, device, tapes, transform_program=transform_program)
+    config = _resolve_execution_config(config, device, tapes)
 
-    transform_program = transform_program or qml.transforms.core.TransformProgram()
-    transform_program, inner_transform = _setup_transform_program(
-        transform_program, device, config, cache, cachesize
-    )
+    outer_transform, inner_transform = _setup_transform_program(device, config, cache, cachesize)
 
     #### Executing the configured setup #####
-    tapes, post_processing = transform_program(tapes)
+    tapes, outer_post_processing = outer_transform(tapes)
 
-    if transform_program.is_informative:
-        return post_processing(tapes)
+    assert not outer_transform.is_informative, "should only contain device preprocessing"
 
     results = run(tapes, device, config, inner_transform)
-    return post_processing(results)
+    return user_post_processing(outer_post_processing(results))
diff --git a/pennylane/workflow/resolution.py b/pennylane/workflow/resolution.py
index 7796d49f1..6b0f04a36 100644
--- a/pennylane/workflow/resolution.py
+++ b/pennylane/workflow/resolution.py
@@ -17,7 +17,7 @@ from copy import copy
 from dataclasses import replace
 from importlib.metadata import version
 from importlib.util import find_spec
-from typing import Literal, Optional, Union, get_args
+from typing import Literal, Union, get_args
 from warnings import warn
 
 from packaging.version import Version
@@ -27,7 +27,7 @@ from pennylane.exceptions import QuantumFunctionError
 from pennylane.logging import debug_logger
 from pennylane.math import Interface, get_canonical_interface_name, get_interface
 from pennylane.tape import QuantumScriptBatch
-from pennylane.transforms.core import TransformDispatcher, TransformProgram
+from pennylane.transforms.core import TransformDispatcher
 
 SupportedDiffMethods = Literal[
     None,
@@ -269,7 +269,6 @@ def _resolve_execution_config(
     execution_config: "qml.devices.ExecutionConfig",
     device: "qml.devices.Device",
     tapes: QuantumScriptBatch,
-    transform_program: Optional[TransformProgram] = None,
 ) -> "qml.devices.ExecutionConfig":
     """Resolves the execution configuration for non-device specific properties.
 
@@ -277,7 +276,6 @@ def _resolve_execution_config(
         execution_config (qml.devices.ExecutionConfig): an execution config to be executed on the device
         device (qml.devices.Device): a Pennylane device
         tapes (QuantumScriptBatch): a batch of tapes
-        transform_program (TransformProgram): a program of transformations to be applied to the tapes
 
     Returns:
         qml.devices.ExecutionConfig: resolved execution configuration
@@ -288,14 +286,6 @@ def _resolve_execution_config(
         execution_config.gradient_method, Callable
     ):
         updated_values["grad_on_execution"] = False
-
-    if (
-        "lightning" in device.name
-        and transform_program
-        and qml.metric_tensor in transform_program
-        and execution_config.gradient_method == "best"
-    ):
-        execution_config = replace(execution_config, gradient_method=qml.gradients.param_shift)
     execution_config = _resolve_diff_method(execution_config, device, tape=tapes[0])
 
     if execution_config.use_device_jacobian_product and not device.supports_vjp(


Test patch:
diff --git a/tests/gradients/core/test_hadamard_gradient.py b/tests/gradients/core/test_hadamard_gradient.py
index bc436a758..9d98c5445 100755
--- a/tests/gradients/core/test_hadamard_gradient.py
+++ b/tests/gradients/core/test_hadamard_gradient.py
@@ -871,7 +871,7 @@ class TestHadamardGrad:
         (cost4, [4, 3], np.ndarray),
         (cost5, [4, 3], list),
         (cost6, [2, 4, 3], tuple),
-        (cost10, [32, 3], np.ndarray),  # Note that the shape here depends on the device
+        (cost10, [8, 3], np.ndarray),  # Note that the shape here depends on the device
         (cost11, [2, 32, 3], tuple),
         (cost12, [8, 3], np.ndarray),
     ]
@@ -882,7 +882,7 @@ class TestHadamardGrad:
     @pytest.mark.parametrize("cost, exp_shape, exp_type", costs_and_expected_probs)
     def test_output_shape_matches_qnode_probs(self, cost, exp_shape, exp_type, mode):
         """Test that the transform output shape matches that of the QNode."""
-        dev = qml.device("default.qubit", wires=5)
+        dev = qml.device("default.qubit", wires=6)
 
         x = np.random.rand(3)
         circuit = qml.QNode(cost, dev)
diff --git a/tests/gradients/core/test_metric_tensor.py b/tests/gradients/core/test_metric_tensor.py
index 18f18b5dd..2b70b0c1d 100644
--- a/tests/gradients/core/test_metric_tensor.py
+++ b/tests/gradients/core/test_metric_tensor.py
@@ -1561,7 +1561,7 @@ def test_raises_circuit_that_uses_missing_wire():
         return qml.expval(qml.PauliZ(0))
 
     x = np.array([1.3, 0.2])
-    with pytest.raises(qml.wires.WireError, match=r"contain wires not found on the device: \{1\}"):
+    with pytest.raises(qml.wires.WireError, match=r"no free wire"):
         qml.metric_tensor(circuit)(x)
 
 
diff --git a/tests/logging/test_logging_autograd.py b/tests/logging/test_logging_autograd.py
index 48861f41e..6dcfba710 100644
--- a/tests/logging/test_logging_autograd.py
+++ b/tests/logging/test_logging_autograd.py
@@ -92,11 +92,11 @@ class TestLogging:
             ),
             (
                 "pennylane.devices.default_qubit",
-                ["Calling <preprocess(self=<default.qubit device (wires=2)"],
+                ["Calling <setup_execution_config(self=<default.qubit device (wires=2)"],
             ),
             (
                 "pennylane.devices.default_qubit",
-                ["Calling <preprocess(self=<default.qubit device (wires=2)"],
+                ["Calling <preprocess_transforms(self=<default.qubit device (wires=2)"],
             ),
         ]
 
diff --git a/tests/param_shift_dev.py b/tests/param_shift_dev.py
index 7c7442161..0496c4435 100644
--- a/tests/param_shift_dev.py
+++ b/tests/param_shift_dev.py
@@ -26,17 +26,20 @@ class ParamShiftDerivativesDevice(qml.devices.DefaultQubit):
 
     name = "param_shift.qubit"
 
-    def preprocess(self, execution_config=qml.devices.DefaultExecutionConfig):
-        if execution_config.gradient_method in {"device", "parameter-shift"}:
-            execution_config = dataclasses.replace(execution_config, use_device_gradient=True)
-            if execution_config.use_device_jacobian_product is None:
-                execution_config = dataclasses.replace(
-                    execution_config, use_device_jacobian_product=True
-                )
-        program, config = super().preprocess(execution_config)
+    def setup_execution_config(self, config=None, circuit=None):
+        config = config or qml.devices.ExecutionConfig()
+        if config.gradient_method in {"device", "parameter-shift"}:
+            config = dataclasses.replace(config, use_device_gradient=True)
+            if config.use_device_jacobian_product is None:
+                config = dataclasses.replace(config, use_device_jacobian_product=True)
+        config = super().setup_execution_config(config, circuit)
         config = dataclasses.replace(config, convert_to_numpy=True)
+        return config
+
+    def preprocess_transforms(self, execution_config=None):
+        program = super().preprocess_transforms(execution_config)
         program.add_transform(qml.transform(qml.gradients.param_shift.expand_transform))
-        return program, config
+        return program
 
     def supports_derivatives(self, execution_config=None, circuit=None):
         if execution_config is None:
diff --git a/tests/resource/test_specs.py b/tests/resource/test_specs.py
index 4d5ca4e4e..8916428cb 100644
--- a/tests/resource/test_specs.py
+++ b/tests/resource/test_specs.py
@@ -206,12 +206,12 @@ class TestSpecsTransform:
                     return False
                 return True
 
-            def preprocess(self, execution_config=qml.devices.DefaultExecutionConfig):
-                program, config = super().preprocess(execution_config)
+            def preprocess_transforms(self, execution_config=qml.devices.DefaultExecutionConfig):
+                program = super().preprocess_transforms(execution_config)
                 program.add_transform(
                     qml.devices.preprocess.decompose, stopping_condition=self.stopping_condition
                 )
-                return program, config
+                return program
 
         dev = TestDevice(wires=2)
         matrix = qml.matrix(qml.RX(1.2, 0))
diff --git a/tests/test_qnode.py b/tests/test_qnode.py
index 98099a899..ceb261d00 100644
--- a/tests/test_qnode.py
+++ b/tests/test_qnode.py
@@ -1858,12 +1858,12 @@ class TestNewDeviceIntegration:
             def supports_derivatives(self, execution_config=None, circuit=None):
                 return getattr(execution_config, "gradient_method", None) == "hello"
 
-            def _setup_execution_config(self, execution_config=qml.devices.DefaultExecutionConfig):
-                if execution_config.gradient_method in {"best", "hello"}:
-                    return replace(
-                        execution_config, gradient_method="hello", use_device_gradient=True
-                    )
-                return execution_config
+            def setup_execution_config(
+                self, config=qml.devices.DefaultExecutionConfig, circuit=None
+            ):
+                if config.gradient_method in {"best", "hello"}:
+                    return replace(config, gradient_method="hello", use_device_gradient=True)
+                return config
 
             def compute_derivatives(
                 self, circuits, execution_config=qml.devices.DefaultExecutionConfig
diff --git a/tests/transforms/test_set_shots.py b/tests/transforms/test_set_shots.py
index 540b82755..058b297fa 100644
--- a/tests/transforms/test_set_shots.py
+++ b/tests/transforms/test_set_shots.py
@@ -131,3 +131,67 @@ class TestSetShots:
         with qml.Tracker(dev) as tracker:
             new_circuit()
         assert tracker.history["shots"][-1] == 20
+
+    @pytest.mark.integration
+    def test_best_diff_method_shots_to_none(self):
+        """Test that we can override a device with shots to analytic with diff_method='best' adjusted."""
+        # Test that when overriding from shots to analytic, backprop is used
+        dev_shots = qml.device("default.qubit", wires=1, shots=100)
+
+        @qml.qnode(dev_shots, diff_method="best")
+        def circuit(x):
+            qml.RX(x, wires=0)
+            return qml.expval(qml.PauliZ(0))
+
+        param = qml.numpy.array(0.5, requires_grad=True)
+
+        # With shots, parameter-shift should be used for gradient
+        with qml.Tracker(dev_shots) as tracker_shots:
+            qml.grad(circuit)(param)
+
+        # Store the history for verification
+        shots_history = tracker_shots.history
+
+        # Parameter-shift rule requires 2*num_params + 1 = 3 executions
+        assert len(shots_history["executions"]) == 3
+
+        # Override to analytic (shots=None) - should switch to backprop/adjoint
+        circuit_analytic = set_shots(circuit, shots=None)
+
+        with qml.Tracker(dev_shots) as tracker_analytic:
+            qml.grad(circuit_analytic)(param)
+
+        # Analytic gradient should require only 1 execution
+        assert len(tracker_analytic.history["executions"]) == 1
+
+    @pytest.mark.integration
+    def test_best_diff_method_none_to_shots(self):
+        """Test that we can override an analytic device with finite shots while using diff_method='best'."""
+        # Start with an analytic device
+        dev_analytic = qml.device("default.qubit", wires=1, shots=None)
+
+        @qml.qnode(dev_analytic, diff_method="best")
+        def circuit(x):
+            qml.RX(x, wires=0)
+            return qml.expval(qml.PauliZ(0))
+
+        param = qml.numpy.array(0.5, requires_grad=True)
+
+        # With analytic device, we expect backprop/adjoint (single execution)
+        with qml.Tracker(dev_analytic) as tracker_analytic:
+            qml.grad(circuit)(param)
+
+        # Store the history for verification
+        analytic_history = tracker_analytic.history
+
+        # Analytic gradient should require only 1 execution
+        assert len(analytic_history["executions"]) == 1
+
+        # Override to finite shots - should switch to parameter-shift
+        circuit_with_shots = set_shots(circuit, shots=100)
+
+        with qml.Tracker(dev_analytic) as tracker_shots:
+            qml.grad(circuit_with_shots)(param)
+
+        # Parameter-shift rule requires 2*num_params + 1 = 3 executions
+        assert len(tracker_shots.history["executions"]) == 3
diff --git a/tests/transforms/test_tape_expand.py b/tests/transforms/test_tape_expand.py
index f7b33c8f1..ec21d88e5 100644
--- a/tests/transforms/test_tape_expand.py
+++ b/tests/transforms/test_tape_expand.py
@@ -31,6 +31,19 @@ def crit_0(op: qml.operation.Operator):
     )
 
 
+class PreprocessDevice(qml.devices.Device):
+
+    def __init__(self, wires=None, shots=None):
+        self.target_dev = qml.devices.DefaultQubit(wires=wires, shots=shots)
+        super().__init__(wires=wires, shots=shots)
+
+    def preprocess(self, execution_config=None):
+        return self.target_dev.preprocess(execution_config)
+
+    def execute(self, circuits, execution_config=None):
+        return self.target_dev.execute(circuits, execution_config)
+
+
 class TestCreateExpandFn:
     """Test creating expansion functions from stopping criteria."""
 
@@ -785,12 +798,11 @@ class TestCreateCustomDecompExpandFn:
         assert ops[0].name == "CNOT"
         assert dev.custom_expand_fn is None
 
-    def test_custom_decomp_in_separate_context(self, mocker):
+    @pytest.mark.parametrize("device", (qml.devices.DefaultQubit, PreprocessDevice))
+    def test_custom_decomp_in_separate_context(self, mocker, device):
         """Test that the set_decomposition context manager works for the new device API."""
 
-        # pylint:disable=protected-access
-
-        dev = qml.device("default.qubit", wires=2)
+        dev = device(wires=2)
         spy = mocker.spy(dev, "execute")
 
         @qml.qnode(dev)
diff --git a/tests/workflow/interfaces/run/test_autograd_run.py b/tests/workflow/interfaces/run/test_autograd_run.py
index f5bfe50f2..bf0e29224 100644
--- a/tests/workflow/interfaces/run/test_autograd_run.py
+++ b/tests/workflow/interfaces/run/test_autograd_run.py
@@ -25,7 +25,6 @@ from conftest import atol_for_shots, get_device, test_matrix
 
 import pennylane as qml
 from pennylane import numpy as pnp
-from pennylane.transforms.core import TransformProgram
 from pennylane.workflow import _resolve_execution_config, _setup_transform_program, run
 
 
@@ -46,10 +45,8 @@ class TestAutogradRun:
             ops2 = [qml.RY(a, wires="a"), qml.RX(b, wires="a")]
             tape2 = qml.tape.QuantumScript(ops2, [qml.expval(qml.PauliZ("a"))], shots=shots)
 
-            resolved_config = _resolve_execution_config(
-                config, device, [tape1, tape2], TransformProgram()
-            )
-            inner_tp = _setup_transform_program(TransformProgram(), device, resolved_config)[1]
+            resolved_config = _resolve_execution_config(config, device, [tape1, tape2])
+            inner_tp = _setup_transform_program(device, resolved_config)[1]
             return run([tape1, tape2], device, resolved_config, inner_tp)
 
         a = pnp.array(0.1, requires_grad=True)
@@ -80,8 +77,8 @@ class TestAutogradRun:
 
         def cost(a):
             tape = qml.tape.QuantumScript([qml.RY(a, 0)], [qml.expval(qml.PauliZ(0))], shots=shots)
-            resolved_config = _resolve_execution_config(config, device, [tape], TransformProgram())
-            inner_tp = _setup_transform_program(TransformProgram(), device, resolved_config)[1]
+            resolved_config = _resolve_execution_config(config, device, [tape])
+            inner_tp = _setup_transform_program(device, resolved_config)[1]
             return run([tape], device, resolved_config, inner_tp)[0]
 
         a = pnp.array(0.1, requires_grad=True)
@@ -106,8 +103,8 @@ class TestAutogradRun:
             ops = [qml.RY(a, wires=0), qml.RX(b, wires=1), qml.CNOT(wires=[0, 1])]
             m = [qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliY(1))]
             tape = qml.tape.QuantumScript(ops, m, shots=shots)
-            resolved_config = _resolve_execution_config(config, device, [tape], TransformProgram())
-            inner_tp = _setup_transform_program(TransformProgram(), device, resolved_config)[1]
+            resolved_config = _resolve_execution_config(config, device, [tape])
+            inner_tp = _setup_transform_program(device, resolved_config)[1]
             return autograd.numpy.hstack(run([tape], device, resolved_config, inner_tp)[0])
 
         a = pnp.array(0.1, requires_grad=True)
diff --git a/tests/workflow/interfaces/run/test_jax_jit_run.py b/tests/workflow/interfaces/run/test_jax_jit_run.py
index 85f7fa894..a77c8b3a1 100644
--- a/tests/workflow/interfaces/run/test_jax_jit_run.py
+++ b/tests/workflow/interfaces/run/test_jax_jit_run.py
@@ -23,7 +23,6 @@ import pytest
 from conftest import atol_for_shots, get_device, test_matrix
 
 import pennylane as qml
-from pennylane.transforms.core import TransformProgram
 from pennylane.workflow import _resolve_execution_config, _setup_transform_program, run
 
 jax = pytest.importorskip("jax")
@@ -53,10 +52,8 @@ class TestJaxJitRun:
             ops2 = [qml.RY(a, wires="a"), qml.RX(b, wires="a")]
             tape2 = qml.tape.QuantumScript(ops2, [qml.expval(qml.PauliZ("a"))], shots=shots)
 
-            resolved_config = _resolve_execution_config(
-                config, device, [tape1, tape2], TransformProgram()
-            )
-            inner_tp = _setup_transform_program(TransformProgram(), device, resolved_config)[1]
+            resolved_config = _resolve_execution_config(config, device, [tape1, tape2])
+            inner_tp = _setup_transform_program(device, resolved_config)[1]
             return run([tape1, tape2], device, resolved_config, inner_tp)
 
         a = jnp.array(0.1)
@@ -87,8 +84,8 @@ class TestJaxJitRun:
 
         def cost(a):
             tape = qml.tape.QuantumScript([qml.RY(a, 0)], [qml.expval(qml.PauliZ(0))], shots=shots)
-            resolved_config = _resolve_execution_config(config, device, [tape], TransformProgram())
-            inner_tp = _setup_transform_program(TransformProgram(), device, resolved_config)[1]
+            resolved_config = _resolve_execution_config(config, device, [tape])
+            inner_tp = _setup_transform_program(device, resolved_config)[1]
             return run([tape], device, resolved_config, inner_tp)[0]
 
         a = jnp.array(0.1)
@@ -112,8 +109,8 @@ class TestJaxJitRun:
             m = [qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliY(1))]
             tape = qml.tape.QuantumScript(ops, m, shots=shots)
 
-            resolved_config = _resolve_execution_config(config, device, [tape], TransformProgram())
-            inner_tp = _setup_transform_program(TransformProgram(), device, resolved_config)[1]
+            resolved_config = _resolve_execution_config(config, device, [tape])
+            inner_tp = _setup_transform_program(device, resolved_config)[1]
             return run([tape], device, resolved_config, inner_tp)[0]
 
         a = jnp.array(0.1)
diff --git a/tests/workflow/interfaces/run/test_jax_run.py b/tests/workflow/interfaces/run/test_jax_run.py
index 6dfd7a0da..6e8aec9d3 100644
--- a/tests/workflow/interfaces/run/test_jax_run.py
+++ b/tests/workflow/interfaces/run/test_jax_run.py
@@ -23,7 +23,6 @@ import pytest
 from conftest import atol_for_shots, get_device, test_matrix
 
 import pennylane as qml
-from pennylane.transforms.core import TransformProgram
 from pennylane.workflow import _resolve_execution_config, _setup_transform_program, run
 
 jax = pytest.importorskip("jax")
@@ -48,10 +47,8 @@ class TestJaxRun:
             ops2 = [qml.RY(a, wires="a"), qml.RX(b, wires="a")]
             tape2 = qml.tape.QuantumScript(ops2, [qml.expval(qml.PauliZ("a"))], shots=shots)
 
-            resolved_config = _resolve_execution_config(
-                config, device, [tape1, tape2], TransformProgram()
-            )
-            inner_tp = _setup_transform_program(TransformProgram(), device, resolved_config)[1]
+            resolved_config = _resolve_execution_config(config, device, [tape1, tape2])
+            inner_tp = _setup_transform_program(device, resolved_config)[1]
             return run([tape1, tape2], device, resolved_config, inner_tp)
 
         a = jnp.array(0.1)
@@ -82,8 +79,8 @@ class TestJaxRun:
 
         def cost(a):
             tape = qml.tape.QuantumScript([qml.RY(a, 0)], [qml.expval(qml.PauliZ(0))], shots=shots)
-            resolved_config = _resolve_execution_config(config, device, [tape], TransformProgram())
-            inner_tp = _setup_transform_program(TransformProgram(), device, resolved_config)[1]
+            resolved_config = _resolve_execution_config(config, device, [tape])
+            inner_tp = _setup_transform_program(device, resolved_config)[1]
             return run([tape], device, resolved_config, inner_tp)[0]
 
         a = jnp.array(0.1)
@@ -107,8 +104,8 @@ class TestJaxRun:
             m = [qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliY(1))]
             tape = qml.tape.QuantumScript(ops, m, shots=shots)
 
-            resolved_config = _resolve_execution_config(config, device, [tape], TransformProgram())
-            inner_tp = _setup_transform_program(TransformProgram(), device, resolved_config)[1]
+            resolved_config = _resolve_execution_config(config, device, [tape])
+            inner_tp = _setup_transform_program(device, resolved_config)[1]
             return run([tape], device, resolved_config, inner_tp)[0]
 
         a = jnp.array(0.1)
diff --git a/tests/workflow/interfaces/run/test_tensorflow_autograph_run.py b/tests/workflow/interfaces/run/test_tensorflow_autograph_run.py
index c106f668a..070bb0ed9 100644
--- a/tests/workflow/interfaces/run/test_tensorflow_autograph_run.py
+++ b/tests/workflow/interfaces/run/test_tensorflow_autograph_run.py
@@ -24,7 +24,6 @@ from conftest import atol_for_shots, get_device, test_matrix
 
 import pennylane as qml
 from pennylane.tape import QuantumScript
-from pennylane.transforms.core import TransformProgram
 from pennylane.workflow import _resolve_execution_config, _setup_transform_program, run
 
 tf = pytest.importorskip("tensorflow")
@@ -42,9 +41,7 @@ class TestTFAutographRun:
 
         device = get_device(device, seed=seed)
         config = replace(config, interface="tf-autograph")
-        resolved_config = _resolve_execution_config(
-            config, device, [QuantumScript()], TransformProgram()
-        )
+        resolved_config = _resolve_execution_config(config, device, [QuantumScript()])
 
         def cost(a, b):
             ops1 = [qml.RY(a, wires=0), qml.RX(b, wires=0)]
@@ -53,10 +50,8 @@ class TestTFAutographRun:
             ops2 = [qml.RY(a, wires="a"), qml.RX(b, wires="a")]
             tape2 = qml.tape.QuantumScript(ops2, [qml.expval(qml.PauliZ("a"))], shots=shots)
 
-            resolved_config = _resolve_execution_config(
-                config, device, [tape1, tape2], TransformProgram()
-            )
-            inner_tp = _setup_transform_program(TransformProgram(), device, resolved_config)[1]
+            resolved_config = _resolve_execution_config(config, device, [tape1, tape2])
+            inner_tp = _setup_transform_program(device, resolved_config)[1]
             return run([tape1, tape2], device, resolved_config, inner_tp)
 
         a = tf.Variable(0.1, dtype="float64")
@@ -86,15 +81,13 @@ class TestTFAutographRun:
             pytest.xfail(reason="Partitioned shots are not supported yet.")
         device = get_device(device, seed=seed)
         config = replace(config, interface="tf-autograph")
-        resolved_config = _resolve_execution_config(
-            config, device, [QuantumScript()], TransformProgram()
-        )
+        resolved_config = _resolve_execution_config(config, device, [QuantumScript()])
         device_vjp = resolved_config.use_device_jacobian_product
 
         def cost(a):
             tape = qml.tape.QuantumScript([qml.RY(a, 0)], [qml.expval(qml.PauliZ(0))], shots=shots)
-            resolved_config = _resolve_execution_config(config, device, [tape], TransformProgram())
-            inner_tp = _setup_transform_program(TransformProgram(), device, resolved_config)[1]
+            resolved_config = _resolve_execution_config(config, device, [tape])
+            inner_tp = _setup_transform_program(device, resolved_config)[1]
             return run([tape], device, resolved_config, inner_tp)[0]
 
         a = tf.Variable(0.1, dtype=tf.float64)
@@ -118,17 +111,15 @@ class TestTFAutographRun:
 
         config = replace(config, interface="tf-autograph")
         device = get_device(device, seed=seed)
-        resolved_config = _resolve_execution_config(
-            config, device, [QuantumScript()], TransformProgram()
-        )
+        resolved_config = _resolve_execution_config(config, device, [QuantumScript()])
         device_vjp = resolved_config.use_device_jacobian_product
 
         def cost(a, b):
             ops = [qml.RY(a, wires=0), qml.RX(b, wires=1), qml.CNOT(wires=[0, 1])]
             m = [qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliY(1))]
             tape = qml.tape.QuantumScript(ops, m, shots=shots)
-            resolved_config = _resolve_execution_config(config, device, [tape], TransformProgram())
-            inner_tp = _setup_transform_program(TransformProgram(), device, resolved_config)[1]
+            resolved_config = _resolve_execution_config(config, device, [tape])
+            inner_tp = _setup_transform_program(device, resolved_config)[1]
             return qml.math.hstack(
                 run([tape], device, resolved_config, inner_tp)[0], like="tensorflow"
             )
diff --git a/tests/workflow/interfaces/run/test_tensorflow_run.py b/tests/workflow/interfaces/run/test_tensorflow_run.py
index 0114b6601..295145a4a 100644
--- a/tests/workflow/interfaces/run/test_tensorflow_run.py
+++ b/tests/workflow/interfaces/run/test_tensorflow_run.py
@@ -24,7 +24,6 @@ from conftest import atol_for_shots, get_device, test_matrix
 
 import pennylane as qml
 from pennylane.tape import QuantumScript
-from pennylane.transforms.core import TransformProgram
 from pennylane.workflow import _resolve_execution_config, _setup_transform_program, run
 
 tf = pytest.importorskip("tensorflow")
@@ -39,9 +38,7 @@ class TestTensorFlowRun:
         """Test execution of tapes on 'tensorflow' interface."""
         device = get_device(device, seed=seed)
         config = replace(config, interface="tensorflow")
-        resolved_config = _resolve_execution_config(
-            config, device, [QuantumScript()], TransformProgram()
-        )
+        resolved_config = _resolve_execution_config(config, device, [QuantumScript()])
 
         def cost(a, b):
             ops1 = [qml.RY(a, wires=0), qml.RX(b, wires=0)]
@@ -50,11 +47,8 @@ class TestTensorFlowRun:
             ops2 = [qml.RY(a, wires="a"), qml.RX(b, wires="a")]
             tape2 = qml.tape.QuantumScript(ops2, [qml.expval(qml.PauliZ("a"))], shots=shots)
 
-            resolved_config = _resolve_execution_config(
-                config, device, [tape1, tape2], TransformProgram()
-            )
-            print(resolved_config.use_device_jacobian_product)
-            inner_tp = _setup_transform_program(TransformProgram(), device, resolved_config)[1]
+            resolved_config = _resolve_execution_config(config, device, [tape1, tape2])
+            inner_tp = _setup_transform_program(device, resolved_config)[1]
             return run([tape1, tape2], device, resolved_config, inner_tp)
 
         a = tf.Variable(0.1, dtype="float64")
@@ -87,15 +81,13 @@ class TestTensorFlowRun:
             pytest.xfail(reason="Partitioned shots are not supported yet.")
         device = get_device(device, seed=seed)
         config = replace(config, interface="tensorflow")
-        resolved_config = _resolve_execution_config(
-            config, device, [QuantumScript()], TransformProgram()
-        )
+        resolved_config = _resolve_execution_config(config, device, [QuantumScript()])
         device_vjp = resolved_config.use_device_jacobian_product
 
         def cost(a):
             tape = qml.tape.QuantumScript([qml.RY(a, 0)], [qml.expval(qml.PauliZ(0))], shots=shots)
-            resolved_config = _resolve_execution_config(config, device, [tape], TransformProgram())
-            inner_tp = _setup_transform_program(TransformProgram(), device, resolved_config)[1]
+            resolved_config = _resolve_execution_config(config, device, [tape])
+            inner_tp = _setup_transform_program(device, resolved_config)[1]
             return run([tape], device, resolved_config, inner_tp)[0]
 
         a = tf.Variable(0.1, dtype=tf.float64)
@@ -117,17 +109,15 @@ class TestTensorFlowRun:
 
         device = get_device(device, seed=seed)
         config = replace(config, interface="tensorflow")
-        resolved_config = _resolve_execution_config(
-            config, device, [QuantumScript()], TransformProgram()
-        )
+        resolved_config = _resolve_execution_config(config, device, [QuantumScript()])
         device_vjp = resolved_config.use_device_jacobian_product
 
         def cost(a, b):
             ops = [qml.RY(a, wires=0), qml.RX(b, wires=1), qml.CNOT(wires=[0, 1])]
             m = [qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliY(1))]
             tape = qml.tape.QuantumScript(ops, m, shots=shots)
-            resolved_config = _resolve_execution_config(config, device, [tape], TransformProgram())
-            inner_tp = _setup_transform_program(TransformProgram(), device, resolved_config)[1]
+            resolved_config = _resolve_execution_config(config, device, [tape])
+            inner_tp = _setup_transform_program(device, resolved_config)[1]
             return qml.math.hstack(
                 run([tape], device, resolved_config, inner_tp)[0], like="tensorflow"
             )
diff --git a/tests/workflow/interfaces/run/test_torch_run.py b/tests/workflow/interfaces/run/test_torch_run.py
index 1da6f17ff..919f7120b 100644
--- a/tests/workflow/interfaces/run/test_torch_run.py
+++ b/tests/workflow/interfaces/run/test_torch_run.py
@@ -22,7 +22,6 @@ import pytest
 from conftest import atol_for_shots, get_device, test_matrix
 
 import pennylane as qml
-from pennylane.transforms.core import TransformProgram
 from pennylane.workflow import _resolve_execution_config, _setup_transform_program, run
 
 torch = pytest.importorskip("torch")
@@ -51,10 +50,8 @@ class TestTorchRun:
             ops2 = [qml.RY(a, wires="a"), qml.RX(b, wires="a")]
             tape2 = qml.tape.QuantumScript(ops2, [qml.expval(qml.PauliZ("a"))], shots=shots)
 
-            resolved_config = _resolve_execution_config(
-                config, device, [tape1, tape2], TransformProgram()
-            )
-            inner_tp = _setup_transform_program(TransformProgram(), device, resolved_config)[1]
+            resolved_config = _resolve_execution_config(config, device, [tape1, tape2])
+            inner_tp = _setup_transform_program(device, resolved_config)[1]
             return run([tape1, tape2], device, resolved_config, inner_tp)
 
         a = torch.tensor(0.1, requires_grad=True)
@@ -91,8 +88,8 @@ class TestTorchRun:
 
         def cost(a):
             tape = qml.tape.QuantumScript([qml.RY(a, 0)], [qml.expval(qml.PauliZ(0))], shots=shots)
-            resolved_config = _resolve_execution_config(config, device, [tape], TransformProgram())
-            _, inner_tp = _setup_transform_program(TransformProgram(), device, resolved_config)
+            resolved_config = _resolve_execution_config(config, device, [tape])
+            _, inner_tp = _setup_transform_program(device, resolved_config)
             return run([tape], device, resolved_config, inner_tp)[0]
 
         a = torch.tensor(0.1, requires_grad=True)
@@ -122,8 +119,8 @@ class TestTorchRun:
             m = [qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliY(1))]
             tape = qml.tape.QuantumScript(ops, m, shots=shots)
 
-            resolved_config = _resolve_execution_config(config, device, [tape], TransformProgram())
-            _, inner_tp = _setup_transform_program(TransformProgram(), device, resolved_config)
+            resolved_config = _resolve_execution_config(config, device, [tape])
+            _, inner_tp = _setup_transform_program(device, resolved_config)
             res = run([tape], device, resolved_config, inner_tp)[0]
 
             if shots.has_partitioned_shots:
diff --git a/tests/workflow/test_resolve_execution_config.py b/tests/workflow/test_resolve_execution_config.py
index 7ba5de6d9..4b6b2a039 100644
--- a/tests/workflow/test_resolve_execution_config.py
+++ b/tests/workflow/test_resolve_execution_config.py
@@ -19,7 +19,6 @@ import pytest
 import pennylane as qml
 from pennylane.devices import ExecutionConfig, MCMConfig
 from pennylane.exceptions import QuantumFunctionError
-from pennylane.transforms.core import TransformProgram
 from pennylane.workflow.resolution import _resolve_execution_config
 
 
@@ -29,9 +28,8 @@ def test_resolve_execution_config_with_gradient_method():
     device = qml.device("default.qubit")
 
     empty_tape = qml.tape.QuantumScript([], [qml.expval(qml.Z(0))])
-    empty_tp = TransformProgram()
 
-    resolved_config = _resolve_execution_config(execution_config, device, [empty_tape], empty_tp)
+    resolved_config = _resolve_execution_config(execution_config, device, [empty_tape])
 
     assert resolved_config.gradient_method == "backprop"
 
@@ -44,13 +42,10 @@ def test_metric_tensor_lightning_edge_case():
     device = qml.device("lightning.qubit", wires=2)
 
     empty_tape = qml.tape.QuantumScript([], [qml.expval(qml.Z(0))])
-    metric_tensor_tp = TransformProgram([qml.metric_tensor])
 
-    resolved_config = _resolve_execution_config(
-        execution_config, device, [empty_tape], metric_tensor_tp
-    )
+    resolved_config = _resolve_execution_config(execution_config, device, [empty_tape])
 
-    assert resolved_config.gradient_method is qml.gradients.param_shift
+    assert resolved_config.gradient_method == "adjoint"
 
 
 def test_param_shift_cv_kwargs():
@@ -58,9 +53,8 @@ def test_param_shift_cv_kwargs():
     dev = qml.device("default.gaussian", wires=1)
     tape = qml.tape.QuantumScript([qml.Displacement(0.5, 0.0, wires=0)])
     execution_config = ExecutionConfig(gradient_method="parameter-shift")
-    empty_tp = TransformProgram()
 
-    resolved_config = _resolve_execution_config(execution_config, dev, [tape], empty_tp)
+    resolved_config = _resolve_execution_config(execution_config, dev, [tape])
 
     assert resolved_config.gradient_keyword_arguments["dev"] == dev
 
@@ -72,9 +66,8 @@ def test_mcm_config_validation():
     device = qml.device("default.qubit")
 
     empty_tape = qml.tape.QuantumScript([], [qml.expval(qml.Z(0))])
-    empty_tp = TransformProgram()
 
-    resolved_config = _resolve_execution_config(execution_config, device, [empty_tape], empty_tp)
+    resolved_config = _resolve_execution_config(execution_config, device, [empty_tape])
 
     expected_mcm_config = MCMConfig(postselect_mode=None)
 
@@ -91,11 +84,8 @@ def test_jax_interface(mcm_method, postselect_mode):
     device = qml.device("default.qubit")
 
     tape_with_finite_shots = qml.tape.QuantumScript([], [qml.expval(qml.Z(0))], shots=100)
-    empty_tp = TransformProgram()
 
-    resolved_config = _resolve_execution_config(
-        execution_config, device, [tape_with_finite_shots], empty_tp
-    )
+    resolved_config = _resolve_execution_config(execution_config, device, [tape_with_finite_shots])
 
     expected_mcm_config = MCMConfig(mcm_method, postselect_mode="pad-invalid-samples")
 
@@ -110,9 +100,8 @@ def test_jax_jit_interface():
     device = qml.device("default.qubit")
 
     empty_tape = qml.tape.QuantumScript([], [qml.expval(qml.Z(0))])
-    empty_tp = TransformProgram()
 
-    resolved_config = _resolve_execution_config(execution_config, device, [empty_tape], empty_tp)
+    resolved_config = _resolve_execution_config(execution_config, device, [empty_tape])
 
     expected_mcm_config = MCMConfig(mcm_method="deferred", postselect_mode="fill-shots")
 
diff --git a/tests/workflow/test_setup_transform_program.py b/tests/workflow/test_setup_transform_program.py
index 20f209d43..c03a7749c 100644
--- a/tests/workflow/test_setup_transform_program.py
+++ b/tests/workflow/test_setup_transform_program.py
@@ -15,10 +15,8 @@
 
 from unittest.mock import MagicMock
 
-import pytest
-
 import pennylane as qml
-from pennylane.devices import ExecutionConfig, MCMConfig
+from pennylane.devices import ExecutionConfig
 from pennylane.transforms.core import TransformProgram
 from pennylane.workflow._setup_transform_program import (
     _prune_dynamic_transform,
@@ -50,11 +48,9 @@ def test_gradient_expand_transform():
 
     device = qml.device("default.qubit")
 
-    container = qml.transforms.core.TransformContainer(mock_user_transform)
-    user_tp = qml.transforms.core.TransformProgram((container,))
-    full_tp, _ = _setup_transform_program(user_tp, device, config)
+    full_tp, _ = _setup_transform_program(device, config)
 
-    assert repr(full_tp) == "TransformProgram(mock_user_transform, _expand_transform_param_shift)"
+    assert repr(full_tp) == "TransformProgram(_expand_transform_param_shift)"
 
 
 def test_device_transform_program():
@@ -67,15 +63,14 @@ def test_device_transform_program():
     device = qml.device("default.qubit")
     device.preprocess_transforms = MagicMock(return_value=device_tp)
 
-    user_transform_program = TransformProgram()
-    full_tp, inner_tp = _setup_transform_program(user_transform_program, device, config)
+    full_tp, inner_tp = _setup_transform_program(device, config)
 
     assert repr(full_tp) == "TransformProgram(device_transform)"
     assert inner_tp.is_empty()
 
     config.use_device_gradient = False
 
-    full_tp, inner_tp = _setup_transform_program(user_transform_program, device, config)
+    full_tp, inner_tp = _setup_transform_program(device, config)
 
     assert full_tp.is_empty()
     assert repr(inner_tp) == "TransformProgram(device_transform)"
@@ -126,25 +121,12 @@ def test_prune_dynamic_transform_with_mcm():
     assert len(program2) == 1
 
 
-def test_prune_dynamic_transform_warning_raised():
-    """Tests that a warning raised when a user-applied dynamic-one-shot transform is ignored."""
-
-    user_transform_program = TransformProgram()
-    user_transform_program.add_transform(qml.transforms.dynamic_one_shot)
-    device = qml.device("default.qubit")
-    config = ExecutionConfig(mcm_config=MCMConfig(mcm_method="one-shot"))
-
-    with pytest.warns(UserWarning, match="A dynamic_one_shot transform already exists"):
-        _, __ = _setup_transform_program(user_transform_program, device, config)
-
-
 def test_interface_data_not_supported():
     """Test that convert_to_numpy_parameters transform is correctly added."""
     config = ExecutionConfig(interface="autograd", gradient_method="adjoint")
     device = qml.device("default.qubit")
 
-    user_transform_program = TransformProgram()
-    full_tp, inner_tp = _setup_transform_program(user_transform_program, device, config)
+    full_tp, inner_tp = _setup_transform_program(device, config)
 
     assert full_tp.is_empty()
     assert qml.transforms.convert_to_numpy_parameters in inner_tp
@@ -156,8 +138,7 @@ def test_interface_data_supported():
 
     device = qml.device("default.mixed", wires=1)
 
-    user_transform_program = TransformProgram()
-    _, inner_tp = _setup_transform_program(user_transform_program, device, config)
+    _, inner_tp = _setup_transform_program(device, config)
 
     assert qml.transforms.convert_to_numpy_parameters not in inner_tp
 
@@ -165,8 +146,7 @@ def test_interface_data_supported():
 
     device = qml.device("default.qubit")
 
-    user_transform_program = TransformProgram()
-    _, inner_tp = _setup_transform_program(user_transform_program, device, config)
+    _, inner_tp = _setup_transform_program(device, config)
 
     assert qml.transforms.convert_to_numpy_parameters not in inner_tp
 
@@ -174,8 +154,7 @@ def test_interface_data_supported():
 
     device = qml.device("default.qubit")
 
-    user_transform_program = TransformProgram()
-    _, inner_tp = _setup_transform_program(user_transform_program, device, config)
+    _, inner_tp = _setup_transform_program(device, config)
 
     assert qml.transforms.convert_to_numpy_parameters not in inner_tp
 
@@ -183,7 +162,7 @@ def test_interface_data_supported():
         convert_to_numpy=False, interface="jax", gradient_method=qml.gradients.param_shift
     )
 
-    _, inner_tp = _setup_transform_program(TransformProgram(), device, config)
+    _, inner_tp = _setup_transform_program(device, config)
     assert qml.transforms.convert_to_numpy_parameters not in inner_tp
 
 
@@ -193,15 +172,12 @@ def test_cache_handling():
     device = qml.device("default.qubit")
     device.preprocess_transforms = MagicMock(return_value=TransformProgram())
 
-    user_transform_program = TransformProgram()
-    full_tp, inner_tp = _setup_transform_program(user_transform_program, device, config, cache=True)
+    full_tp, inner_tp = _setup_transform_program(device, config, cache=True)
 
     assert repr(inner_tp) == "TransformProgram(_cache_transform)"
     assert full_tp.is_empty()
 
-    full_tp, inner_tp = _setup_transform_program(
-        user_transform_program, device, config, cache=False
-    )
+    full_tp, inner_tp = _setup_transform_program(device, config, cache=False)
 
     assert full_tp.is_empty()
     assert inner_tp.is_empty()