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

Side by Side Diff: third_party/logilab/logilab/astroid/brain/py2stdlib.py

Issue 1920403002: [content/test/gpu] Run pylint check of gpu tests in unittest instead of PRESUBMIT (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update path to LICENSE.txt of logilab/README.chromium Created 4 years, 7 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
2 """Astroid hooks for the Python 2 standard library.
3
4 Currently help understanding of :
5
6 * hashlib.md5 and hashlib.sha1
7 """
8
9 import sys
10 from functools import partial
11 from textwrap import dedent
12
13 from astroid import (
14 MANAGER, AsStringRegexpPredicate,
15 UseInferenceDefault, inference_tip,
16 YES, InferenceError, register_module_extender)
17 from astroid import exceptions
18 from astroid import nodes
19 from astroid.builder import AstroidBuilder
20
21 PY3K = sys.version_info > (3, 0)
22 PY33 = sys.version_info >= (3, 3)
23
24 # general function
25
26 def infer_func_form(node, base_type, context=None, enum=False):
27 """Specific inference function for namedtuple or Python 3 enum. """
28 def infer_first(node):
29 try:
30 value = next(node.infer(context=context))
31 if value is YES:
32 raise UseInferenceDefault()
33 else:
34 return value
35 except StopIteration:
36 raise InferenceError()
37
38 # node is a CallFunc node, class name as first argument and generated class
39 # attributes as second argument
40 if len(node.args) != 2:
41 # something weird here, go back to class implementation
42 raise UseInferenceDefault()
43 # namedtuple or enums list of attributes can be a list of strings or a
44 # whitespace-separate string
45 try:
46 name = infer_first(node.args[0]).value
47 names = infer_first(node.args[1])
48 try:
49 attributes = names.value.replace(',', ' ').split()
50 except AttributeError:
51 if not enum:
52 attributes = [infer_first(const).value for const in names.elts]
53 else:
54 # Enums supports either iterator of (name, value) pairs
55 # or mappings.
56 # TODO: support only list, tuples and mappings.
57 if hasattr(names, 'items') and isinstance(names.items, list):
58 attributes = [infer_first(const[0]).value
59 for const in names.items
60 if isinstance(const[0], nodes.Const)]
61 elif hasattr(names, 'elts'):
62 # Enums can support either ["a", "b", "c"]
63 # or [("a", 1), ("b", 2), ...], but they can't
64 # be mixed.
65 if all(isinstance(const, nodes.Tuple)
66 for const in names.elts):
67 attributes = [infer_first(const.elts[0]).value
68 for const in names.elts
69 if isinstance(const, nodes.Tuple)]
70 else:
71 attributes = [infer_first(const).value
72 for const in names.elts]
73 else:
74 raise AttributeError
75 if not attributes:
76 raise AttributeError
77 except (AttributeError, exceptions.InferenceError) as exc:
78 raise UseInferenceDefault()
79 # we want to return a Class node instance with proper attributes set
80 class_node = nodes.Class(name, 'docstring')
81 class_node.parent = node.parent
82 # set base class=tuple
83 class_node.bases.append(base_type)
84 # XXX add __init__(*attributes) method
85 for attr in attributes:
86 fake_node = nodes.EmptyNode()
87 fake_node.parent = class_node
88 class_node.instance_attrs[attr] = [fake_node]
89 return class_node, name, attributes
90
91
92 # module specific transformation functions #####################################
93
94 def hashlib_transform():
95 template = '''
96
97 class %(name)s(object):
98 def __init__(self, value=''): pass
99 def digest(self):
100 return %(digest)s
101 def copy(self):
102 return self
103 def update(self, value): pass
104 def hexdigest(self):
105 return ''
106 @property
107 def name(self):
108 return %(name)r
109 @property
110 def block_size(self):
111 return 1
112 @property
113 def digest_size(self):
114 return 1
115 '''
116 algorithms = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512')
117 classes = "".join(
118 template % {'name': hashfunc, 'digest': 'b""' if PY3K else '""'}
119 for hashfunc in algorithms)
120 return AstroidBuilder(MANAGER).string_build(classes)
121
122
123 def collections_transform():
124 return AstroidBuilder(MANAGER).string_build('''
125
126 class defaultdict(dict):
127 default_factory = None
128 def __missing__(self, key): pass
129
130 class deque(object):
131 maxlen = 0
132 def __init__(self, iterable=None, maxlen=None): pass
133 def append(self, x): pass
134 def appendleft(self, x): pass
135 def clear(self): pass
136 def count(self, x): return 0
137 def extend(self, iterable): pass
138 def extendleft(self, iterable): pass
139 def pop(self): pass
140 def popleft(self): pass
141 def remove(self, value): pass
142 def reverse(self): pass
143 def rotate(self, n): pass
144 def __iter__(self): return self
145
146 ''')
147
148
149 def pkg_resources_transform():
150 return AstroidBuilder(MANAGER).string_build('''
151
152 def resource_exists(package_or_requirement, resource_name):
153 pass
154
155 def resource_isdir(package_or_requirement, resource_name):
156 pass
157
158 def resource_filename(package_or_requirement, resource_name):
159 pass
160
161 def resource_stream(package_or_requirement, resource_name):
162 pass
163
164 def resource_string(package_or_requirement, resource_name):
165 pass
166
167 def resource_listdir(package_or_requirement, resource_name):
168 pass
169
170 def extraction_error():
171 pass
172
173 def get_cache_path(archive_name, names=()):
174 pass
175
176 def postprocess(tempname, filename):
177 pass
178
179 def set_extraction_path(path):
180 pass
181
182 def cleanup_resources(force=False):
183 pass
184
185 ''')
186
187
188 def subprocess_transform():
189 if PY3K:
190 communicate = (bytes('string', 'ascii'), bytes('string', 'ascii'))
191 init = """
192 def __init__(self, args, bufsize=0, executable=None,
193 stdin=None, stdout=None, stderr=None,
194 preexec_fn=None, close_fds=False, shell=False,
195 cwd=None, env=None, universal_newlines=False,
196 startupinfo=None, creationflags=0, restore_signals=True,
197 start_new_session=False, pass_fds=()):
198 pass
199 """
200 else:
201 communicate = ('string', 'string')
202 init = """
203 def __init__(self, args, bufsize=0, executable=None,
204 stdin=None, stdout=None, stderr=None,
205 preexec_fn=None, close_fds=False, shell=False,
206 cwd=None, env=None, universal_newlines=False,
207 startupinfo=None, creationflags=0):
208 pass
209 """
210 if PY33:
211 wait_signature = 'def wait(self, timeout=None)'
212 else:
213 wait_signature = 'def wait(self)'
214 return AstroidBuilder(MANAGER).string_build('''
215
216 class Popen(object):
217 returncode = pid = 0
218 stdin = stdout = stderr = file()
219
220 %(init)s
221
222 def communicate(self, input=None):
223 return %(communicate)r
224 %(wait_signature)s:
225 return self.returncode
226 def poll(self):
227 return self.returncode
228 def send_signal(self, signal):
229 pass
230 def terminate(self):
231 pass
232 def kill(self):
233 pass
234 ''' % {'init': init,
235 'communicate': communicate,
236 'wait_signature': wait_signature})
237
238
239 # namedtuple support ###########################################################
240
241 def looks_like_namedtuple(node):
242 func = node.func
243 if type(func) is nodes.Getattr:
244 return func.attrname == 'namedtuple'
245 if type(func) is nodes.Name:
246 return func.name == 'namedtuple'
247 return False
248
249 def infer_named_tuple(node, context=None):
250 """Specific inference function for namedtuple CallFunc node"""
251 class_node, name, attributes = infer_func_form(node, nodes.Tuple._proxied,
252 context=context)
253 fake = AstroidBuilder(MANAGER).string_build('''
254 class %(name)s(tuple):
255 _fields = %(fields)r
256 def _asdict(self):
257 return self.__dict__
258 @classmethod
259 def _make(cls, iterable, new=tuple.__new__, len=len):
260 return new(cls, iterable)
261 def _replace(_self, **kwds):
262 result = _self._make(map(kwds.pop, %(fields)r, _self))
263 if kwds:
264 raise ValueError('Got unexpected field names: %%r' %% list(kwds))
265 return result
266 ''' % {'name': name, 'fields': attributes})
267 class_node.locals['_asdict'] = fake.body[0].locals['_asdict']
268 class_node.locals['_make'] = fake.body[0].locals['_make']
269 class_node.locals['_replace'] = fake.body[0].locals['_replace']
270 class_node.locals['_fields'] = fake.body[0].locals['_fields']
271 # we use UseInferenceDefault, we can't be a generator so return an iterator
272 return iter([class_node])
273
274 def infer_enum(node, context=None):
275 """ Specific inference function for enum CallFunc node. """
276 enum_meta = nodes.Class("EnumMeta", 'docstring')
277 class_node = infer_func_form(node, enum_meta,
278 context=context, enum=True)[0]
279 return iter([class_node.instanciate_class()])
280
281 def infer_enum_class(node):
282 """ Specific inference for enums. """
283 names = set(('Enum', 'IntEnum', 'enum.Enum', 'enum.IntEnum'))
284 for basename in node.basenames:
285 # TODO: doesn't handle subclasses yet. This implementation
286 # is a hack to support enums.
287 if basename not in names:
288 continue
289 if node.root().name == 'enum':
290 # Skip if the class is directly from enum module.
291 break
292 for local, values in node.locals.items():
293 if any(not isinstance(value, nodes.AssName)
294 for value in values):
295 continue
296
297 stmt = values[0].statement()
298 if isinstance(stmt.targets[0], nodes.Tuple):
299 targets = stmt.targets[0].itered()
300 else:
301 targets = stmt.targets
302
303 new_targets = []
304 for target in targets:
305 # Replace all the assignments with our mocked class.
306 classdef = dedent('''
307 class %(name)s(object):
308 @property
309 def value(self):
310 # Not the best return.
311 return None
312 @property
313 def name(self):
314 return %(name)r
315 ''' % {'name': target.name})
316 fake = AstroidBuilder(MANAGER).string_build(classdef)[target.nam e]
317 fake.parent = target.parent
318 for method in node.mymethods():
319 fake.locals[method.name] = [method]
320 new_targets.append(fake.instanciate_class())
321 node.locals[local] = new_targets
322 break
323 return node
324
325
326 MANAGER.register_transform(nodes.CallFunc, inference_tip(infer_named_tuple),
327 looks_like_namedtuple)
328 MANAGER.register_transform(nodes.CallFunc, inference_tip(infer_enum),
329 AsStringRegexpPredicate('Enum', 'func'))
330 MANAGER.register_transform(nodes.Class, infer_enum_class)
331 register_module_extender(MANAGER, 'hashlib', hashlib_transform)
332 register_module_extender(MANAGER, 'collections', collections_transform)
333 register_module_extender(MANAGER, 'pkg_resources', pkg_resources_transform)
334 register_module_extender(MANAGER, 'subprocess', subprocess_transform)
OLDNEW
« no previous file with comments | « third_party/logilab/logilab/astroid/brain/py2qt4.py ('k') | third_party/logilab/logilab/astroid/brain/pynose.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698