Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
marvel
GitHub Repository: marvel/qnf
Path: blob/master/elisp/emacs-for-python/rope-dist/rope/base/pyobjectsdef.py
1415 views
1
import rope.base.codeanalyze
2
import rope.base.evaluate
3
import rope.base.builtins
4
import rope.base.oi.soi
5
import rope.base.pyscopes
6
from rope.base import (pynamesdef as pynames, exceptions, ast,
7
astutils, pyobjects, fscommands, arguments, utils)
8
from rope.base.pyobjects import *
9
10
11
class PyFunction(pyobjects.PyFunction):
12
13
def __init__(self, pycore, ast_node, parent):
14
AbstractFunction.__init__(self)
15
PyDefinedObject.__init__(self, pycore, ast_node, parent)
16
self.arguments = self.ast_node.args
17
self.parameter_pyobjects = pynames._Inferred(
18
self._infer_parameters, self.get_module()._get_concluded_data())
19
self.returned = pynames._Inferred(self._infer_returned)
20
self.parameter_pynames = None
21
22
def _create_structural_attributes(self):
23
return {}
24
25
def _create_concluded_attributes(self):
26
return {}
27
28
def _create_scope(self):
29
return rope.base.pyscopes.FunctionScope(self.pycore, self,
30
_FunctionVisitor)
31
32
def _infer_parameters(self):
33
pyobjects = rope.base.oi.soi.infer_parameter_objects(self)
34
self._handle_special_args(pyobjects)
35
return pyobjects
36
37
def _infer_returned(self, args=None):
38
return rope.base.oi.soi.infer_returned_object(self, args)
39
40
def _handle_special_args(self, pyobjects):
41
if len(pyobjects) == len(self.arguments.args):
42
if self.arguments.vararg:
43
pyobjects.append(rope.base.builtins.get_list())
44
if self.arguments.kwarg:
45
pyobjects.append(rope.base.builtins.get_dict())
46
47
def _set_parameter_pyobjects(self, pyobjects):
48
if pyobjects is not None:
49
self._handle_special_args(pyobjects)
50
self.parameter_pyobjects.set(pyobjects)
51
52
def get_parameters(self):
53
if self.parameter_pynames is None:
54
result = {}
55
for index, name in enumerate(self.get_param_names()):
56
# TODO: handle tuple parameters
57
result[name] = pynames.ParameterName(self, index)
58
self.parameter_pynames = result
59
return self.parameter_pynames
60
61
def get_parameter(self, index):
62
if index < len(self.parameter_pyobjects.get()):
63
return self.parameter_pyobjects.get()[index]
64
65
def get_returned_object(self, args):
66
return self.returned.get(args)
67
68
def get_name(self):
69
return self.get_ast().name
70
71
def get_param_names(self, special_args=True):
72
# TODO: handle tuple parameters
73
result = [node.id for node in self.arguments.args
74
if isinstance(node, ast.Name)]
75
if special_args:
76
if self.arguments.vararg:
77
result.append(self.arguments.vararg)
78
if self.arguments.kwarg:
79
result.append(self.arguments.kwarg)
80
return result
81
82
def get_kind(self):
83
"""Get function type
84
85
It returns one of 'function', 'method', 'staticmethod' or
86
'classmethod' strs.
87
88
"""
89
scope = self.parent.get_scope()
90
if isinstance(self.parent, PyClass):
91
for decorator in self.decorators:
92
pyname = rope.base.evaluate.eval_node(scope, decorator)
93
if pyname == rope.base.builtins.builtins['staticmethod']:
94
return 'staticmethod'
95
if pyname == rope.base.builtins.builtins['classmethod']:
96
return 'classmethod'
97
return 'method'
98
return 'function'
99
100
@property
101
def decorators(self):
102
try:
103
return getattr(self.ast_node, 'decorator_list')
104
except AttributeError:
105
return getattr(self.ast_node, 'decorators', None)
106
107
108
class PyClass(pyobjects.PyClass):
109
110
def __init__(self, pycore, ast_node, parent):
111
self.visitor_class = _ClassVisitor
112
AbstractClass.__init__(self)
113
PyDefinedObject.__init__(self, pycore, ast_node, parent)
114
self.parent = parent
115
self._superclasses = self.get_module()._get_concluded_data()
116
117
def get_superclasses(self):
118
if self._superclasses.get() is None:
119
self._superclasses.set(self._get_bases())
120
return self._superclasses.get()
121
122
def get_name(self):
123
return self.get_ast().name
124
125
def _create_concluded_attributes(self):
126
result = {}
127
for base in reversed(self.get_superclasses()):
128
result.update(base.get_attributes())
129
return result
130
131
def _get_bases(self):
132
result = []
133
for base_name in self.ast_node.bases:
134
base = rope.base.evaluate.eval_node(self.parent.get_scope(),
135
base_name)
136
if base is not None and \
137
base.get_object().get_type() == get_base_type('Type'):
138
result.append(base.get_object())
139
return result
140
141
def _create_scope(self):
142
return rope.base.pyscopes.ClassScope(self.pycore, self)
143
144
145
class PyModule(pyobjects.PyModule):
146
147
def __init__(self, pycore, source=None,
148
resource=None, force_errors=False):
149
ignore = pycore.project.prefs.get('ignore_syntax_errors', False)
150
syntax_errors = force_errors or not ignore
151
self.has_errors = False
152
try:
153
source, node = self._init_source(pycore, source, resource)
154
except exceptions.ModuleSyntaxError:
155
self.has_errors = True
156
if syntax_errors:
157
raise
158
else:
159
source = '\n'
160
node = ast.parse('\n')
161
self.source_code = source
162
self.star_imports = []
163
self.visitor_class = _GlobalVisitor
164
self.coding = fscommands.read_str_coding(self.source_code)
165
super(PyModule, self).__init__(pycore, node, resource)
166
167
def _init_source(self, pycore, source_code, resource):
168
filename = 'string'
169
if resource:
170
filename = resource.path
171
try:
172
if source_code is None:
173
source_bytes = resource.read_bytes()
174
source_code = fscommands.file_data_to_unicode(source_bytes)
175
else:
176
if isinstance(source_code, unicode):
177
source_bytes = fscommands.unicode_to_file_data(source_code)
178
else:
179
source_bytes = source_code
180
ast_node = ast.parse(source_bytes, filename=filename)
181
except SyntaxError, e:
182
raise exceptions.ModuleSyntaxError(filename, e.lineno, e.msg)
183
except UnicodeDecodeError, e:
184
raise exceptions.ModuleSyntaxError(filename, 1, '%s' % (e.reason))
185
return source_code, ast_node
186
187
@utils.prevent_recursion(lambda: {})
188
def _create_concluded_attributes(self):
189
result = {}
190
for star_import in self.star_imports:
191
result.update(star_import.get_names())
192
return result
193
194
def _create_scope(self):
195
return rope.base.pyscopes.GlobalScope(self.pycore, self)
196
197
@property
198
@utils.saveit
199
def lines(self):
200
"""A `SourceLinesAdapter`"""
201
return rope.base.codeanalyze.SourceLinesAdapter(self.source_code)
202
203
@property
204
@utils.saveit
205
def logical_lines(self):
206
"""A `LogicalLinesFinder`"""
207
return rope.base.codeanalyze.CachingLogicalLineFinder(self.lines)
208
209
210
class PyPackage(pyobjects.PyPackage):
211
212
def __init__(self, pycore, resource=None, force_errors=False):
213
self.resource = resource
214
init_dot_py = self._get_init_dot_py()
215
if init_dot_py is not None:
216
ast_node = pycore.resource_to_pyobject(
217
init_dot_py, force_errors=force_errors).get_ast()
218
else:
219
ast_node = ast.parse('\n')
220
super(PyPackage, self).__init__(pycore, ast_node, resource)
221
222
def _create_structural_attributes(self):
223
result = {}
224
modname = self.pycore.modname(self.resource)
225
extension_submodules = self.pycore._builtin_submodules(modname)
226
for name, module in extension_submodules.iteritems():
227
result[name] = rope.base.builtins.BuiltinName(module)
228
if self.resource is None:
229
return result
230
for name, resource in self._get_child_resources().items():
231
result[name] = pynames.ImportedModule(self, resource=resource)
232
return result
233
234
def _create_concluded_attributes(self):
235
result = {}
236
init_dot_py = self._get_init_dot_py()
237
if init_dot_py:
238
init_object = self.pycore.resource_to_pyobject(init_dot_py)
239
result.update(init_object.get_attributes())
240
return result
241
242
def _get_child_resources(self):
243
result = {}
244
for child in self.resource.get_children():
245
if child.is_folder():
246
result[child.name] = child
247
elif child.name.endswith('.py') and \
248
child.name != '__init__.py':
249
name = child.name[:-3]
250
result[name] = child
251
return result
252
253
def _get_init_dot_py(self):
254
if self.resource is not None and self.resource.has_child('__init__.py'):
255
return self.resource.get_child('__init__.py')
256
else:
257
return None
258
259
def _create_scope(self):
260
return self.get_module().get_scope()
261
262
def get_module(self):
263
init_dot_py = self._get_init_dot_py()
264
if init_dot_py:
265
return self.pycore.resource_to_pyobject(init_dot_py)
266
return self
267
268
269
class _AssignVisitor(object):
270
271
def __init__(self, scope_visitor):
272
self.scope_visitor = scope_visitor
273
self.assigned_ast = None
274
275
def _Assign(self, node):
276
self.assigned_ast = node.value
277
for child_node in node.targets:
278
ast.walk(child_node, self)
279
280
def _assigned(self, name, assignment=None):
281
self.scope_visitor._assigned(name, assignment)
282
283
def _Name(self, node):
284
assignment = None
285
if self.assigned_ast is not None:
286
assignment = pynames.AssignmentValue(self.assigned_ast)
287
self._assigned(node.id, assignment)
288
289
def _Tuple(self, node):
290
names = astutils.get_name_levels(node)
291
for name, levels in names:
292
assignment = None
293
if self.assigned_ast is not None:
294
assignment = pynames.AssignmentValue(self.assigned_ast, levels)
295
self._assigned(name, assignment)
296
297
def _Attribute(self, node):
298
pass
299
300
def _Subscript(self, node):
301
pass
302
303
def _Slice(self, node):
304
pass
305
306
307
class _ScopeVisitor(object):
308
309
def __init__(self, pycore, owner_object):
310
self.pycore = pycore
311
self.owner_object = owner_object
312
self.names = {}
313
self.defineds = []
314
315
def get_module(self):
316
if self.owner_object is not None:
317
return self.owner_object.get_module()
318
else:
319
return None
320
321
def _ClassDef(self, node):
322
pyclass = PyClass(self.pycore, node, self.owner_object)
323
self.names[node.name] = pynames.DefinedName(pyclass)
324
self.defineds.append(pyclass)
325
326
def _FunctionDef(self, node):
327
pyfunction = PyFunction(self.pycore, node, self.owner_object)
328
for decorator in pyfunction.decorators:
329
if isinstance(decorator, ast.Name) and decorator.id == 'property':
330
if isinstance(self, _ClassVisitor):
331
type_ = rope.base.builtins.Property(pyfunction)
332
arg = pynames.UnboundName(PyObject(self.owner_object))
333
def _eval(type_=type_, arg=arg):
334
return type_.get_property_object(
335
arguments.ObjectArguments([arg]))
336
self.names[node.name] = pynames.EvaluatedName(
337
_eval, module=self.get_module(), lineno=node.lineno)
338
break
339
else:
340
self.names[node.name] = pynames.DefinedName(pyfunction)
341
self.defineds.append(pyfunction)
342
343
def _Assign(self, node):
344
ast.walk(node, _AssignVisitor(self))
345
346
def _AugAssign(self, node):
347
pass
348
349
def _For(self, node):
350
names = self._update_evaluated(node.target, node.iter,
351
'.__iter__().next()')
352
for child in node.body + node.orelse:
353
ast.walk(child, self)
354
355
def _assigned(self, name, assignment):
356
pyname = self.names.get(name, None)
357
if pyname is None:
358
pyname = pynames.AssignedName(module=self.get_module())
359
if isinstance(pyname, pynames.AssignedName):
360
if assignment is not None:
361
pyname.assignments.append(assignment)
362
self.names[name] = pyname
363
364
def _update_evaluated(self, targets, assigned,
365
evaluation= '', eval_type=False):
366
result = {}
367
names = astutils.get_name_levels(targets)
368
for name, levels in names:
369
assignment = pynames.AssignmentValue(assigned, levels,
370
evaluation, eval_type)
371
self._assigned(name, assignment)
372
return result
373
374
def _With(self, node):
375
if node.optional_vars:
376
self._update_evaluated(node.optional_vars,
377
node.context_expr, '.__enter__()')
378
for child in node.body:
379
ast.walk(child, self)
380
381
def _excepthandler(self, node):
382
if node.name is not None and isinstance(node.name, ast.Name):
383
type_node = node.type
384
if isinstance(node.type, ast.Tuple) and type_node.elts:
385
type_node = type_node.elts[0]
386
self._update_evaluated(node.name, type_node, eval_type=True)
387
for child in node.body:
388
ast.walk(child, self)
389
390
def _ExceptHandler(self, node):
391
self._excepthandler(node)
392
393
def _Import(self, node):
394
for import_pair in node.names:
395
module_name = import_pair.name
396
alias = import_pair.asname
397
first_package = module_name.split('.')[0]
398
if alias is not None:
399
imported = pynames.ImportedModule(self.get_module(),
400
module_name)
401
if not self._is_ignored_import(imported):
402
self.names[alias] = imported
403
else:
404
imported = pynames.ImportedModule(self.get_module(),
405
first_package)
406
if not self._is_ignored_import(imported):
407
self.names[first_package] = imported
408
409
def _ImportFrom(self, node):
410
level = 0
411
if node.level:
412
level = node.level
413
imported_module = pynames.ImportedModule(self.get_module(),
414
node.module, level)
415
if self._is_ignored_import(imported_module):
416
return
417
if len(node.names) == 1 and node.names[0].name == '*':
418
if isinstance(self.owner_object, PyModule):
419
self.owner_object.star_imports.append(
420
StarImport(imported_module))
421
else:
422
for imported_name in node.names:
423
imported = imported_name.name
424
alias = imported_name.asname
425
if alias is not None:
426
imported = alias
427
self.names[imported] = pynames.ImportedName(imported_module,
428
imported_name.name)
429
430
def _is_ignored_import(self, imported_module):
431
if not self.pycore.project.prefs.get('ignore_bad_imports', False):
432
return False
433
return not isinstance(imported_module.get_object(), AbstractModule)
434
435
def _Global(self, node):
436
module = self.get_module()
437
for name in node.names:
438
if module is not None:
439
try:
440
pyname = module[name]
441
except exceptions.AttributeNotFoundError:
442
pyname = pynames.AssignedName(node.lineno)
443
self.names[name] = pyname
444
445
446
class _GlobalVisitor(_ScopeVisitor):
447
448
def __init__(self, pycore, owner_object):
449
super(_GlobalVisitor, self).__init__(pycore, owner_object)
450
451
452
class _ClassVisitor(_ScopeVisitor):
453
454
def __init__(self, pycore, owner_object):
455
super(_ClassVisitor, self).__init__(pycore, owner_object)
456
457
def _FunctionDef(self, node):
458
_ScopeVisitor._FunctionDef(self, node)
459
if len(node.args.args) > 0:
460
first = node.args.args[0]
461
if isinstance(first, ast.Name):
462
new_visitor = _ClassInitVisitor(self, first.id)
463
for child in ast.get_child_nodes(node):
464
ast.walk(child, new_visitor)
465
466
467
class _FunctionVisitor(_ScopeVisitor):
468
469
def __init__(self, pycore, owner_object):
470
super(_FunctionVisitor, self).__init__(pycore, owner_object)
471
self.returned_asts = []
472
self.generator = False
473
474
def _Return(self, node):
475
if node.value is not None:
476
self.returned_asts.append(node.value)
477
478
def _Yield(self, node):
479
if node.value is not None:
480
self.returned_asts.append(node.value)
481
self.generator = True
482
483
484
class _ClassInitVisitor(_AssignVisitor):
485
486
def __init__(self, scope_visitor, self_name):
487
super(_ClassInitVisitor, self).__init__(scope_visitor)
488
self.self_name = self_name
489
490
def _Attribute(self, node):
491
if not isinstance(node.ctx, ast.Store):
492
return
493
if isinstance(node.value, ast.Name) and \
494
node.value.id == self.self_name:
495
if node.attr not in self.scope_visitor.names:
496
self.scope_visitor.names[node.attr] = pynames.AssignedName(
497
lineno=node.lineno, module=self.scope_visitor.get_module())
498
if self.assigned_ast is not None:
499
pyname = self.scope_visitor.names[node.attr]
500
if isinstance(pyname, pynames.AssignedName):
501
pyname.assignments.append(
502
pynames.AssignmentValue(self.assigned_ast))
503
504
def _Tuple(self, node):
505
if not isinstance(node.ctx, ast.Store):
506
return
507
for child in ast.get_child_nodes(node):
508
ast.walk(child, self)
509
510
def _Name(self, node):
511
pass
512
513
def _FunctionDef(self, node):
514
pass
515
516
def _ClassDef(self, node):
517
pass
518
519
def _For(self, node):
520
pass
521
522
def _With(self, node):
523
pass
524
525
526
class StarImport(object):
527
528
def __init__(self, imported_module):
529
self.imported_module = imported_module
530
531
def get_names(self):
532
result = {}
533
imported = self.imported_module.get_object()
534
for name in imported:
535
if not name.startswith('_'):
536
result[name] = pynames.ImportedName(self.imported_module, name)
537
return result
538
539