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

Side by Side Diff: third_party/oauth2client/util.py

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

Powered by Google App Engine
This is Rietveld 408576698