We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Possible issue with checking of Quantity input
In my branch ji_diff_rot3 I've started using the quantity_input decorator.  It now decorates rot_hpc, a differential rotation calculator.  The decorator crashes when applied to this function

``` python
In [1]: from sunpy.physics.transforms.differential_rotation import rot_hpc
In [2]: import astropy.units as u
In [3]: rot_hpc( -570 * u.arcsec, 120 * u.arcsec, '2010-09-10 12:34:56', '2010-09-10 13:34:56')
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-3-0803dabeac04> in <module>()
----> 1 rot_hpc( -570 * u.arcsec, 120 * u.arcsec, '2010-09-10 12:34:56', '2010-09-10 13:34:56')

/Users/ireland/sunpy/sunpy/util/unit_decorators.pyc in wrapper(*func_args, **func_kwargs)
     81 
     82                 # Get the value of this parameter (argument to new function)
---> 83                 arg = bound_args.arguments[param.name]
     84 
     85                 # Get target unit, either from decotrator kwargs or annotations

KeyError: 'kwargs'
```

The error is reproducible with much simpler functions:

``` python
In [2]: import astropy.units as u
In [3]: from sunpy.util import quantity_input

In [4]: @quantity_input(a=u.deg)
   ...: def funct(a, **kwargs):
   ...:     pass
   ...: 

In [5]: funct(1 * u.deg)
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-5-5fb4e89adcc1> in <module>()
----> 1 funct(1 * u.deg)

/Users/ireland/sunpy/sunpy/util/unit_decorators.pyc in wrapper(*func_args, **func_kwargs)
     81 
     82                 # Get the value of this parameter (argument to new function)
---> 83                 arg = bound_args.arguments[param.name]
     84 
     85                 # Get target unit, either from decotrator kwargs or annotations

KeyError: 'kwargs'
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `sunpy/util/unit_decorators.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 # Lovingly borrowed from Astropy
3 # Licensed under a 3-clause BSD style license - see licences/ASTROPY.rst
4 
5 __all__ = ['quantity_input']
6 
7 from ..util.compat import funcsigs
8 
9 from astropy.units import UnitsError, add_enabled_equivalencies
10 
11 class QuantityInput(object):
12 
13     @classmethod
14     def as_decorator(cls, func=None, **kwargs):
15         """
16         A decorator for validating the units of arguments to functions.
17 
18         Unit specifications can be provided as keyword arguments to the decorator,
19         or by using Python 3's function annotation syntax. Arguments to the decorator
20         take precidence over any function annotations present.
21 
22         A `~astropy.units.UnitsError` will be raised if the unit attribute of
23         the argument is not equivalent to the unit specified to the decorator
24         or in the annotation.
25         If the argument has no unit attribute, i.e. it is not a Quantity object, a
26         `~exceptions.ValueError` will be raised.
27 
28         Where an equivalency is specified in the decorator, the function will be
29         executed with that equivalency in force.
30 
31         Examples
32         --------
33 
34         Python 2 and 3::
35 
36             import astropy.units as u
37             @u.quantity_input(myangle=u.arcsec)
38             def myfunction(myangle):
39                 return myangle**2
40 
41         Python 3 only::
42 
43             import astropy.units as u
44             @u.quantity_input
45             def myfunction(myangle: u.arcsec):
46                 return myangle**2
47 
48         Using equivalencies::
49 
50             import astropy.units as u
51             @u.quantity_input(myenergy=u.eV, equivalencies=u.mass_energy())
52             def myfunction(myenergy):
53                 return myenergy**2
54 
55         """
56         self = cls(**kwargs)
57         if func is not None and not kwargs:
58             return self(func)
59         else:
60             return self
61 
62     def __init__(self, func=None, **kwargs):
63         self.equivalencies = kwargs.pop('equivalencies', [])
64         self.decorator_kwargs = kwargs
65 
66     def __call__(self, wrapped_function):
67 
68         # Extract the function signature for the function we are wrapping.
69         wrapped_signature = funcsigs.signature(wrapped_function)
70 
71         # Define a new function to return in place of the wrapped one
72         def wrapper(*func_args, **func_kwargs):
73             # Bind the arguments to our new function to the signature of the original.
74             bound_args = wrapped_signature.bind(*func_args, **func_kwargs)
75 
76             # Iterate through the parameters of the original signature
77             for param in wrapped_signature.parameters.values():
78                 # Catch the (never triggered) case where bind relied on a default value.
79                 if param.name not in bound_args.arguments and param.default is not param.empty:
80                     bound_args.arguments[param.name] = param.default
81 
82                 # Get the value of this parameter (argument to new function)
83                 arg = bound_args.arguments[param.name]
84 
85                 # Get target unit, either from decotrator kwargs or annotations
86                 if param.name in self.decorator_kwargs:
87                     target_unit = self.decorator_kwargs[param.name]
88                 else:
89                     target_unit = param.annotation
90 
91                 # If the target unit is empty, then no unit was specified so we
92                 # move past it
93                 if target_unit is not funcsigs.Parameter.empty:
94                     try:
95                         equivalent = arg.unit.is_equivalent(target_unit,
96                                                   equivalencies=self.equivalencies)
97 
98                         if not equivalent:
99                             raise UnitsError("Argument '{0}' to function '{1}'"
100                                              " must be in units convertable to"
101                                              " '{2}'.".format(param.name,
102                                                      wrapped_function.__name__,
103                                                      target_unit.to_string()))
104 
105                     # Either there is no .unit or no .is_equivalent
106                     except AttributeError:
107                         if hasattr(arg, "unit"):
108                             error_msg = "a 'unit' attribute without an 'is_equivalent' method"
109                         else:
110                             error_msg = "no 'unit' attribute"
111                         raise TypeError("Argument '{0}' to function has '{1}' {2}. "
112                               "You may want to pass in an astropy Quantity instead."
113                                  .format(param.name, wrapped_function.__name__, error_msg))
114 
115             # Call the original function with any equivalencies in force.
116             with add_enabled_equivalencies(self.equivalencies):
117                 return wrapped_function(*func_args, **func_kwargs)
118 
119         return wrapper
120 
121 quantity_input = QuantityInput.as_decorator
122
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/sunpy/util/unit_decorators.py b/sunpy/util/unit_decorators.py
--- a/sunpy/util/unit_decorators.py
+++ b/sunpy/util/unit_decorators.py
@@ -75,6 +75,11 @@
 
             # Iterate through the parameters of the original signature
             for param in wrapped_signature.parameters.values():
+                 # We do not support variable arguments (*args,
+                 # **kwargs)
+                if param.kind in (funcsigs.Parameter.VAR_KEYWORD,
+                                  funcsigs.Parameter.VAR_POSITIONAL):
+                    continue
                 # Catch the (never triggered) case where bind relied on a default value.
                 if param.name not in bound_args.arguments and param.default is not param.empty:
                     bound_args.arguments[param.name] = param.default

{"golden_diff": "diff --git a/sunpy/util/unit_decorators.py b/sunpy/util/unit_decorators.py\n--- a/sunpy/util/unit_decorators.py\n+++ b/sunpy/util/unit_decorators.py\n@@ -75,6 +75,11 @@\n \n             # Iterate through the parameters of the original signature\n             for param in wrapped_signature.parameters.values():\n+                 # We do not support variable arguments (*args,\n+                 # **kwargs)\n+                if param.kind in (funcsigs.Parameter.VAR_KEYWORD,\n+                                  funcsigs.Parameter.VAR_POSITIONAL):\n+                    continue\n                 # Catch the (never triggered) case where bind relied on a default value.\n                 if param.name not in bound_args.arguments and param.default is not param.empty:\n                     bound_args.arguments[param.name] = param.default\n", "issue": "Possible issue with checking of Quantity input\nIn my branch ji_diff_rot3 I've started using the quantity_input decorator.  It now decorates rot_hpc, a differential rotation calculator.  The decorator crashes when applied to this function\n\n``` python\nIn [1]: from sunpy.physics.transforms.differential_rotation import rot_hpc\nIn [2]: import astropy.units as u\nIn [3]: rot_hpc( -570 * u.arcsec, 120 * u.arcsec, '2010-09-10 12:34:56', '2010-09-10 13:34:56')\n---------------------------------------------------------------------------\nKeyError                                  Traceback (most recent call last)\n<ipython-input-3-0803dabeac04> in <module>()\n----> 1 rot_hpc( -570 * u.arcsec, 120 * u.arcsec, '2010-09-10 12:34:56', '2010-09-10 13:34:56')\n\n/Users/ireland/sunpy/sunpy/util/unit_decorators.pyc in wrapper(*func_args, **func_kwargs)\n     81 \n     82                 # Get the value of this parameter (argument to new function)\n---> 83                 arg = bound_args.arguments[param.name]\n     84 \n     85                 # Get target unit, either from decotrator kwargs or annotations\n\nKeyError: 'kwargs'\n```\n\nThe error is reproducible with much simpler functions:\n\n``` python\nIn [2]: import astropy.units as u\nIn [3]: from sunpy.util import quantity_input\n\nIn [4]: @quantity_input(a=u.deg)\n   ...: def funct(a, **kwargs):\n   ...:     pass\n   ...: \n\nIn [5]: funct(1 * u.deg)\n---------------------------------------------------------------------------\nKeyError                                  Traceback (most recent call last)\n<ipython-input-5-5fb4e89adcc1> in <module>()\n----> 1 funct(1 * u.deg)\n\n/Users/ireland/sunpy/sunpy/util/unit_decorators.pyc in wrapper(*func_args, **func_kwargs)\n     81 \n     82                 # Get the value of this parameter (argument to new function)\n---> 83                 arg = bound_args.arguments[param.name]\n     84 \n     85                 # Get target unit, either from decotrator kwargs or annotations\n\nKeyError: 'kwargs'\n```\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n# Lovingly borrowed from Astropy\n# Licensed under a 3-clause BSD style license - see licences/ASTROPY.rst\n\n__all__ = ['quantity_input']\n\nfrom ..util.compat import funcsigs\n\nfrom astropy.units import UnitsError, add_enabled_equivalencies\n\nclass QuantityInput(object):\n\n    @classmethod\n    def as_decorator(cls, func=None, **kwargs):\n        \"\"\"\n        A decorator for validating the units of arguments to functions.\n\n        Unit specifications can be provided as keyword arguments to the decorator,\n        or by using Python 3's function annotation syntax. Arguments to the decorator\n        take precidence over any function annotations present.\n\n        A `~astropy.units.UnitsError` will be raised if the unit attribute of\n        the argument is not equivalent to the unit specified to the decorator\n        or in the annotation.\n        If the argument has no unit attribute, i.e. it is not a Quantity object, a\n        `~exceptions.ValueError` will be raised.\n\n        Where an equivalency is specified in the decorator, the function will be\n        executed with that equivalency in force.\n\n        Examples\n        --------\n\n        Python 2 and 3::\n\n            import astropy.units as u\n            @u.quantity_input(myangle=u.arcsec)\n            def myfunction(myangle):\n                return myangle**2\n\n        Python 3 only::\n\n            import astropy.units as u\n            @u.quantity_input\n            def myfunction(myangle: u.arcsec):\n                return myangle**2\n\n        Using equivalencies::\n\n            import astropy.units as u\n            @u.quantity_input(myenergy=u.eV, equivalencies=u.mass_energy())\n            def myfunction(myenergy):\n                return myenergy**2\n\n        \"\"\"\n        self = cls(**kwargs)\n        if func is not None and not kwargs:\n            return self(func)\n        else:\n            return self\n\n    def __init__(self, func=None, **kwargs):\n        self.equivalencies = kwargs.pop('equivalencies', [])\n        self.decorator_kwargs = kwargs\n\n    def __call__(self, wrapped_function):\n\n        # Extract the function signature for the function we are wrapping.\n        wrapped_signature = funcsigs.signature(wrapped_function)\n\n        # Define a new function to return in place of the wrapped one\n        def wrapper(*func_args, **func_kwargs):\n            # Bind the arguments to our new function to the signature of the original.\n            bound_args = wrapped_signature.bind(*func_args, **func_kwargs)\n\n            # Iterate through the parameters of the original signature\n            for param in wrapped_signature.parameters.values():\n                # Catch the (never triggered) case where bind relied on a default value.\n                if param.name not in bound_args.arguments and param.default is not param.empty:\n                    bound_args.arguments[param.name] = param.default\n\n                # Get the value of this parameter (argument to new function)\n                arg = bound_args.arguments[param.name]\n\n                # Get target unit, either from decotrator kwargs or annotations\n                if param.name in self.decorator_kwargs:\n                    target_unit = self.decorator_kwargs[param.name]\n                else:\n                    target_unit = param.annotation\n\n                # If the target unit is empty, then no unit was specified so we\n                # move past it\n                if target_unit is not funcsigs.Parameter.empty:\n                    try:\n                        equivalent = arg.unit.is_equivalent(target_unit,\n                                                  equivalencies=self.equivalencies)\n\n                        if not equivalent:\n                            raise UnitsError(\"Argument '{0}' to function '{1}'\"\n                                             \" must be in units convertable to\"\n                                             \" '{2}'.\".format(param.name,\n                                                     wrapped_function.__name__,\n                                                     target_unit.to_string()))\n\n                    # Either there is no .unit or no .is_equivalent\n                    except AttributeError:\n                        if hasattr(arg, \"unit\"):\n                            error_msg = \"a 'unit' attribute without an 'is_equivalent' method\"\n                        else:\n                            error_msg = \"no 'unit' attribute\"\n                        raise TypeError(\"Argument '{0}' to function has '{1}' {2}. \"\n                              \"You may want to pass in an astropy Quantity instead.\"\n                                 .format(param.name, wrapped_function.__name__, error_msg))\n\n            # Call the original function with any equivalencies in force.\n            with add_enabled_equivalencies(self.equivalencies):\n                return wrapped_function(*func_args, **func_kwargs)\n\n        return wrapper\n\nquantity_input = QuantityInput.as_decorator\n", "path": "sunpy/util/unit_decorators.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n# Lovingly borrowed from Astropy\n# Licensed under a 3-clause BSD style license - see licences/ASTROPY.rst\n\n__all__ = ['quantity_input']\n\nfrom ..util.compat import funcsigs\n\nfrom astropy.units import UnitsError, add_enabled_equivalencies\n\nclass QuantityInput(object):\n\n    @classmethod\n    def as_decorator(cls, func=None, **kwargs):\n        \"\"\"\n        A decorator for validating the units of arguments to functions.\n\n        Unit specifications can be provided as keyword arguments to the decorator,\n        or by using Python 3's function annotation syntax. Arguments to the decorator\n        take precidence over any function annotations present.\n\n        A `~astropy.units.UnitsError` will be raised if the unit attribute of\n        the argument is not equivalent to the unit specified to the decorator\n        or in the annotation.\n        If the argument has no unit attribute, i.e. it is not a Quantity object, a\n        `~exceptions.ValueError` will be raised.\n\n        Where an equivalency is specified in the decorator, the function will be\n        executed with that equivalency in force.\n\n        Examples\n        --------\n\n        Python 2 and 3::\n\n            import astropy.units as u\n            @u.quantity_input(myangle=u.arcsec)\n            def myfunction(myangle):\n                return myangle**2\n\n        Python 3 only::\n\n            import astropy.units as u\n            @u.quantity_input\n            def myfunction(myangle: u.arcsec):\n                return myangle**2\n\n        Using equivalencies::\n\n            import astropy.units as u\n            @u.quantity_input(myenergy=u.eV, equivalencies=u.mass_energy())\n            def myfunction(myenergy):\n                return myenergy**2\n\n        \"\"\"\n        self = cls(**kwargs)\n        if func is not None and not kwargs:\n            return self(func)\n        else:\n            return self\n\n    def __init__(self, func=None, **kwargs):\n        self.equivalencies = kwargs.pop('equivalencies', [])\n        self.decorator_kwargs = kwargs\n\n    def __call__(self, wrapped_function):\n\n        # Extract the function signature for the function we are wrapping.\n        wrapped_signature = funcsigs.signature(wrapped_function)\n\n        # Define a new function to return in place of the wrapped one\n        def wrapper(*func_args, **func_kwargs):\n            # Bind the arguments to our new function to the signature of the original.\n            bound_args = wrapped_signature.bind(*func_args, **func_kwargs)\n\n            # Iterate through the parameters of the original signature\n            for param in wrapped_signature.parameters.values():\n                 # We do not support variable arguments (*args,\n                 # **kwargs)\n                if param.kind in (funcsigs.Parameter.VAR_KEYWORD,\n                                  funcsigs.Parameter.VAR_POSITIONAL):\n                    continue\n                # Catch the (never triggered) case where bind relied on a default value.\n                if param.name not in bound_args.arguments and param.default is not param.empty:\n                    bound_args.arguments[param.name] = param.default\n\n                # Get the value of this parameter (argument to new function)\n                arg = bound_args.arguments[param.name]\n\n                # Get target unit, either from decotrator kwargs or annotations\n                if param.name in self.decorator_kwargs:\n                    target_unit = self.decorator_kwargs[param.name]\n                else:\n                    target_unit = param.annotation\n\n                # If the target unit is empty, then no unit was specified so we\n                # move past it\n                if target_unit is not funcsigs.Parameter.empty:\n                    try:\n                        equivalent = arg.unit.is_equivalent(target_unit,\n                                                  equivalencies=self.equivalencies)\n\n                        if not equivalent:\n                            raise UnitsError(\"Argument '{0}' to function '{1}'\"\n                                             \" must be in units convertable to\"\n                                             \" '{2}'.\".format(param.name,\n                                                     wrapped_function.__name__,\n                                                     target_unit.to_string()))\n\n                    # Either there is no .unit or no .is_equivalent\n                    except AttributeError:\n                        if hasattr(arg, \"unit\"):\n                            error_msg = \"a 'unit' attribute without an 'is_equivalent' method\"\n                        else:\n                            error_msg = \"no 'unit' attribute\"\n                        raise TypeError(\"Argument '{0}' to function has '{1}' {2}. \"\n                              \"You may want to pass in an astropy Quantity instead.\"\n                                 .format(param.name, wrapped_function.__name__, error_msg))\n\n            # Call the original function with any equivalencies in force.\n            with add_enabled_equivalencies(self.equivalencies):\n                return wrapped_function(*func_args, **func_kwargs)\n\n        return wrapper\n\nquantity_input = QuantityInput.as_decorator\n", "path": "sunpy/util/unit_decorators.py"}]}