Repository: PennyLaneAI/pennylane

Issue:
[BUG] Unable to reference some decorated top-lvl functions
### Expected behavior

The syntax
```
func:`~.pennylane.compile`
```
works for referencing any top-level functions in the docs.

### Actual behavior

```
func:`~.pennylane.compile`
```
doesn't include a hyperlink to the related documentation change, likely because `qml.compile` is decorated with `@qfunc_transform`. This behaviour was originally noted with the [`@qml.defer_measurements` transform](https://github.com/PennyLaneAI/pennylane/pull/2211#discussion_r818996929).

### Additional information

Further note, that the documentation pages for such decorated functions also differs in style:
![Screenshot from 2022-03-04 15-06-39](https://user-images.githubusercontent.com/24476053/156834715-847fe2ad-429b-4481-9912-8b658d3773cf.png)
![Screenshot from 2022-03-04 15-06-58](https://user-images.githubusercontent.com/24476053/156834725-bfcd6955-190b-47b9-bf0f-887a84630a55.png)

### Source code

_No response_

### Tracebacks

_No response_

### System information

```shell
Name: PennyLane
Version: 0.22.0.dev0
Summary: PennyLane is a Python quantum machine learning library by Xanadu Inc.
Home-page: https://github.com/XanaduAI/pennylane
Author: 
Author-email: 
License: Apache License 2.0
Location: /home/antal/xanadu/pennylane
Requires: numpy, scipy, networkx, retworkx, autograd, toml, appdirs, semantic_version, autoray, cachetools, pennylane-lightning
Required-by: PennyLane-Lightning, amazon-braket-pennylane-plugin, PennyLane-Orquestra, pennylane-qulacs, PennyLane-Honeywell, PennyLane-AQT, PennyLane-PQ, PennyLane-Forest, PennyLane-qsharp, PennyLane-Qchem, PennyLane-IonQ, PennyLane-SF, PennyLane-Cirq, PennyLane-qiskit
Platform info:           Linux-5.13.0-30-generic-x86_64-with-glibc2.10
Python version:          3.8.5
Numpy version:           1.22.1
Scipy version:           1.7.3
Installed devices:
- default.gaussian (PennyLane-0.22.0.dev0)
- default.mixed (PennyLane-0.22.0.dev0)
- default.qubit (PennyLane-0.22.0.dev0)
- default.qubit.autograd (PennyLane-0.22.0.dev0)
- default.qubit.jax (PennyLane-0.22.0.dev0)
- default.qubit.tf (PennyLane-0.22.0.dev0)
- default.qubit.torch (PennyLane-0.22.0.dev0)
- lightning.qubit (PennyLane-Lightning-0.21.0)
- braket.aws.qubit (amazon-braket-pennylane-plugin-1.5.3)
- braket.local.qubit (amazon-braket-pennylane-plugin-1.5.3)
- orquestra.forest (PennyLane-Orquestra-0.15.0)
- orquestra.ibmq (PennyLane-Orquestra-0.15.0)
- orquestra.qiskit (PennyLane-Orquestra-0.15.0)
- orquestra.qulacs (PennyLane-Orquestra-0.15.0)
- qulacs.simulator (pennylane-qulacs-0.17.0.dev0)
- honeywell.hqs (PennyLane-Honeywell-0.16.0.dev0)
- aqt.noisy_sim (PennyLane-AQT-0.18.0)
- aqt.sim (PennyLane-AQT-0.18.0)
- projectq.classical (PennyLane-PQ-0.18.0.dev0)
- projectq.ibm (PennyLane-PQ-0.18.0.dev0)
- projectq.simulator (PennyLane-PQ-0.18.0.dev0)
- forest.numpy_wavefunction (PennyLane-Forest-0.18.0.dev0)
- forest.qvm (PennyLane-Forest-0.18.0.dev0)
- forest.wavefunction (PennyLane-Forest-0.18.0.dev0)
- microsoft.QuantumSimulator (PennyLane-qsharp-0.19.0)
- ionq.qpu (PennyLane-IonQ-0.17.0.dev0)
- ionq.simulator (PennyLane-IonQ-0.17.0.dev0)
- strawberryfields.fock (PennyLane-SF-0.20.0.dev0)
- strawberryfields.gaussian (PennyLane-SF-0.20.0.dev0)
- strawberryfields.gbs (PennyLane-SF-0.20.0.dev0)
- strawberryfields.remote (PennyLane-SF-0.20.0.dev0)
- strawberryfields.tf (PennyLane-SF-0.20.0.dev0)
- cirq.mixedsimulator (PennyLane-Cirq-0.20.0.dev0)
- cirq.pasqal (PennyLane-Cirq-0.20.0.dev0)
- cirq.qsim (PennyLane-Cirq-0.20.0.dev0)
- cirq.qsimh (PennyLane-Cirq-0.20.0.dev0)
- cirq.simulator (PennyLane-Cirq-0.20.0.dev0)
- qiskit.aer (PennyLane-qiskit-0.22.0.dev0)
- qiskit.basicaer (PennyLane-qiskit-0.22.0.dev0)
- qiskit.ibmq (PennyLane-qiskit-0.22.0.dev0)
- qiskit.ibmq.circuit_runner (PennyLane-qiskit-0.22.0.dev0)
- qiskit.ibmq.sampler (PennyLane-qiskit-0.22.0.dev0)
```


### Existing GitHub issues

- [X] I have searched existing GitHub issues to make sure the issue does not already exist.


Discussion:
> `func:~.pennylane.compile` doesn't include a hyperlink to the related documentation change, likely because qml.compile is decorated with `@qfunc_transform`.

@antalszava this one is weird, since [`two_qubit_decomposition`](https://pennylane.readthedocs.io/en/latest/code/api/pennylane.transforms.two_qubit_decomposition.html) includes a cross reference to [`unitary_to_rot`](https://pennylane.readthedocs.io/en/latest/code/api/pennylane.transforms.unitary_to_rot.html), which is also decorated, and this cross reference seems to work 🤔 

https://github.com/PennyLaneAI/pennylane/blob/281e55f1d7f36901501535ddc2a903a3b146a463/pennylane/transforms/decompositions/two_qubit_unitary.py#L540-L542

> Further note, that the documentation pages for such decorated functions also differs in style:

I will see if I can fix this one :) If not, we may need to port `@qfunc_transform` to a class, like we do with other decorators:

https://github.com/PennyLaneAI/pennylane/blob/703ae35f206bb0c3782a18a117b95012315ba7f0/pennylane/transforms/batch_transform.py#L187-L191

Resolving patch:
diff --git a/pennylane/transforms/qfunc_transforms.py b/pennylane/transforms/qfunc_transforms.py
--- a/pennylane/transforms/qfunc_transforms.py
+++ b/pennylane/transforms/qfunc_transforms.py
@@ -16,6 +16,8 @@
 from copy import deepcopy
 import functools
 import inspect
+import os
+import warnings
 
 import pennylane as qml
 
@@ -374,6 +376,21 @@ def new_qfunc(*args, **kwargs):
         the queueing logic required under steps (1) and (3), so that it does not need to be
         repeated and tested for every new qfunc transform.
     """
+    if os.environ.get("SPHINX_BUILD") == "1":
+        # If called during a Sphinx documentation build,
+        # simply return the original function rather than
+        # instantiating the object. This allows the signature to
+        # be correctly displayed in the documentation.
+
+        warnings.warn(
+            "qfunc transformations have been disabled, as a Sphinx "
+            "build has been detected via SPHINX_BUILD='1'. If this is not the "
+            "case, please set the environment variable SPHINX_BUILD='0'.",
+            UserWarning,
+        )
+
+        return tape_transform
+
     if not callable(tape_transform):
         raise ValueError(
             "The qfunc_transform decorator can only be applied "


Test patch:
diff --git a/tests/transforms/test_qfunc_transform.py b/tests/transforms/test_qfunc_transform.py
--- a/tests/transforms/test_qfunc_transform.py
+++ b/tests/transforms/test_qfunc_transform.py
@@ -302,6 +302,27 @@ def ansatz():
         assert np.allclose(normal_result, transformed_result)
         assert normal_result.shape == transformed_result.shape
 
+    def test_sphinx_build(self, monkeypatch):
+        """Test that qfunc transforms are not created during Sphinx builds"""
+
+        def original_fn(tape):
+            for op in tape.operations + tape.measurements:
+                if op.name == "Hadamard":
+                    qml.RZ(np.pi, wires=op.wires)
+                    qml.RY(np.pi / 2, wires=op.wires)
+                else:
+                    op.queue()
+
+        decorated_transform = qml.qfunc_transform(original_fn)
+        assert original_fn is not decorated_transform
+
+        monkeypatch.setenv("SPHINX_BUILD", "1")
+
+        with pytest.warns(UserWarning, match="qfunc transformations have been disabled"):
+            decorated_transform = qml.qfunc_transform(original_fn)
+
+        assert original_fn is decorated_transform
+
 
 ############################################
 # Test transform, ansatz, and qfunc function