Repository: networkx/networkx

Issue:
upgrade 2.8.6  -> 3.0 breaks shortest_path()
<!--- Provide a general summary of the issue in the Title above -->
I just re-installed networkx without specifying version so I was upgraded from 2.8.6 to 3.0
Running unaltered code calling nx.shortest_path(*args, **kwargs) under 2.8.6 runs fine and produces correct result but 3.0 fails with an error, missing arguments.

Looking at the source, the 3.0 version got a decorator which doesn't seem to work properly.

The error is reproduced using stripped-down [lollipop example](https://networkx.org/documentation/stable/auto_examples/basic/plot_properties.html#sphx-glr-auto-examples-basic-plot-properties-py)

### Current Behavior

under 3.0:
```
import networkx as nx
G = nx.lollipop_graph(4, 6)
print(nx.shortest_path(G=G, source=list(G.nodes())[1], target=list(G.nodes())[9]))
```
produces

```
Traceback (most recent call last):
  File "C:\Users\XYZ\AppData\Roaming\JetBrains\PyCharm2022.3\scratches\scratch_1.py", line 7, in <module>
    print(nx.shortest_path(G=G, source=list(G.nodes())[1], target=list(G.nodes())[9]))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "E:\modules\venv\networkx_3\Lib\site-packages\networkx\classes\backends.py", line 134, in wrapper
    graph = args[0]
            ~~~~^^^
IndexError: tuple index out of range
```

### Expected Behavior

under 2.8.6:
```
import networkx as nx
G = nx.lollipop_graph(4, 6)
print(nx.shortest_path(G=G, source=list(G.nodes())[1], target=list(G.nodes())[9]))
```
produces
`[1, 3, 4, 5, 6, 7, 8, 9]`

### Environment
Python version: anaconda 3.10, networkx installed via pip
NetworkX version: 2.8.6 and 3.0


Discussion:

Patch:
diff --git a/networkx/classes/backends.py b/networkx/classes/backends.py
index 183db1708..c96f4896a 100644
--- a/networkx/classes/backends.py
+++ b/networkx/classes/backends.py
@@ -128,7 +128,13 @@ def _dispatch(func=None, *, name=None):
 
     @functools.wraps(func)
     def wrapper(*args, **kwds):
-        graph = args[0]
+        if args:
+            graph = args[0]
+        else:
+            try:
+                graph = kwds["G"]
+            except KeyError:
+                raise TypeError(f"{name}() missing positional argument: 'G'") from None
         if hasattr(graph, "__networkx_plugin__") and plugins:
             plugin_name = graph.__networkx_plugin__
             if plugin_name in plugins:


Test patch:
diff --git a/networkx/classes/tests/test_backends.py b/networkx/classes/tests/test_backends.py
new file mode 100644
index 000000000..8d0c86a44
--- /dev/null
+++ b/networkx/classes/tests/test_backends.py
@@ -0,0 +1,14 @@
+import pytest
+
+import networkx as nx
+
+pytest.importorskip("scipy")
+pytest.importorskip("numpy")
+
+
+def test_dispatch_kwds_vs_args():
+    G = nx.path_graph(4)
+    nx.pagerank(G)
+    nx.pagerank(G=G)
+    with pytest.raises(TypeError):
+        nx.pagerank()