We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Fix typo in positional decorator method docstring
Thanks for stopping by to let us know something could be better!

**PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response.

Please run down the following list and make sure you've tried the usual "quick fixes":

  - Search the issues already opened: https://github.com/googleapis/google-api-python-client/issues
  - Search StackOverflow: https://stackoverflow.com/questions/tagged/google-cloud-platform+python

If you are still having issues, please be sure to include as much information as possible:

#### Environment details

  - OS type and version:  irrelevant
  - Python version:  irrelevant
  - pip version:  irrelevant
  - `google-api-python-client` version:  irrelevant

#### Steps to reproduce

 irrelevant

#### Code example

 irrelevant

#### Stack trace

 irrelevant

Making sure to follow these steps will guarantee the quickest resolution possible.

Thanks!


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `googleapiclient/_helpers.py`
Content:
```
1 # Copyright 2015 Google Inc. All rights reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 """Helper functions for commonly used utilities."""
16 
17 import functools
18 import inspect
19 import logging
20 import warnings
21 
22 import six
23 from six.moves import urllib
24 
25 
26 logger = logging.getLogger(__name__)
27 
28 POSITIONAL_WARNING = "WARNING"
29 POSITIONAL_EXCEPTION = "EXCEPTION"
30 POSITIONAL_IGNORE = "IGNORE"
31 POSITIONAL_SET = frozenset(
32     [POSITIONAL_WARNING, POSITIONAL_EXCEPTION, POSITIONAL_IGNORE]
33 )
34 
35 positional_parameters_enforcement = POSITIONAL_WARNING
36 
37 _SYM_LINK_MESSAGE = "File: {0}: Is a symbolic link."
38 _IS_DIR_MESSAGE = "{0}: Is a directory"
39 _MISSING_FILE_MESSAGE = "Cannot access {0}: No such file or directory"
40 
41 
42 def positional(max_positional_args):
43     """A decorator to declare that only the first N arguments my be positional.
44 
45     This decorator makes it easy to support Python 3 style keyword-only
46     parameters. For example, in Python 3 it is possible to write::
47 
48         def fn(pos1, *, kwonly1=None, kwonly1=None):
49             ...
50 
51     All named parameters after ``*`` must be a keyword::
52 
53         fn(10, 'kw1', 'kw2')  # Raises exception.
54         fn(10, kwonly1='kw1')  # Ok.
55 
56     Example
57     ^^^^^^^
58 
59     To define a function like above, do::
60 
61         @positional(1)
62         def fn(pos1, kwonly1=None, kwonly2=None):
63             ...
64 
65     If no default value is provided to a keyword argument, it becomes a
66     required keyword argument::
67 
68         @positional(0)
69         def fn(required_kw):
70             ...
71 
72     This must be called with the keyword parameter::
73 
74         fn()  # Raises exception.
75         fn(10)  # Raises exception.
76         fn(required_kw=10)  # Ok.
77 
78     When defining instance or class methods always remember to account for
79     ``self`` and ``cls``::
80 
81         class MyClass(object):
82 
83             @positional(2)
84             def my_method(self, pos1, kwonly1=None):
85                 ...
86 
87             @classmethod
88             @positional(2)
89             def my_method(cls, pos1, kwonly1=None):
90                 ...
91 
92     The positional decorator behavior is controlled by
93     ``_helpers.positional_parameters_enforcement``, which may be set to
94     ``POSITIONAL_EXCEPTION``, ``POSITIONAL_WARNING`` or
95     ``POSITIONAL_IGNORE`` to raise an exception, log a warning, or do
96     nothing, respectively, if a declaration is violated.
97 
98     Args:
99         max_positional_arguments: Maximum number of positional arguments. All
100                                   parameters after the this index must be
101                                   keyword only.
102 
103     Returns:
104         A decorator that prevents using arguments after max_positional_args
105         from being used as positional parameters.
106 
107     Raises:
108         TypeError: if a key-word only argument is provided as a positional
109                    parameter, but only if
110                    _helpers.positional_parameters_enforcement is set to
111                    POSITIONAL_EXCEPTION.
112     """
113 
114     def positional_decorator(wrapped):
115         @functools.wraps(wrapped)
116         def positional_wrapper(*args, **kwargs):
117             if len(args) > max_positional_args:
118                 plural_s = ""
119                 if max_positional_args != 1:
120                     plural_s = "s"
121                 message = (
122                     "{function}() takes at most {args_max} positional "
123                     "argument{plural} ({args_given} given)".format(
124                         function=wrapped.__name__,
125                         args_max=max_positional_args,
126                         args_given=len(args),
127                         plural=plural_s,
128                     )
129                 )
130                 if positional_parameters_enforcement == POSITIONAL_EXCEPTION:
131                     raise TypeError(message)
132                 elif positional_parameters_enforcement == POSITIONAL_WARNING:
133                     logger.warning(message)
134             return wrapped(*args, **kwargs)
135 
136         return positional_wrapper
137 
138     if isinstance(max_positional_args, six.integer_types):
139         return positional_decorator
140     else:
141         args, _, _, defaults = inspect.getargspec(max_positional_args)
142         return positional(len(args) - len(defaults))(max_positional_args)
143 
144 
145 def parse_unique_urlencoded(content):
146     """Parses unique key-value parameters from urlencoded content.
147 
148     Args:
149         content: string, URL-encoded key-value pairs.
150 
151     Returns:
152         dict, The key-value pairs from ``content``.
153 
154     Raises:
155         ValueError: if one of the keys is repeated.
156     """
157     urlencoded_params = urllib.parse.parse_qs(content)
158     params = {}
159     for key, value in six.iteritems(urlencoded_params):
160         if len(value) != 1:
161             msg = "URL-encoded content contains a repeated value:" "%s -> %s" % (
162                 key,
163                 ", ".join(value),
164             )
165             raise ValueError(msg)
166         params[key] = value[0]
167     return params
168 
169 
170 def update_query_params(uri, params):
171     """Updates a URI with new query parameters.
172 
173     If a given key from ``params`` is repeated in the ``uri``, then
174     the URI will be considered invalid and an error will occur.
175 
176     If the URI is valid, then each value from ``params`` will
177     replace the corresponding value in the query parameters (if
178     it exists).
179 
180     Args:
181         uri: string, A valid URI, with potential existing query parameters.
182         params: dict, A dictionary of query parameters.
183 
184     Returns:
185         The same URI but with the new query parameters added.
186     """
187     parts = urllib.parse.urlparse(uri)
188     query_params = parse_unique_urlencoded(parts.query)
189     query_params.update(params)
190     new_query = urllib.parse.urlencode(query_params)
191     new_parts = parts._replace(query=new_query)
192     return urllib.parse.urlunparse(new_parts)
193 
194 
195 def _add_query_parameter(url, name, value):
196     """Adds a query parameter to a url.
197 
198     Replaces the current value if it already exists in the URL.
199 
200     Args:
201         url: string, url to add the query parameter to.
202         name: string, query parameter name.
203         value: string, query parameter value.
204 
205     Returns:
206         Updated query parameter. Does not update the url if value is None.
207     """
208     if value is None:
209         return url
210     else:
211         return update_query_params(url, {name: value})
212
```
--- 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/googleapiclient/_helpers.py b/googleapiclient/_helpers.py
--- a/googleapiclient/_helpers.py
+++ b/googleapiclient/_helpers.py
@@ -40,7 +40,7 @@
 
 
 def positional(max_positional_args):
-    """A decorator to declare that only the first N arguments my be positional.
+    """A decorator to declare that only the first N arguments may be positional.
 
     This decorator makes it easy to support Python 3 style keyword-only
     parameters. For example, in Python 3 it is possible to write::

{"golden_diff": "diff --git a/googleapiclient/_helpers.py b/googleapiclient/_helpers.py\n--- a/googleapiclient/_helpers.py\n+++ b/googleapiclient/_helpers.py\n@@ -40,7 +40,7 @@\n \n \n def positional(max_positional_args):\n-    \"\"\"A decorator to declare that only the first N arguments my be positional.\n+    \"\"\"A decorator to declare that only the first N arguments may be positional.\n \n     This decorator makes it easy to support Python 3 style keyword-only\n     parameters. For example, in Python 3 it is possible to write::\n", "issue": "Fix typo in positional decorator method docstring\nThanks for stopping by to let us know something could be better!\r\n\r\n**PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response.\r\n\r\nPlease run down the following list and make sure you've tried the usual \"quick fixes\":\r\n\r\n  - Search the issues already opened: https://github.com/googleapis/google-api-python-client/issues\r\n  - Search StackOverflow: https://stackoverflow.com/questions/tagged/google-cloud-platform+python\r\n\r\nIf you are still having issues, please be sure to include as much information as possible:\r\n\r\n#### Environment details\r\n\r\n  - OS type and version:  irrelevant\r\n  - Python version:  irrelevant\r\n  - pip version:  irrelevant\r\n  - `google-api-python-client` version:  irrelevant\r\n\r\n#### Steps to reproduce\r\n\r\n irrelevant\r\n\r\n#### Code example\r\n\r\n irrelevant\r\n\r\n#### Stack trace\r\n\r\n irrelevant\r\n\r\nMaking sure to follow these steps will guarantee the quickest resolution possible.\r\n\r\nThanks!\r\n\n", "before_files": [{"content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Helper functions for commonly used utilities.\"\"\"\n\nimport functools\nimport inspect\nimport logging\nimport warnings\n\nimport six\nfrom six.moves import urllib\n\n\nlogger = logging.getLogger(__name__)\n\nPOSITIONAL_WARNING = \"WARNING\"\nPOSITIONAL_EXCEPTION = \"EXCEPTION\"\nPOSITIONAL_IGNORE = \"IGNORE\"\nPOSITIONAL_SET = frozenset(\n    [POSITIONAL_WARNING, POSITIONAL_EXCEPTION, POSITIONAL_IGNORE]\n)\n\npositional_parameters_enforcement = POSITIONAL_WARNING\n\n_SYM_LINK_MESSAGE = \"File: {0}: Is a symbolic link.\"\n_IS_DIR_MESSAGE = \"{0}: Is a directory\"\n_MISSING_FILE_MESSAGE = \"Cannot access {0}: No such file or directory\"\n\n\ndef positional(max_positional_args):\n    \"\"\"A decorator to declare that only the first N arguments my be positional.\n\n    This decorator makes it easy to support Python 3 style keyword-only\n    parameters. For example, in Python 3 it is possible to write::\n\n        def fn(pos1, *, kwonly1=None, kwonly1=None):\n            ...\n\n    All named parameters after ``*`` must be a keyword::\n\n        fn(10, 'kw1', 'kw2')  # Raises exception.\n        fn(10, kwonly1='kw1')  # Ok.\n\n    Example\n    ^^^^^^^\n\n    To define a function like above, do::\n\n        @positional(1)\n        def fn(pos1, kwonly1=None, kwonly2=None):\n            ...\n\n    If no default value is provided to a keyword argument, it becomes a\n    required keyword argument::\n\n        @positional(0)\n        def fn(required_kw):\n            ...\n\n    This must be called with the keyword parameter::\n\n        fn()  # Raises exception.\n        fn(10)  # Raises exception.\n        fn(required_kw=10)  # Ok.\n\n    When defining instance or class methods always remember to account for\n    ``self`` and ``cls``::\n\n        class MyClass(object):\n\n            @positional(2)\n            def my_method(self, pos1, kwonly1=None):\n                ...\n\n            @classmethod\n            @positional(2)\n            def my_method(cls, pos1, kwonly1=None):\n                ...\n\n    The positional decorator behavior is controlled by\n    ``_helpers.positional_parameters_enforcement``, which may be set to\n    ``POSITIONAL_EXCEPTION``, ``POSITIONAL_WARNING`` or\n    ``POSITIONAL_IGNORE`` to raise an exception, log a warning, or do\n    nothing, respectively, if a declaration is violated.\n\n    Args:\n        max_positional_arguments: Maximum number of positional arguments. All\n                                  parameters after the this index must be\n                                  keyword only.\n\n    Returns:\n        A decorator that prevents using arguments after max_positional_args\n        from being used as positional parameters.\n\n    Raises:\n        TypeError: if a key-word only argument is provided as a positional\n                   parameter, but only if\n                   _helpers.positional_parameters_enforcement is set to\n                   POSITIONAL_EXCEPTION.\n    \"\"\"\n\n    def positional_decorator(wrapped):\n        @functools.wraps(wrapped)\n        def positional_wrapper(*args, **kwargs):\n            if len(args) > max_positional_args:\n                plural_s = \"\"\n                if max_positional_args != 1:\n                    plural_s = \"s\"\n                message = (\n                    \"{function}() takes at most {args_max} positional \"\n                    \"argument{plural} ({args_given} given)\".format(\n                        function=wrapped.__name__,\n                        args_max=max_positional_args,\n                        args_given=len(args),\n                        plural=plural_s,\n                    )\n                )\n                if positional_parameters_enforcement == POSITIONAL_EXCEPTION:\n                    raise TypeError(message)\n                elif positional_parameters_enforcement == POSITIONAL_WARNING:\n                    logger.warning(message)\n            return wrapped(*args, **kwargs)\n\n        return positional_wrapper\n\n    if isinstance(max_positional_args, six.integer_types):\n        return positional_decorator\n    else:\n        args, _, _, defaults = inspect.getargspec(max_positional_args)\n        return positional(len(args) - len(defaults))(max_positional_args)\n\n\ndef parse_unique_urlencoded(content):\n    \"\"\"Parses unique key-value parameters from urlencoded content.\n\n    Args:\n        content: string, URL-encoded key-value pairs.\n\n    Returns:\n        dict, The key-value pairs from ``content``.\n\n    Raises:\n        ValueError: if one of the keys is repeated.\n    \"\"\"\n    urlencoded_params = urllib.parse.parse_qs(content)\n    params = {}\n    for key, value in six.iteritems(urlencoded_params):\n        if len(value) != 1:\n            msg = \"URL-encoded content contains a repeated value:\" \"%s -> %s\" % (\n                key,\n                \", \".join(value),\n            )\n            raise ValueError(msg)\n        params[key] = value[0]\n    return params\n\n\ndef update_query_params(uri, params):\n    \"\"\"Updates a URI with new query parameters.\n\n    If a given key from ``params`` is repeated in the ``uri``, then\n    the URI will be considered invalid and an error will occur.\n\n    If the URI is valid, then each value from ``params`` will\n    replace the corresponding value in the query parameters (if\n    it exists).\n\n    Args:\n        uri: string, A valid URI, with potential existing query parameters.\n        params: dict, A dictionary of query parameters.\n\n    Returns:\n        The same URI but with the new query parameters added.\n    \"\"\"\n    parts = urllib.parse.urlparse(uri)\n    query_params = parse_unique_urlencoded(parts.query)\n    query_params.update(params)\n    new_query = urllib.parse.urlencode(query_params)\n    new_parts = parts._replace(query=new_query)\n    return urllib.parse.urlunparse(new_parts)\n\n\ndef _add_query_parameter(url, name, value):\n    \"\"\"Adds a query parameter to a url.\n\n    Replaces the current value if it already exists in the URL.\n\n    Args:\n        url: string, url to add the query parameter to.\n        name: string, query parameter name.\n        value: string, query parameter value.\n\n    Returns:\n        Updated query parameter. Does not update the url if value is None.\n    \"\"\"\n    if value is None:\n        return url\n    else:\n        return update_query_params(url, {name: value})\n", "path": "googleapiclient/_helpers.py"}], "after_files": [{"content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Helper functions for commonly used utilities.\"\"\"\n\nimport functools\nimport inspect\nimport logging\nimport warnings\n\nimport six\nfrom six.moves import urllib\n\n\nlogger = logging.getLogger(__name__)\n\nPOSITIONAL_WARNING = \"WARNING\"\nPOSITIONAL_EXCEPTION = \"EXCEPTION\"\nPOSITIONAL_IGNORE = \"IGNORE\"\nPOSITIONAL_SET = frozenset(\n    [POSITIONAL_WARNING, POSITIONAL_EXCEPTION, POSITIONAL_IGNORE]\n)\n\npositional_parameters_enforcement = POSITIONAL_WARNING\n\n_SYM_LINK_MESSAGE = \"File: {0}: Is a symbolic link.\"\n_IS_DIR_MESSAGE = \"{0}: Is a directory\"\n_MISSING_FILE_MESSAGE = \"Cannot access {0}: No such file or directory\"\n\n\ndef positional(max_positional_args):\n    \"\"\"A decorator to declare that only the first N arguments may be positional.\n\n    This decorator makes it easy to support Python 3 style keyword-only\n    parameters. For example, in Python 3 it is possible to write::\n\n        def fn(pos1, *, kwonly1=None, kwonly1=None):\n            ...\n\n    All named parameters after ``*`` must be a keyword::\n\n        fn(10, 'kw1', 'kw2')  # Raises exception.\n        fn(10, kwonly1='kw1')  # Ok.\n\n    Example\n    ^^^^^^^\n\n    To define a function like above, do::\n\n        @positional(1)\n        def fn(pos1, kwonly1=None, kwonly2=None):\n            ...\n\n    If no default value is provided to a keyword argument, it becomes a\n    required keyword argument::\n\n        @positional(0)\n        def fn(required_kw):\n            ...\n\n    This must be called with the keyword parameter::\n\n        fn()  # Raises exception.\n        fn(10)  # Raises exception.\n        fn(required_kw=10)  # Ok.\n\n    When defining instance or class methods always remember to account for\n    ``self`` and ``cls``::\n\n        class MyClass(object):\n\n            @positional(2)\n            def my_method(self, pos1, kwonly1=None):\n                ...\n\n            @classmethod\n            @positional(2)\n            def my_method(cls, pos1, kwonly1=None):\n                ...\n\n    The positional decorator behavior is controlled by\n    ``_helpers.positional_parameters_enforcement``, which may be set to\n    ``POSITIONAL_EXCEPTION``, ``POSITIONAL_WARNING`` or\n    ``POSITIONAL_IGNORE`` to raise an exception, log a warning, or do\n    nothing, respectively, if a declaration is violated.\n\n    Args:\n        max_positional_arguments: Maximum number of positional arguments. All\n                                  parameters after the this index must be\n                                  keyword only.\n\n    Returns:\n        A decorator that prevents using arguments after max_positional_args\n        from being used as positional parameters.\n\n    Raises:\n        TypeError: if a key-word only argument is provided as a positional\n                   parameter, but only if\n                   _helpers.positional_parameters_enforcement is set to\n                   POSITIONAL_EXCEPTION.\n    \"\"\"\n\n    def positional_decorator(wrapped):\n        @functools.wraps(wrapped)\n        def positional_wrapper(*args, **kwargs):\n            if len(args) > max_positional_args:\n                plural_s = \"\"\n                if max_positional_args != 1:\n                    plural_s = \"s\"\n                message = (\n                    \"{function}() takes at most {args_max} positional \"\n                    \"argument{plural} ({args_given} given)\".format(\n                        function=wrapped.__name__,\n                        args_max=max_positional_args,\n                        args_given=len(args),\n                        plural=plural_s,\n                    )\n                )\n                if positional_parameters_enforcement == POSITIONAL_EXCEPTION:\n                    raise TypeError(message)\n                elif positional_parameters_enforcement == POSITIONAL_WARNING:\n                    logger.warning(message)\n            return wrapped(*args, **kwargs)\n\n        return positional_wrapper\n\n    if isinstance(max_positional_args, six.integer_types):\n        return positional_decorator\n    else:\n        args, _, _, defaults = inspect.getargspec(max_positional_args)\n        return positional(len(args) - len(defaults))(max_positional_args)\n\n\ndef parse_unique_urlencoded(content):\n    \"\"\"Parses unique key-value parameters from urlencoded content.\n\n    Args:\n        content: string, URL-encoded key-value pairs.\n\n    Returns:\n        dict, The key-value pairs from ``content``.\n\n    Raises:\n        ValueError: if one of the keys is repeated.\n    \"\"\"\n    urlencoded_params = urllib.parse.parse_qs(content)\n    params = {}\n    for key, value in six.iteritems(urlencoded_params):\n        if len(value) != 1:\n            msg = \"URL-encoded content contains a repeated value:\" \"%s -> %s\" % (\n                key,\n                \", \".join(value),\n            )\n            raise ValueError(msg)\n        params[key] = value[0]\n    return params\n\n\ndef update_query_params(uri, params):\n    \"\"\"Updates a URI with new query parameters.\n\n    If a given key from ``params`` is repeated in the ``uri``, then\n    the URI will be considered invalid and an error will occur.\n\n    If the URI is valid, then each value from ``params`` will\n    replace the corresponding value in the query parameters (if\n    it exists).\n\n    Args:\n        uri: string, A valid URI, with potential existing query parameters.\n        params: dict, A dictionary of query parameters.\n\n    Returns:\n        The same URI but with the new query parameters added.\n    \"\"\"\n    parts = urllib.parse.urlparse(uri)\n    query_params = parse_unique_urlencoded(parts.query)\n    query_params.update(params)\n    new_query = urllib.parse.urlencode(query_params)\n    new_parts = parts._replace(query=new_query)\n    return urllib.parse.urlunparse(new_parts)\n\n\ndef _add_query_parameter(url, name, value):\n    \"\"\"Adds a query parameter to a url.\n\n    Replaces the current value if it already exists in the URL.\n\n    Args:\n        url: string, url to add the query parameter to.\n        name: string, query parameter name.\n        value: string, query parameter value.\n\n    Returns:\n        Updated query parameter. Does not update the url if value is None.\n    \"\"\"\n    if value is None:\n        return url\n    else:\n        return update_query_params(url, {name: value})\n", "path": "googleapiclient/_helpers.py"}]}