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

Side by Side Diff: third_party/logilab/astng/raw_building.py

Issue 719313003: Revert "pylint: upgrade to 1.3.1" (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Created 6 years, 1 month 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
« no previous file with comments | « third_party/logilab/astng/protocols.py ('k') | third_party/logilab/astng/rebuilder.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved. 1 # copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr 2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
3 # copyright 2003-2010 Sylvain Thenault, all rights reserved.
4 # contact mailto:thenault@gmail.com
3 # 5 #
4 # This file is part of astroid. 6 # This file is part of logilab-astng.
5 # 7 #
6 # astroid is free software: you can redistribute it and/or modify it 8 # logilab-astng is free software: you can redistribute it and/or modify it
7 # under the terms of the GNU Lesser General Public License as published by the 9 # under the terms of the GNU Lesser General Public License as published by the
8 # Free Software Foundation, either version 2.1 of the License, or (at your 10 # Free Software Foundation, either version 2.1 of the License, or (at your
9 # option) any later version. 11 # option) any later version.
10 # 12 #
11 # astroid is distributed in the hope that it will be useful, but 13 # logilab-astng is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
14 # for more details. 16 # for more details.
15 # 17 #
16 # You should have received a copy of the GNU Lesser General Public License along 18 # You should have received a copy of the GNU Lesser General Public License along
17 # with astroid. If not, see <http://www.gnu.org/licenses/>. 19 # with logilab-astng. If not, see <http://www.gnu.org/licenses/>.
18 """this module contains a set of functions to create astroid trees from scratch 20 """this module contains a set of functions to create astng trees from scratch
19 (build_* functions) or from living object (object_build_* functions) 21 (build_* functions) or from living object (object_build_* functions)
20 """ 22 """
21 23
22 __docformat__ = "restructuredtext en" 24 __docformat__ = "restructuredtext en"
23 25
24 import sys 26 import sys
25 from os.path import abspath 27 from os.path import abspath
26 from inspect import (getargspec, isdatadescriptor, isfunction, ismethod, 28 from inspect import (getargspec, isdatadescriptor, isfunction, ismethod,
27 ismethoddescriptor, isclass, isbuiltin, ismodule) 29 ismethoddescriptor, isclass, isbuiltin)
28 30
29 from astroid.node_classes import CONST_CLS 31 from logilab.astng import BUILTINS_MODULE
30 from astroid.nodes import (Module, Class, Const, const_factory, From, 32 from logilab.astng.node_classes import CONST_CLS
31 Function, EmptyNode, Name, Arguments) 33 from logilab.astng.nodes import (Module, Class, Const, const_factory, From,
32 from astroid.bases import BUILTINS, Generator 34 Function, EmptyNode, Name, Arguments, Dict, List, Set, Tuple)
33 from astroid.manager import AstroidManager 35 from logilab.astng.bases import Generator
34 MANAGER = AstroidManager() 36 from logilab.astng.manager import ASTNGManager
37 MANAGER = ASTNGManager()
35 38
36 _CONSTANTS = tuple(CONST_CLS) # the keys of CONST_CLS eg python builtin types 39 _CONSTANTS = tuple(CONST_CLS) # the keys of CONST_CLS eg python builtin types
37 40
38 def _io_discrepancy(member):
39 # _io module names itself `io`: http://bugs.python.org/issue18602
40 member_self = getattr(member, '__self__', None)
41 return (member_self and
42 ismodule(member_self) and
43 member_self.__name__ == '_io' and
44 member.__module__ == 'io')
45
46 def _attach_local_node(parent, node, name): 41 def _attach_local_node(parent, node, name):
47 node.name = name # needed by add_local_node 42 node.name = name # needed by add_local_node
48 parent.add_local_node(node) 43 parent.add_local_node(node)
49 44
50 _marker = object() 45 _marker = object()
51 46
52 def attach_dummy_node(node, name, object=_marker): 47 def attach_dummy_node(node, name, object=_marker):
53 """create a dummy node and register it in the locals of the given 48 """create a dummy node and register it in the locals of the given
54 node with the specified name 49 node with the specified name
55 """ 50 """
(...skipping 12 matching lines...) Expand all
68 63
69 def attach_import_node(node, modname, membername): 64 def attach_import_node(node, modname, membername):
70 """create a From node and register it in the locals of the given 65 """create a From node and register it in the locals of the given
71 node with the specified name 66 node with the specified name
72 """ 67 """
73 from_node = From(modname, [(membername, None)]) 68 from_node = From(modname, [(membername, None)])
74 _attach_local_node(node, from_node, membername) 69 _attach_local_node(node, from_node, membername)
75 70
76 71
77 def build_module(name, doc=None): 72 def build_module(name, doc=None):
78 """create and initialize a astroid Module node""" 73 """create and initialize a astng Module node"""
79 node = Module(name, doc, pure_python=False) 74 node = Module(name, doc, pure_python=False)
80 node.package = False 75 node.package = False
81 node.parent = None 76 node.parent = None
82 return node 77 return node
83 78
84 def build_class(name, basenames=(), doc=None): 79 def build_class(name, basenames=(), doc=None):
85 """create and initialize a astroid Class node""" 80 """create and initialize a astng Class node"""
86 node = Class(name, doc) 81 node = Class(name, doc)
87 for base in basenames: 82 for base in basenames:
88 basenode = Name() 83 basenode = Name()
89 basenode.name = base 84 basenode.name = base
90 node.bases.append(basenode) 85 node.bases.append(basenode)
91 basenode.parent = node 86 basenode.parent = node
92 return node 87 return node
93 88
94 def build_function(name, args=None, defaults=None, flag=0, doc=None): 89 def build_function(name, args=None, defaults=None, flag=0, doc=None):
95 """create and initialize a astroid Function node""" 90 """create and initialize a astng Function node"""
96 args, defaults = args or [], defaults or [] 91 args, defaults = args or [], defaults or []
97 # first argument is now a list of decorators 92 # first argument is now a list of decorators
98 func = Function(name, doc) 93 func = Function(name, doc)
99 func.args = argsnode = Arguments() 94 func.args = argsnode = Arguments()
100 argsnode.args = [] 95 argsnode.args = []
101 for arg in args: 96 for arg in args:
102 argsnode.args.append(Name()) 97 argsnode.args.append(Name())
103 argsnode.args[-1].name = arg 98 argsnode.args[-1].name = arg
104 argsnode.args[-1].parent = argsnode 99 argsnode.args[-1].parent = argsnode
105 argsnode.defaults = [] 100 argsnode.defaults = []
106 for default in defaults: 101 for default in defaults:
107 argsnode.defaults.append(const_factory(default)) 102 argsnode.defaults.append(const_factory(default))
108 argsnode.defaults[-1].parent = argsnode 103 argsnode.defaults[-1].parent = argsnode
109 argsnode.kwarg = None 104 argsnode.kwarg = None
110 argsnode.vararg = None 105 argsnode.vararg = None
111 argsnode.parent = func 106 argsnode.parent = func
112 if args: 107 if args:
113 register_arguments(func) 108 register_arguments(func)
114 return func 109 return func
115 110
116 111
117 def build_from_import(fromname, names): 112 def build_from_import(fromname, names):
118 """create and initialize an astroid From import statement""" 113 """create and initialize an astng From import statement"""
119 return From(fromname, [(name, None) for name in names]) 114 return From(fromname, [(name, None) for name in names])
120 115
121 def register_arguments(func, args=None): 116 def register_arguments(func, args=None):
122 """add given arguments to local 117 """add given arguments to local
123 118
124 args is a list that may contains nested lists 119 args is a list that may contains nested lists
125 (i.e. def func(a, (b, c, d)): ...) 120 (i.e. def func(a, (b, c, d)): ...)
126 """ 121 """
127 if args is None: 122 if args is None:
128 args = func.args.args 123 args = func.args.args
129 if func.args.vararg: 124 if func.args.vararg:
130 func.set_local(func.args.vararg, func.args) 125 func.set_local(func.args.vararg, func.args)
131 if func.args.kwarg: 126 if func.args.kwarg:
132 func.set_local(func.args.kwarg, func.args) 127 func.set_local(func.args.kwarg, func.args)
133 for arg in args: 128 for arg in args:
134 if isinstance(arg, Name): 129 if isinstance(arg, Name):
135 func.set_local(arg.name, arg) 130 func.set_local(arg.name, arg)
136 else: 131 else:
137 register_arguments(func, arg.elts) 132 register_arguments(func, arg.elts)
138 133
139 def object_build_class(node, member, localname): 134 def object_build_class(node, member, localname):
140 """create astroid for a living class object""" 135 """create astng for a living class object"""
141 basenames = [base.__name__ for base in member.__bases__] 136 basenames = [base.__name__ for base in member.__bases__]
142 return _base_class_object_build(node, member, basenames, 137 return _base_class_object_build(node, member, basenames,
143 localname=localname) 138 localname=localname)
144 139
145 def object_build_function(node, member, localname): 140 def object_build_function(node, member, localname):
146 """create astroid for a living function object""" 141 """create astng for a living function object"""
147 args, varargs, varkw, defaults = getargspec(member) 142 args, varargs, varkw, defaults = getargspec(member)
148 if varargs is not None: 143 if varargs is not None:
149 args.append(varargs) 144 args.append(varargs)
150 if varkw is not None: 145 if varkw is not None:
151 args.append(varkw) 146 args.append(varkw)
152 func = build_function(getattr(member, '__name__', None) or localname, args, 147 func = build_function(getattr(member, '__name__', None) or localname, args,
153 defaults, member.func_code.co_flags, member.__doc__) 148 defaults, member.func_code.co_flags, member.__doc__)
154 node.add_local_node(func, localname) 149 node.add_local_node(func, localname)
155 150
156 def object_build_datadescriptor(node, member, name): 151 def object_build_datadescriptor(node, member, name):
157 """create astroid for a living data descriptor object""" 152 """create astng for a living data descriptor object"""
158 return _base_class_object_build(node, member, [], name) 153 return _base_class_object_build(node, member, [], name)
159 154
160 def object_build_methoddescriptor(node, member, localname): 155 def object_build_methoddescriptor(node, member, localname):
161 """create astroid for a living method descriptor object""" 156 """create astng for a living method descriptor object"""
162 # FIXME get arguments ? 157 # FIXME get arguments ?
163 func = build_function(getattr(member, '__name__', None) or localname, 158 func = build_function(getattr(member, '__name__', None) or localname,
164 doc=member.__doc__) 159 doc=member.__doc__)
165 # set node's arguments to None to notice that we have no information, not 160 # set node's arguments to None to notice that we have no information, not
166 # and empty argument list 161 # and empty argument list
167 func.args.args = None 162 func.args.args = None
168 node.add_local_node(func, localname) 163 node.add_local_node(func, localname)
169 164
170 def _base_class_object_build(node, member, basenames, name=None, localname=None) : 165 def _base_class_object_build(node, member, basenames, name=None, localname=None) :
171 """create astroid for a living class object, with a given set of base names 166 """create astng for a living class object, with a given set of base names
172 (e.g. ancestors) 167 (e.g. ancestors)
173 """ 168 """
174 klass = build_class(name or getattr(member, '__name__', None) or localname, 169 klass = build_class(name or getattr(member, '__name__', None) or localname,
175 basenames, member.__doc__) 170 basenames, member.__doc__)
176 klass._newstyle = isinstance(member, type) 171 klass._newstyle = isinstance(member, type)
177 node.add_local_node(klass, localname) 172 node.add_local_node(klass, localname)
178 try: 173 try:
179 # limit the instantiation trick since it's too dangerous 174 # limit the instantiation trick since it's too dangerous
180 # (such as infinite test execution...) 175 # (such as infinite test execution...)
181 # this at least resolves common case such as Exception.args, 176 # this at least resolves common case such as Exception.args,
(...skipping 16 matching lines...) Expand all
198 193
199 194
200 195
201 class InspectBuilder(object): 196 class InspectBuilder(object):
202 """class for building nodes from living object 197 """class for building nodes from living object
203 198
204 this is actually a really minimal representation, including only Module, 199 this is actually a really minimal representation, including only Module,
205 Function and Class nodes and some others as guessed. 200 Function and Class nodes and some others as guessed.
206 """ 201 """
207 202
208 # astroid from living objects ############################################## # 203 # astng from living objects ###############################################
209 204
210 def __init__(self): 205 def __init__(self):
211 self._done = {} 206 self._done = {}
212 self._module = None 207 self._module = None
213 208
214 def inspect_build(self, module, modname=None, path=None): 209 def inspect_build(self, module, modname=None, path=None):
215 """build astroid from a living module (i.e. using inspect) 210 """build astng from a living module (i.e. using inspect)
216 this is used when there is no python source code available (either 211 this is used when there is no python source code available (either
217 because it's a built-in module or because the .py is not available) 212 because it's a built-in module or because the .py is not available)
218 """ 213 """
219 self._module = module 214 self._module = module
220 if modname is None: 215 if modname is None:
221 modname = module.__name__ 216 modname = module.__name__
222 try: 217 node = build_module(modname, module.__doc__)
223 node = build_module(modname, module.__doc__)
224 except AttributeError:
225 # in jython, java modules have no __doc__ (see #109562)
226 node = build_module(modname)
227 node.file = node.path = path and abspath(path) or path 218 node.file = node.path = path and abspath(path) or path
228 node.name = modname 219 MANAGER.astng_cache[modname] = node
229 MANAGER.cache_module(node)
230 node.package = hasattr(module, '__path__') 220 node.package = hasattr(module, '__path__')
231 self._done = {} 221 self._done = {}
232 self.object_build(node, module) 222 self.object_build(node, module)
233 return node 223 return node
234 224
235 def object_build(self, node, obj): 225 def object_build(self, node, obj):
236 """recursive method which create a partial ast from real objects 226 """recursive method which create a partial ast from real objects
237 (only function, class, and method are handled) 227 (only function, class, and method are handled)
238 """ 228 """
239 if obj in self._done: 229 if obj in self._done:
240 return self._done[obj] 230 return self._done[obj]
241 self._done[obj] = node 231 self._done[obj] = node
242 for name in dir(obj): 232 for name in dir(obj):
243 try: 233 try:
244 member = getattr(obj, name) 234 member = getattr(obj, name)
245 except AttributeError: 235 except AttributeError:
246 # damned ExtensionClass.Base, I know you're there ! 236 # damned ExtensionClass.Base, I know you're there !
247 attach_dummy_node(node, name) 237 attach_dummy_node(node, name)
248 continue 238 continue
249 if ismethod(member): 239 if ismethod(member):
250 member = member.im_func 240 member = member.im_func
251 if isfunction(member): 241 if isfunction(member):
252 # verify this is not an imported function 242 # verify this is not an imported function
253 filename = getattr(member.func_code, 'co_filename', None) 243 if member.func_code.co_filename != getattr(self._module, '__file __', None):
254 if filename is None:
255 assert isinstance(member, object)
256 object_build_methoddescriptor(node, member, name)
257 elif filename != getattr(self._module, '__file__', None):
258 attach_dummy_node(node, name, member) 244 attach_dummy_node(node, name, member)
259 else: 245 continue
260 object_build_function(node, member, name) 246 object_build_function(node, member, name)
261 elif isbuiltin(member): 247 elif isbuiltin(member):
262 if (not _io_discrepancy(member) and 248 if self.imported_member(node, member, name):
263 self.imported_member(node, member, name)):
264 #if obj is object: 249 #if obj is object:
265 # print 'skippp', obj, name, member 250 # print 'skippp', obj, name, member
266 continue 251 continue
267 object_build_methoddescriptor(node, member, name) 252 object_build_methoddescriptor(node, member, name)
268 elif isclass(member): 253 elif isclass(member):
269 if self.imported_member(node, member, name): 254 if self.imported_member(node, member, name):
270 continue 255 continue
271 if member in self._done: 256 if member in self._done:
272 class_node = self._done[member] 257 class_node = self._done[member]
273 if not class_node in node.locals.get(name, ()): 258 if not class_node in node.locals.get(name, ()):
274 node.add_local_node(class_node, name) 259 node.add_local_node(class_node, name)
275 else: 260 else:
276 class_node = object_build_class(node, member, name) 261 class_node = object_build_class(node, member, name)
277 # recursion 262 # recursion
278 self.object_build(class_node, member) 263 self.object_build(class_node, member)
279 if name == '__class__' and class_node.parent is None: 264 if name == '__class__' and class_node.parent is None:
280 class_node.parent = self._done[self._module] 265 class_node.parent = self._done[self._module]
281 elif ismethoddescriptor(member): 266 elif ismethoddescriptor(member):
282 assert isinstance(member, object) 267 assert isinstance(member, object)
283 object_build_methoddescriptor(node, member, name) 268 object_build_methoddescriptor(node, member, name)
284 elif isdatadescriptor(member): 269 elif isdatadescriptor(member):
285 assert isinstance(member, object) 270 assert isinstance(member, object)
286 object_build_datadescriptor(node, member, name) 271 object_build_datadescriptor(node, member, name)
287 elif type(member) in _CONSTANTS: 272 elif isinstance(member, _CONSTANTS):
288 attach_const_node(node, name, member) 273 attach_const_node(node, name, member)
289 else: 274 else:
290 # create an empty node so that the name is actually defined 275 # create an empty node so that the name is actually defined
291 attach_dummy_node(node, name, member) 276 attach_dummy_node(node, name, member)
292 277
293 def imported_member(self, node, member, name): 278 def imported_member(self, node, member, name):
294 """verify this is not an imported class or handle it""" 279 """verify this is not an imported class or handle it"""
295 # /!\ some classes like ExtensionClass doesn't have a __module__ 280 # /!\ some classes like ExtensionClass doesn't have a __module__
296 # attribute ! Also, this may trigger an exception on badly built module 281 # attribute ! Also, this may trigger an exception on badly built module
297 # (see http://www.logilab.org/ticket/57299 for instance) 282 # (see http://www.logilab.org/ticket/57299 for instance)
298 try: 283 try:
299 modname = getattr(member, '__module__', None) 284 modname = getattr(member, '__module__', None)
300 except: 285 except:
301 # XXX use logging 286 # XXX use logging
302 print 'unexpected error while building astroid from living object' 287 print 'unexpected error while building astng from living object'
303 import traceback 288 import traceback
304 traceback.print_exc() 289 traceback.print_exc()
305 modname = None 290 modname = None
306 if modname is None: 291 if modname is None:
307 if name in ('__new__', '__subclasshook__'): 292 if name in ('__new__', '__subclasshook__'):
308 # Python 2.5.1 (r251:54863, Sep 1 2010, 22:03:14) 293 # Python 2.5.1 (r251:54863, Sep 1 2010, 22:03:14)
309 # >>> print object.__new__.__module__ 294 # >>> print object.__new__.__module__
310 # None 295 # None
311 modname = BUILTINS 296 modname = BUILTINS_MODULE
312 else: 297 else:
313 attach_dummy_node(node, name, member) 298 attach_dummy_node(node, name, member)
314 return True 299 return True
315 if {'gtk': 'gtk._gtk'}.get(modname, modname) != self._module.__name__: 300 if {'gtk': 'gtk._gtk'}.get(modname, modname) != self._module.__name__:
316 # check if it sounds valid and then add an import node, else use a 301 # check if it sounds valid and then add an import node, else use a
317 # dummy node 302 # dummy node
318 try: 303 try:
319 getattr(sys.modules[modname], name) 304 getattr(sys.modules[modname], name)
320 except (KeyError, AttributeError): 305 except (KeyError, AttributeError):
321 attach_dummy_node(node, name, member) 306 attach_dummy_node(node, name, member)
322 else: 307 else:
323 attach_import_node(node, modname, name) 308 attach_import_node(node, modname, name)
324 return True 309 return True
325 return False 310 return False
326 311
327 312
328 ### astroid bootstrapping ###################################################### 313 ### astng boot strapping ################################################### ###
329 Astroid_BUILDER = InspectBuilder()
330 314
331 _CONST_PROXY = {} 315 _CONST_PROXY = {}
332 def astroid_bootstrapping(): 316 def astng_boot_strapping():
333 """astroid boot strapping the builtins module""" 317 """astng boot strapping the builtins module"""
334 # this boot strapping is necessary since we need the Const nodes to 318 # this boot strapping is necessary since we need the Const nodes to
335 # inspect_build builtins, and then we can proxy Const 319 # inspect_build builtins, and then we can proxy Const
320 builder = InspectBuilder()
336 from logilab.common.compat import builtins 321 from logilab.common.compat import builtins
337 astroid_builtin = Astroid_BUILDER.inspect_build(builtins) 322 astng_builtin = builder.inspect_build(builtins)
338 for cls, node_cls in CONST_CLS.items(): 323 for cls, node_cls in CONST_CLS.items():
339 if cls is type(None): 324 if cls is type(None):
340 proxy = build_class('NoneType') 325 proxy = build_class('NoneType')
341 proxy.parent = astroid_builtin 326 proxy.parent = astng_builtin
342 else: 327 else:
343 proxy = astroid_builtin.getattr(cls.__name__)[0] 328 proxy = astng_builtin.getattr(cls.__name__)[0] # XXX
344 if cls in (dict, list, set, tuple): 329 if cls in (dict, list, set, tuple):
345 node_cls._proxied = proxy 330 node_cls._proxied = proxy
346 else: 331 else:
347 _CONST_PROXY[cls] = proxy 332 _CONST_PROXY[cls] = proxy
348 333
349 astroid_bootstrapping() 334 astng_boot_strapping()
350 335
351 # TODO : find a nicer way to handle this situation; 336 # TODO : find a nicer way to handle this situation;
352 # However __proxied introduced an 337 # However __proxied introduced an
353 # infinite recursion (see https://bugs.launchpad.net/pylint/+bug/456870) 338 # infinite recursion (see https://bugs.launchpad.net/pylint/+bug/456870)
354 def _set_proxied(const): 339 def _set_proxied(const):
355 return _CONST_PROXY[const.value.__class__] 340 return _CONST_PROXY[const.value.__class__]
356 Const._proxied = property(_set_proxied) 341 Const._proxied = property(_set_proxied)
357 342
358 from types import GeneratorType 343 # FIXME : is it alright that Generator._proxied is not a astng node?
359 Generator._proxied = Class(GeneratorType.__name__, GeneratorType.__doc__) 344 Generator._proxied = MANAGER.infer_astng_from_something(type(a for a in ()))
360 Astroid_BUILDER.object_build(Generator._proxied, GeneratorType)
361 345
OLDNEW
« no previous file with comments | « third_party/logilab/astng/protocols.py ('k') | third_party/logilab/astng/rebuilder.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698