Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(565)

Side by Side Diff: third_party/google-endpoints/oauth2client/util.py

Issue 2666783008: Add google-endpoints to third_party/. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 #
3 # Copyright 2014 Google Inc. All rights reserved.
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 #
17
18 """Common utility library."""
19
20 import functools
21 import inspect
22 import logging
23
24 import six
25 from six.moves import urllib
26
27
28 __author__ = [
29 'rafek@google.com (Rafe Kaplan)',
30 'guido@google.com (Guido van Rossum)',
31 ]
32
33 __all__ = [
34 'positional',
35 'POSITIONAL_WARNING',
36 'POSITIONAL_EXCEPTION',
37 'POSITIONAL_IGNORE',
38 ]
39
40 logger = logging.getLogger(__name__)
41
42 POSITIONAL_WARNING = 'WARNING'
43 POSITIONAL_EXCEPTION = 'EXCEPTION'
44 POSITIONAL_IGNORE = 'IGNORE'
45 POSITIONAL_SET = frozenset([POSITIONAL_WARNING, POSITIONAL_EXCEPTION,
46 POSITIONAL_IGNORE])
47
48 positional_parameters_enforcement = POSITIONAL_WARNING
49
50
51 def positional(max_positional_args):
52 """A decorator to declare that only the first N arguments my be positional.
53
54 This decorator makes it easy to support Python 3 style keyword-only
55 parameters. For example, in Python 3 it is possible to write::
56
57 def fn(pos1, *, kwonly1=None, kwonly1=None):
58 ...
59
60 All named parameters after ``*`` must be a keyword::
61
62 fn(10, 'kw1', 'kw2') # Raises exception.
63 fn(10, kwonly1='kw1') # Ok.
64
65 Example
66 ^^^^^^^
67
68 To define a function like above, do::
69
70 @positional(1)
71 def fn(pos1, kwonly1=None, kwonly2=None):
72 ...
73
74 If no default value is provided to a keyword argument, it becomes a
75 required keyword argument::
76
77 @positional(0)
78 def fn(required_kw):
79 ...
80
81 This must be called with the keyword parameter::
82
83 fn() # Raises exception.
84 fn(10) # Raises exception.
85 fn(required_kw=10) # Ok.
86
87 When defining instance or class methods always remember to account for
88 ``self`` and ``cls``::
89
90 class MyClass(object):
91
92 @positional(2)
93 def my_method(self, pos1, kwonly1=None):
94 ...
95
96 @classmethod
97 @positional(2)
98 def my_method(cls, pos1, kwonly1=None):
99 ...
100
101 The positional decorator behavior is controlled by
102 ``util.positional_parameters_enforcement``, which may be set to
103 ``POSITIONAL_EXCEPTION``, ``POSITIONAL_WARNING`` or
104 ``POSITIONAL_IGNORE`` to raise an exception, log a warning, or do
105 nothing, respectively, if a declaration is violated.
106
107 Args:
108 max_positional_arguments: Maximum number of positional arguments. All
109 parameters after the this index must be
110 keyword only.
111
112 Returns:
113 A decorator that prevents using arguments after max_positional_args
114 from being used as positional parameters.
115
116 Raises:
117 TypeError: if a key-word only argument is provided as a positional
118 parameter, but only if
119 util.positional_parameters_enforcement is set to
120 POSITIONAL_EXCEPTION.
121 """
122
123 def positional_decorator(wrapped):
124 @functools.wraps(wrapped)
125 def positional_wrapper(*args, **kwargs):
126 if len(args) > max_positional_args:
127 plural_s = ''
128 if max_positional_args != 1:
129 plural_s = 's'
130 message = ('%s() takes at most %d positional '
131 'argument%s (%d given)' % (
132 wrapped.__name__, max_positional_args,
133 plural_s, len(args)))
134 if positional_parameters_enforcement == POSITIONAL_EXCEPTION:
135 raise TypeError(message)
136 elif positional_parameters_enforcement == POSITIONAL_WARNING:
137 logger.warning(message)
138 else: # IGNORE
139 pass
140 return wrapped(*args, **kwargs)
141 return positional_wrapper
142
143 if isinstance(max_positional_args, six.integer_types):
144 return positional_decorator
145 else:
146 args, _, _, defaults = inspect.getargspec(max_positional_args)
147 return positional(len(args) - len(defaults))(max_positional_args)
148
149
150 def scopes_to_string(scopes):
151 """Converts scope value to a string.
152
153 If scopes is a string then it is simply passed through. If scopes is an
154 iterable then a string is returned that is all the individual scopes
155 concatenated with spaces.
156
157 Args:
158 scopes: string or iterable of strings, the scopes.
159
160 Returns:
161 The scopes formatted as a single string.
162 """
163 if isinstance(scopes, six.string_types):
164 return scopes
165 else:
166 return ' '.join(scopes)
167
168
169 def string_to_scopes(scopes):
170 """Converts stringifed scope value to a list.
171
172 If scopes is a list then it is simply passed through. If scopes is an
173 string then a list of each individual scope is returned.
174
175 Args:
176 scopes: a string or iterable of strings, the scopes.
177
178 Returns:
179 The scopes in a list.
180 """
181 if not scopes:
182 return []
183 if isinstance(scopes, six.string_types):
184 return scopes.split(' ')
185 else:
186 return scopes
187
188
189 def dict_to_tuple_key(dictionary):
190 """Converts a dictionary to a tuple that can be used as an immutable key.
191
192 The resulting key is always sorted so that logically equivalent
193 dictionaries always produce an identical tuple for a key.
194
195 Args:
196 dictionary: the dictionary to use as the key.
197
198 Returns:
199 A tuple representing the dictionary in it's naturally sorted ordering.
200 """
201 return tuple(sorted(dictionary.items()))
202
203
204 def _add_query_parameter(url, name, value):
205 """Adds a query parameter to a url.
206
207 Replaces the current value if it already exists in the URL.
208
209 Args:
210 url: string, url to add the query parameter to.
211 name: string, query parameter name.
212 value: string, query parameter value.
213
214 Returns:
215 Updated query parameter. Does not update the url if value is None.
216 """
217 if value is None:
218 return url
219 else:
220 parsed = list(urllib.parse.urlparse(url))
221 q = dict(urllib.parse.parse_qsl(parsed[4]))
222 q[name] = value
223 parsed[4] = urllib.parse.urlencode(q)
224 return urllib.parse.urlunparse(parsed)
OLDNEW
« no previous file with comments | « third_party/google-endpoints/oauth2client/tools.py ('k') | third_party/google-endpoints/oauth2client/xsrfutil.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698