Path: blob/master/elisp/emacs-for-python/rope-dist/rope/base/pyobjectsdef.py
1415 views
import rope.base.codeanalyze1import rope.base.evaluate2import rope.base.builtins3import rope.base.oi.soi4import rope.base.pyscopes5from rope.base import (pynamesdef as pynames, exceptions, ast,6astutils, pyobjects, fscommands, arguments, utils)7from rope.base.pyobjects import *8910class PyFunction(pyobjects.PyFunction):1112def __init__(self, pycore, ast_node, parent):13AbstractFunction.__init__(self)14PyDefinedObject.__init__(self, pycore, ast_node, parent)15self.arguments = self.ast_node.args16self.parameter_pyobjects = pynames._Inferred(17self._infer_parameters, self.get_module()._get_concluded_data())18self.returned = pynames._Inferred(self._infer_returned)19self.parameter_pynames = None2021def _create_structural_attributes(self):22return {}2324def _create_concluded_attributes(self):25return {}2627def _create_scope(self):28return rope.base.pyscopes.FunctionScope(self.pycore, self,29_FunctionVisitor)3031def _infer_parameters(self):32pyobjects = rope.base.oi.soi.infer_parameter_objects(self)33self._handle_special_args(pyobjects)34return pyobjects3536def _infer_returned(self, args=None):37return rope.base.oi.soi.infer_returned_object(self, args)3839def _handle_special_args(self, pyobjects):40if len(pyobjects) == len(self.arguments.args):41if self.arguments.vararg:42pyobjects.append(rope.base.builtins.get_list())43if self.arguments.kwarg:44pyobjects.append(rope.base.builtins.get_dict())4546def _set_parameter_pyobjects(self, pyobjects):47if pyobjects is not None:48self._handle_special_args(pyobjects)49self.parameter_pyobjects.set(pyobjects)5051def get_parameters(self):52if self.parameter_pynames is None:53result = {}54for index, name in enumerate(self.get_param_names()):55# TODO: handle tuple parameters56result[name] = pynames.ParameterName(self, index)57self.parameter_pynames = result58return self.parameter_pynames5960def get_parameter(self, index):61if index < len(self.parameter_pyobjects.get()):62return self.parameter_pyobjects.get()[index]6364def get_returned_object(self, args):65return self.returned.get(args)6667def get_name(self):68return self.get_ast().name6970def get_param_names(self, special_args=True):71# TODO: handle tuple parameters72result = [node.id for node in self.arguments.args73if isinstance(node, ast.Name)]74if special_args:75if self.arguments.vararg:76result.append(self.arguments.vararg)77if self.arguments.kwarg:78result.append(self.arguments.kwarg)79return result8081def get_kind(self):82"""Get function type8384It returns one of 'function', 'method', 'staticmethod' or85'classmethod' strs.8687"""88scope = self.parent.get_scope()89if isinstance(self.parent, PyClass):90for decorator in self.decorators:91pyname = rope.base.evaluate.eval_node(scope, decorator)92if pyname == rope.base.builtins.builtins['staticmethod']:93return 'staticmethod'94if pyname == rope.base.builtins.builtins['classmethod']:95return 'classmethod'96return 'method'97return 'function'9899@property100def decorators(self):101try:102return getattr(self.ast_node, 'decorator_list')103except AttributeError:104return getattr(self.ast_node, 'decorators', None)105106107class PyClass(pyobjects.PyClass):108109def __init__(self, pycore, ast_node, parent):110self.visitor_class = _ClassVisitor111AbstractClass.__init__(self)112PyDefinedObject.__init__(self, pycore, ast_node, parent)113self.parent = parent114self._superclasses = self.get_module()._get_concluded_data()115116def get_superclasses(self):117if self._superclasses.get() is None:118self._superclasses.set(self._get_bases())119return self._superclasses.get()120121def get_name(self):122return self.get_ast().name123124def _create_concluded_attributes(self):125result = {}126for base in reversed(self.get_superclasses()):127result.update(base.get_attributes())128return result129130def _get_bases(self):131result = []132for base_name in self.ast_node.bases:133base = rope.base.evaluate.eval_node(self.parent.get_scope(),134base_name)135if base is not None and \136base.get_object().get_type() == get_base_type('Type'):137result.append(base.get_object())138return result139140def _create_scope(self):141return rope.base.pyscopes.ClassScope(self.pycore, self)142143144class PyModule(pyobjects.PyModule):145146def __init__(self, pycore, source=None,147resource=None, force_errors=False):148ignore = pycore.project.prefs.get('ignore_syntax_errors', False)149syntax_errors = force_errors or not ignore150self.has_errors = False151try:152source, node = self._init_source(pycore, source, resource)153except exceptions.ModuleSyntaxError:154self.has_errors = True155if syntax_errors:156raise157else:158source = '\n'159node = ast.parse('\n')160self.source_code = source161self.star_imports = []162self.visitor_class = _GlobalVisitor163self.coding = fscommands.read_str_coding(self.source_code)164super(PyModule, self).__init__(pycore, node, resource)165166def _init_source(self, pycore, source_code, resource):167filename = 'string'168if resource:169filename = resource.path170try:171if source_code is None:172source_bytes = resource.read_bytes()173source_code = fscommands.file_data_to_unicode(source_bytes)174else:175if isinstance(source_code, unicode):176source_bytes = fscommands.unicode_to_file_data(source_code)177else:178source_bytes = source_code179ast_node = ast.parse(source_bytes, filename=filename)180except SyntaxError, e:181raise exceptions.ModuleSyntaxError(filename, e.lineno, e.msg)182except UnicodeDecodeError, e:183raise exceptions.ModuleSyntaxError(filename, 1, '%s' % (e.reason))184return source_code, ast_node185186@utils.prevent_recursion(lambda: {})187def _create_concluded_attributes(self):188result = {}189for star_import in self.star_imports:190result.update(star_import.get_names())191return result192193def _create_scope(self):194return rope.base.pyscopes.GlobalScope(self.pycore, self)195196@property197@utils.saveit198def lines(self):199"""A `SourceLinesAdapter`"""200return rope.base.codeanalyze.SourceLinesAdapter(self.source_code)201202@property203@utils.saveit204def logical_lines(self):205"""A `LogicalLinesFinder`"""206return rope.base.codeanalyze.CachingLogicalLineFinder(self.lines)207208209class PyPackage(pyobjects.PyPackage):210211def __init__(self, pycore, resource=None, force_errors=False):212self.resource = resource213init_dot_py = self._get_init_dot_py()214if init_dot_py is not None:215ast_node = pycore.resource_to_pyobject(216init_dot_py, force_errors=force_errors).get_ast()217else:218ast_node = ast.parse('\n')219super(PyPackage, self).__init__(pycore, ast_node, resource)220221def _create_structural_attributes(self):222result = {}223modname = self.pycore.modname(self.resource)224extension_submodules = self.pycore._builtin_submodules(modname)225for name, module in extension_submodules.iteritems():226result[name] = rope.base.builtins.BuiltinName(module)227if self.resource is None:228return result229for name, resource in self._get_child_resources().items():230result[name] = pynames.ImportedModule(self, resource=resource)231return result232233def _create_concluded_attributes(self):234result = {}235init_dot_py = self._get_init_dot_py()236if init_dot_py:237init_object = self.pycore.resource_to_pyobject(init_dot_py)238result.update(init_object.get_attributes())239return result240241def _get_child_resources(self):242result = {}243for child in self.resource.get_children():244if child.is_folder():245result[child.name] = child246elif child.name.endswith('.py') and \247child.name != '__init__.py':248name = child.name[:-3]249result[name] = child250return result251252def _get_init_dot_py(self):253if self.resource is not None and self.resource.has_child('__init__.py'):254return self.resource.get_child('__init__.py')255else:256return None257258def _create_scope(self):259return self.get_module().get_scope()260261def get_module(self):262init_dot_py = self._get_init_dot_py()263if init_dot_py:264return self.pycore.resource_to_pyobject(init_dot_py)265return self266267268class _AssignVisitor(object):269270def __init__(self, scope_visitor):271self.scope_visitor = scope_visitor272self.assigned_ast = None273274def _Assign(self, node):275self.assigned_ast = node.value276for child_node in node.targets:277ast.walk(child_node, self)278279def _assigned(self, name, assignment=None):280self.scope_visitor._assigned(name, assignment)281282def _Name(self, node):283assignment = None284if self.assigned_ast is not None:285assignment = pynames.AssignmentValue(self.assigned_ast)286self._assigned(node.id, assignment)287288def _Tuple(self, node):289names = astutils.get_name_levels(node)290for name, levels in names:291assignment = None292if self.assigned_ast is not None:293assignment = pynames.AssignmentValue(self.assigned_ast, levels)294self._assigned(name, assignment)295296def _Attribute(self, node):297pass298299def _Subscript(self, node):300pass301302def _Slice(self, node):303pass304305306class _ScopeVisitor(object):307308def __init__(self, pycore, owner_object):309self.pycore = pycore310self.owner_object = owner_object311self.names = {}312self.defineds = []313314def get_module(self):315if self.owner_object is not None:316return self.owner_object.get_module()317else:318return None319320def _ClassDef(self, node):321pyclass = PyClass(self.pycore, node, self.owner_object)322self.names[node.name] = pynames.DefinedName(pyclass)323self.defineds.append(pyclass)324325def _FunctionDef(self, node):326pyfunction = PyFunction(self.pycore, node, self.owner_object)327for decorator in pyfunction.decorators:328if isinstance(decorator, ast.Name) and decorator.id == 'property':329if isinstance(self, _ClassVisitor):330type_ = rope.base.builtins.Property(pyfunction)331arg = pynames.UnboundName(PyObject(self.owner_object))332def _eval(type_=type_, arg=arg):333return type_.get_property_object(334arguments.ObjectArguments([arg]))335self.names[node.name] = pynames.EvaluatedName(336_eval, module=self.get_module(), lineno=node.lineno)337break338else:339self.names[node.name] = pynames.DefinedName(pyfunction)340self.defineds.append(pyfunction)341342def _Assign(self, node):343ast.walk(node, _AssignVisitor(self))344345def _AugAssign(self, node):346pass347348def _For(self, node):349names = self._update_evaluated(node.target, node.iter,350'.__iter__().next()')351for child in node.body + node.orelse:352ast.walk(child, self)353354def _assigned(self, name, assignment):355pyname = self.names.get(name, None)356if pyname is None:357pyname = pynames.AssignedName(module=self.get_module())358if isinstance(pyname, pynames.AssignedName):359if assignment is not None:360pyname.assignments.append(assignment)361self.names[name] = pyname362363def _update_evaluated(self, targets, assigned,364evaluation= '', eval_type=False):365result = {}366names = astutils.get_name_levels(targets)367for name, levels in names:368assignment = pynames.AssignmentValue(assigned, levels,369evaluation, eval_type)370self._assigned(name, assignment)371return result372373def _With(self, node):374if node.optional_vars:375self._update_evaluated(node.optional_vars,376node.context_expr, '.__enter__()')377for child in node.body:378ast.walk(child, self)379380def _excepthandler(self, node):381if node.name is not None and isinstance(node.name, ast.Name):382type_node = node.type383if isinstance(node.type, ast.Tuple) and type_node.elts:384type_node = type_node.elts[0]385self._update_evaluated(node.name, type_node, eval_type=True)386for child in node.body:387ast.walk(child, self)388389def _ExceptHandler(self, node):390self._excepthandler(node)391392def _Import(self, node):393for import_pair in node.names:394module_name = import_pair.name395alias = import_pair.asname396first_package = module_name.split('.')[0]397if alias is not None:398imported = pynames.ImportedModule(self.get_module(),399module_name)400if not self._is_ignored_import(imported):401self.names[alias] = imported402else:403imported = pynames.ImportedModule(self.get_module(),404first_package)405if not self._is_ignored_import(imported):406self.names[first_package] = imported407408def _ImportFrom(self, node):409level = 0410if node.level:411level = node.level412imported_module = pynames.ImportedModule(self.get_module(),413node.module, level)414if self._is_ignored_import(imported_module):415return416if len(node.names) == 1 and node.names[0].name == '*':417if isinstance(self.owner_object, PyModule):418self.owner_object.star_imports.append(419StarImport(imported_module))420else:421for imported_name in node.names:422imported = imported_name.name423alias = imported_name.asname424if alias is not None:425imported = alias426self.names[imported] = pynames.ImportedName(imported_module,427imported_name.name)428429def _is_ignored_import(self, imported_module):430if not self.pycore.project.prefs.get('ignore_bad_imports', False):431return False432return not isinstance(imported_module.get_object(), AbstractModule)433434def _Global(self, node):435module = self.get_module()436for name in node.names:437if module is not None:438try:439pyname = module[name]440except exceptions.AttributeNotFoundError:441pyname = pynames.AssignedName(node.lineno)442self.names[name] = pyname443444445class _GlobalVisitor(_ScopeVisitor):446447def __init__(self, pycore, owner_object):448super(_GlobalVisitor, self).__init__(pycore, owner_object)449450451class _ClassVisitor(_ScopeVisitor):452453def __init__(self, pycore, owner_object):454super(_ClassVisitor, self).__init__(pycore, owner_object)455456def _FunctionDef(self, node):457_ScopeVisitor._FunctionDef(self, node)458if len(node.args.args) > 0:459first = node.args.args[0]460if isinstance(first, ast.Name):461new_visitor = _ClassInitVisitor(self, first.id)462for child in ast.get_child_nodes(node):463ast.walk(child, new_visitor)464465466class _FunctionVisitor(_ScopeVisitor):467468def __init__(self, pycore, owner_object):469super(_FunctionVisitor, self).__init__(pycore, owner_object)470self.returned_asts = []471self.generator = False472473def _Return(self, node):474if node.value is not None:475self.returned_asts.append(node.value)476477def _Yield(self, node):478if node.value is not None:479self.returned_asts.append(node.value)480self.generator = True481482483class _ClassInitVisitor(_AssignVisitor):484485def __init__(self, scope_visitor, self_name):486super(_ClassInitVisitor, self).__init__(scope_visitor)487self.self_name = self_name488489def _Attribute(self, node):490if not isinstance(node.ctx, ast.Store):491return492if isinstance(node.value, ast.Name) and \493node.value.id == self.self_name:494if node.attr not in self.scope_visitor.names:495self.scope_visitor.names[node.attr] = pynames.AssignedName(496lineno=node.lineno, module=self.scope_visitor.get_module())497if self.assigned_ast is not None:498pyname = self.scope_visitor.names[node.attr]499if isinstance(pyname, pynames.AssignedName):500pyname.assignments.append(501pynames.AssignmentValue(self.assigned_ast))502503def _Tuple(self, node):504if not isinstance(node.ctx, ast.Store):505return506for child in ast.get_child_nodes(node):507ast.walk(child, self)508509def _Name(self, node):510pass511512def _FunctionDef(self, node):513pass514515def _ClassDef(self, node):516pass517518def _For(self, node):519pass520521def _With(self, node):522pass523524525class StarImport(object):526527def __init__(self, imported_module):528self.imported_module = imported_module529530def get_names(self):531result = {}532imported = self.imported_module.get_object()533for name in imported:534if not name.startswith('_'):535result[name] = pynames.ImportedName(self.imported_module, name)536return result537538539