Repository: brettcannon/gidgethub
Pull request #39 (2017-06-03 03:14:57)

"Fix" routing.Router.dispatch()

codecov[bot]: # [Codecov](https://codecov.io/gh/brettcannon/gidgethub/pull/39?src=pr&el=h1) Report
> Merging [#39](https://codecov.io/gh/brettcannon/gidgethub/pull/39?src=pr&el=desc) into [master](https://codecov.io/gh/brettcannon/gidgethub/commit/420761c950f27916f9727d9b453f4e26d14b1768?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/brettcannon/gidgethub/pull/39/graphs/tree.svg?width=650&height=150&src=pr&token=t1zJsj2sZH)](https://codecov.io/gh/brettcannon/gidgethub/pull/39?src=pr&el=tree)

```diff
@@          Coverage Diff          @@
##           master    #39   +/-   ##
=====================================
  Coverage     100%   100%           
=====================================
  Files          14     14           
  Lines         981    990    +9     
  Branches       57     57           
=====================================
+ Hits          981    990    +9
```


| [Impacted Files](https://codecov.io/gh/brettcannon/gidgethub/pull/39?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [gidgethub/test/test\_routing.py](https://codecov.io/gh/brettcannon/gidgethub/pull/39?src=pr&el=tree#diff-Z2lkZ2V0aHViL3Rlc3QvdGVzdF9yb3V0aW5nLnB5) | `100% <100%> (ø)` | :arrow_up: |
| [gidgethub/routing.py](https://codecov.io/gh/brettcannon/gidgethub/pull/39?src=pr&el=tree#diff-Z2lkZ2V0aHViL3JvdXRpbmcucHk=) | `100% <100%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/brettcannon/gidgethub/pull/39?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/brettcannon/gidgethub/pull/39?src=pr&el=footer). Last update [420761c...8d0e876](https://codecov.io/gh/brettcannon/gidgethub/pull/39?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/README.rst b/README.rst
index 3c93017..b2d923e 100644
--- a/README.rst
+++ b/README.rst
@@ -58,10 +58,10 @@ cat's name, Gidget, as part of the name. Since "Gidget" somewhat sounds like
 Changelog
 ---------
 
-2.3.1 (in development)
+2.4.0
 ''''''''''''''''''''''
 
-N/A
+- Expand ``gidgethub.routing.Router.dispatch()``.
 
 
 2.3.0
diff --git a/docs/routing.rst b/docs/routing.rst
index e4d79e9..16cc19c 100644
--- a/docs/routing.rst
+++ b/docs/routing.rst
@@ -26,12 +26,12 @@ in user code.
     are then used to construct a server-wide router.
 
     Each callback registered with this class is expected to be
-    :term:`awaitable` and to accept a single
+    :term:`awaitable` and to accept at least a single
     :class:`~gidgethub.sansio.Event` instance:
 
     .. code-block:: python
 
-        async def callback(event):
+        async def callback(event, *args, **kwargs):
             ...
 
 
@@ -71,6 +71,11 @@ in user code.
                 ...
 
 
-    .. coroutine:: dispatch(event)
+    .. coroutine:: dispatch(event, *args, **kwargs)
 
         Call the appropriate asynchronous callbacks for the *event*.
+        The provided event and any other arguments will be passed
+        down to the callback unmodified.
+
+        .. versionchanged:: 2.4
+            Added ``*args`` and ``**kwargs``.
diff --git a/gidgethub/routing.py b/gidgethub/routing.py
index 5fbe312..7935c6e 100644
--- a/gidgethub/routing.py
+++ b/gidgethub/routing.py
@@ -3,7 +3,7 @@ from typing import Any, Awaitable, Callable, Dict, List, Optional
 from . import sansio
 
 
-AsyncCallback = Callable[[sansio.Event], Awaitable[None]]
+AsyncCallback = Callable[..., Awaitable[None]]
 
 
 class Router:
@@ -57,7 +57,8 @@ class Router:
             return func
         return decorator
 
-    async def dispatch(self, event: sansio.Event) -> None:
+    async def dispatch(self, event: sansio.Event, *args: Any,
+                       **kwargs: Any) -> None:
         """Dispatch an event to all registered function(s)."""
 
         found_callbacks = []
@@ -76,4 +77,4 @@ class Router:
                     if event_value in data_values:
                         found_callbacks.extend(data_values[event_value])
         for callback in found_callbacks:
-            await callback(event)
+            await callback(event, *args, **kwargs)
diff --git a/setup.py b/setup.py
index 959a89c..d78dcb8 100644
--- a/setup.py
+++ b/setup.py
@@ -13,7 +13,7 @@ long_description = pathlib.Path("README.rst").read_text("utf-8")
 
 setuptools.setup(
     name="gidgethub",
-    version="2.3.1.dev1",
+    version="2.4.0",
     description="An async GitHub API library",
     long_description=long_description,
     url="https://gidgethub.readthedocs.io",


Test patch:
diff --git a/gidgethub/test/test_routing.py b/gidgethub/test/test_routing.py
index fdf70fc..5261d6f 100644
--- a/gidgethub/test/test_routing.py
+++ b/gidgethub/test/test_routing.py
@@ -9,9 +9,11 @@ class Callback:
     def __init__(self):
         self.called = False
 
-    async def meth(self, event):
+    async def meth(self, event, *args, **kwargs):
         self.called = True
         self.event = event
+        self.args = args
+        self.kwargs = kwargs
 
 
 @pytest.mark.asyncio
@@ -23,6 +25,11 @@ async def test_shallow_callback():
     await router.dispatch(event)
     assert callback.called
     assert callback.event == event
+    assert not callback.args
+    assert not callback.kwargs
+    await router.dispatch(event, 42, hello="world")
+    assert callback.args == (42,)
+    assert callback.kwargs == {"hello": "world"}
 
 
 @pytest.mark.asyncio
@@ -34,6 +41,8 @@ async def test_deep_callback():
     await router.dispatch(event)
     assert callback.called
     assert callback.event == event
+    assert not callback.args
+    assert not callback.kwargs
 
 
 def test_too_much_detail():