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

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

Issue 1260293009: make version of ts_mon compatible with appengine (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: clean up code Created 5 years, 4 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
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 ] 23 ]
26 24
27 import gflags 25 __all__ = [
26 'positional',
27 'POSITIONAL_WARNING',
28 'POSITIONAL_EXCEPTION',
29 'POSITIONAL_IGNORE',
30 ]
31
32 import functools
28 import inspect 33 import inspect
29 import logging 34 import logging
35 import sys
30 import types 36 import types
31 import urllib
32 import urlparse
33 37
34 try: 38 import six
35 from urlparse import parse_qsl 39 from six.moves import urllib
36 except ImportError: 40
37 from cgi import parse_qsl
38 41
39 logger = logging.getLogger(__name__) 42 logger = logging.getLogger(__name__)
40 43
41 FLAGS = gflags.FLAGS 44 POSITIONAL_WARNING = 'WARNING'
45 POSITIONAL_EXCEPTION = 'EXCEPTION'
46 POSITIONAL_IGNORE = 'IGNORE'
47 POSITIONAL_SET = frozenset([POSITIONAL_WARNING, POSITIONAL_EXCEPTION,
48 POSITIONAL_IGNORE])
42 49
43 gflags.DEFINE_enum('positional_parameters_enforcement', 'WARNING', 50 positional_parameters_enforcement = POSITIONAL_WARNING
44 ['EXCEPTION', 'WARNING', 'IGNORE'],
45 'The action when an oauth2client.util.positional declaration is violated.')
46
47 51
48 def positional(max_positional_args): 52 def positional(max_positional_args):
49 """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.
50 54
51 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
52 parameters. For example, in Python 3 it is possible to write: 56 parameters. For example, in Python 3 it is possible to write::
53 57
54 def fn(pos1, *, kwonly1=None, kwonly1=None): 58 def fn(pos1, *, kwonly1=None, kwonly1=None):
55 ... 59 ...
56 60
57 All named parameters after * must be a keyword: 61 All named parameters after ``*`` must be a keyword::
58 62
59 fn(10, 'kw1', 'kw2') # Raises exception. 63 fn(10, 'kw1', 'kw2') # Raises exception.
60 fn(10, kwonly1='kw1') # Ok. 64 fn(10, kwonly1='kw1') # Ok.
61 65
62 Example: 66 Example
63 To define a function like above, do: 67 ^^^^^^^
64 68
65 @positional(1) 69 To define a function like above, do::
66 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):
67 ... 95 ...
68 96
69 If no default value is provided to a keyword argument, it becomes a required 97 @classmethod
70 keyword argument: 98 @positional(2)
71 99 def my_method(cls, pos1, kwonly1=None):
72 @positional(0)
73 def fn(required_kw):
74 ... 100 ...
75 101
76 This must be called with the keyword parameter: 102 The positional decorator behavior is controlled by
77 103 ``util.positional_parameters_enforcement``, which may be set to
78 fn() # Raises exception. 104 ``POSITIONAL_EXCEPTION``, ``POSITIONAL_WARNING`` or
79 fn(10) # Raises exception. 105 ``POSITIONAL_IGNORE`` to raise an exception, log a warning, or do
80 fn(required_kw=10) # Ok. 106 nothing, respectively, if a declaration is violated.
81
82 When defining instance or class methods always remember to account for
83 'self' and 'cls':
84
85 class MyClass(object):
86
87 @positional(2)
88 def my_method(self, pos1, kwonly1=None):
89 ...
90
91 @classmethod
92 @positional(2)
93 def my_method(cls, pos1, kwonly1=None):
94 ...
95
96 The positional decorator behavior is controlled by the
97 --positional_parameters_enforcement flag. The flag may be set to 'EXCEPTION',
98 'WARNING' or 'IGNORE' to raise an exception, log a warning, or do nothing,
99 respectively, if a declaration is violated.
100 107
101 Args: 108 Args:
102 max_positional_arguments: Maximum number of positional arguments. All 109 max_positional_arguments: Maximum number of positional arguments. All
103 parameters after the this index must be keyword only. 110 parameters after the this index must be keyword only.
104 111
105 Returns: 112 Returns:
106 A decorator that prevents using arguments after max_positional_args from 113 A decorator that prevents using arguments after max_positional_args from
107 being used as positional parameters. 114 being used as positional parameters.
108 115
109 Raises: 116 Raises:
110 TypeError if a key-word only argument is provided as a positional parameter, 117 TypeError if a key-word only argument is provided as a positional
111 but only if the --positional_parameters_enforcement flag is set to 118 parameter, but only if util.positional_parameters_enforcement is set to
112 'EXCEPTION'. 119 POSITIONAL_EXCEPTION.
120
113 """ 121 """
114 def positional_decorator(wrapped): 122 def positional_decorator(wrapped):
123 @functools.wraps(wrapped)
115 def positional_wrapper(*args, **kwargs): 124 def positional_wrapper(*args, **kwargs):
116 if len(args) > max_positional_args: 125 if len(args) > max_positional_args:
117 plural_s = '' 126 plural_s = ''
118 if max_positional_args != 1: 127 if max_positional_args != 1:
119 plural_s = 's' 128 plural_s = 's'
120 message = '%s() takes at most %d positional argument%s (%d given)' % ( 129 message = '%s() takes at most %d positional argument%s (%d given)' % (
121 wrapped.__name__, max_positional_args, plural_s, len(args)) 130 wrapped.__name__, max_positional_args, plural_s, len(args))
122 if FLAGS.positional_parameters_enforcement == 'EXCEPTION': 131 if positional_parameters_enforcement == POSITIONAL_EXCEPTION:
123 raise TypeError(message) 132 raise TypeError(message)
124 elif FLAGS.positional_parameters_enforcement == 'WARNING': 133 elif positional_parameters_enforcement == POSITIONAL_WARNING:
125 logger.warning(message) 134 logger.warning(message)
126 else: # IGNORE 135 else: # IGNORE
127 pass 136 pass
128 return wrapped(*args, **kwargs) 137 return wrapped(*args, **kwargs)
129 return positional_wrapper 138 return positional_wrapper
130 139
131 if isinstance(max_positional_args, (int, long)): 140 if isinstance(max_positional_args, six.integer_types):
132 return positional_decorator 141 return positional_decorator
133 else: 142 else:
134 args, _, _, defaults = inspect.getargspec(max_positional_args) 143 args, _, _, defaults = inspect.getargspec(max_positional_args)
135 return positional(len(args) - len(defaults))(max_positional_args) 144 return positional(len(args) - len(defaults))(max_positional_args)
136 145
137 146
138 def scopes_to_string(scopes): 147 def scopes_to_string(scopes):
139 """Converts scope value to a string. 148 """Converts scope value to a string.
140 149
141 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
142 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
143 concatenated with spaces. 152 concatenated with spaces.
144 153
145 Args: 154 Args:
146 scopes: string or iterable of strings, the scopes. 155 scopes: string or iterable of strings, the scopes.
147 156
148 Returns: 157 Returns:
149 The scopes formatted as a single string. 158 The scopes formatted as a single string.
150 """ 159 """
151 if isinstance(scopes, types.StringTypes): 160 if isinstance(scopes, six.string_types):
152 return scopes 161 return scopes
153 else: 162 else:
154 return ' '.join(scopes) 163 return ' '.join(scopes)
155 164
156 165
157 def dict_to_tuple_key(dictionary): 166 def dict_to_tuple_key(dictionary):
158 """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.
159 168
160 The resulting key is always sorted so that logically equivalent dictionaries 169 The resulting key is always sorted so that logically equivalent dictionaries
161 always produce an identical tuple for a key. 170 always produce an identical tuple for a key.
(...skipping 16 matching lines...) Expand all
178 url: string, url to add the query parameter to. 187 url: string, url to add the query parameter to.
179 name: string, query parameter name. 188 name: string, query parameter name.
180 value: string, query parameter value. 189 value: string, query parameter value.
181 190
182 Returns: 191 Returns:
183 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.
184 """ 193 """
185 if value is None: 194 if value is None:
186 return url 195 return url
187 else: 196 else:
188 parsed = list(urlparse.urlparse(url)) 197 parsed = list(urllib.parse.urlparse(url))
189 q = dict(parse_qsl(parsed[4])) 198 q = dict(urllib.parse.parse_qsl(parsed[4]))
190 q[name] = value 199 q[name] = value
191 parsed[4] = urllib.urlencode(q) 200 parsed[4] = urllib.parse.urlencode(q)
192 return urlparse.urlunparse(parsed) 201 return urllib.parse.urlunparse(parsed)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698