diff --git a/jedi/api.py b/jedi/api.py index 7e24cc3c..a37ad749 100644 --- a/jedi/api.py +++ b/jedi/api.py @@ -12,7 +12,7 @@ __all__ = ['Script', 'NotFoundError', 'set_debug_function', '_quick_complete'] import re import os -import parsing +import parsing_representation as pr import dynamic import imports import evaluate @@ -129,13 +129,13 @@ class Script(object): # Do the completion if there is no path before and no import stmt. u = self._parser.user_stmt bs = builtin.Builtin.scope - if isinstance(u, parsing.Import): + if isinstance(u, pr.Import): if (u.relative_count > 0 or u.from_ns) and not re.search( r'(,|from)\s*$|import\s+$', completion_line): completions += ((k, bs) for k in keywords.get_keywords('import')) - if not path and not isinstance(u, parsing.Import): + if not path and not isinstance(u, pr.Import): # add keywords completions += ((k, bs) for k in keywords.get_keywords( all=True)) @@ -179,7 +179,7 @@ class Script(object): # matched to much. return [] - if isinstance(user_stmt, parsing.Import): + if isinstance(user_stmt, pr.Import): scopes = [self._get_on_import_stmt(is_like_search)[0]] else: # just parse one statement, take it and evaluate it @@ -188,7 +188,7 @@ class Script(object): return scopes def _get_under_cursor_stmt(self, cursor_txt): - r = parsing.Parser(cursor_txt, no_docstr=True) + r = pr.Parser(cursor_txt, no_docstr=True) try: stmt = r.module.statements[0] except IndexError: @@ -260,7 +260,7 @@ class Script(object): """ definitions = set(defs) for d in defs: - if isinstance(d.parent, parsing.Import) \ + if isinstance(d.parent, pr.Import) \ and d.start_pos == (0, 0): i = imports.ImportPath(d.parent).follow(is_goto=True) definitions.remove(d) @@ -274,7 +274,7 @@ class Script(object): user_scope = self._parser.user_scope definitions = set([user_scope.name]) search_name = unicode(user_scope.name) - elif isinstance(user_stmt, parsing.Import): + elif isinstance(user_stmt, pr.Import): s, name_part = self._get_on_import_stmt() try: definitions = [s.follow(is_goto=True)[0]] @@ -291,7 +291,7 @@ class Script(object): stmt = self._get_under_cursor_stmt(goto_path) defs, search_name = evaluate.goto(stmt) definitions = follow_inexistent_imports(defs) - if isinstance(user_stmt, parsing.Statement): + if isinstance(user_stmt, pr.Statement): if user_stmt.get_assignment_calls().start_pos > self.pos: # The cursor must be after the start, otherwise the # statement is just an assignee. @@ -311,12 +311,12 @@ class Script(object): """ user_stmt = self._parser.user_stmt definitions, search_name = self._goto(add_import_name=True) - if isinstance(user_stmt, parsing.Statement) \ + if isinstance(user_stmt, pr.Statement) \ and self.pos < user_stmt.get_assignment_calls().start_pos: # the search_name might be before `=` definitions = [v for v in user_stmt.set_vars if unicode(v.names[-1]) == search_name] - if not isinstance(user_stmt, parsing.Import): + if not isinstance(user_stmt, pr.Import): # import case is looked at with add_import_name option definitions = dynamic.related_name_add_import_modules(definitions, search_name) @@ -326,7 +326,7 @@ class Script(object): names = dynamic.related_names(definitions, search_name, module) for d in set(definitions): - if isinstance(d, parsing.Module): + if isinstance(d, pr.Module): names.append(api_classes.RelatedName(d, d)) else: names.append(api_classes.RelatedName(d.names[-1], d)) @@ -351,7 +351,7 @@ class Script(object): """ def check_user_stmt(user_stmt): if user_stmt is None \ - or not isinstance(user_stmt, parsing.Statement): + or not isinstance(user_stmt, pr.Statement): return None, 0 ass = helpers.fast_parent_copy(user_stmt.get_assignment_calls()) diff --git a/jedi/api_classes.py b/jedi/api_classes.py index 03ae63d9..26687597 100644 --- a/jedi/api_classes.py +++ b/jedi/api_classes.py @@ -15,7 +15,7 @@ import helpers import settings import evaluate import imports -import parsing +import parsing_representation as pr import keywords @@ -195,9 +195,9 @@ class Completion(BaseDefinition): append = '(' if settings.add_dot_after_module: - if isinstance(self.base, parsing.Module): + if isinstance(self.base, pr.Module): append += '.' - if isinstance(self.base, parsing.Param): + if isinstance(self.base, pr.Param): append += '=' return dot + self.name.names[-1][self.like_name_length:] + append @@ -241,9 +241,9 @@ class Completion(BaseDefinition): numpy), it's just PITA-slow. """ if self._followed_definitions is None: - if self.definition.isinstance(parsing.Statement): + if self.definition.isinstance(pr.Statement): defs = evaluate.follow_statement(self.definition) - elif self.definition.isinstance(parsing.Import): + elif self.definition.isinstance(pr.Import): defs = imports.strip_imports([self.definition]) else: return [self] @@ -275,16 +275,16 @@ class Definition(BaseDefinition): d = self.definition if isinstance(d, evaluate.InstanceElement): d = d.var - if isinstance(d, evaluate.parsing.Name): + if isinstance(d, pr.Name): d = d.parent if isinstance(d, evaluate.Array): d = 'class ' + d.type - elif isinstance(d, (parsing.Class, evaluate.Class, evaluate.Instance)): + elif isinstance(d, (pr.Class, evaluate.Class, evaluate.Instance)): d = 'class ' + unicode(d.name) - elif isinstance(d, (evaluate.Function, evaluate.parsing.Function)): + elif isinstance(d, (evaluate.Function, pr.Function)): d = 'def ' + unicode(d.name) - elif isinstance(d, evaluate.parsing.Module): + elif isinstance(d, evaluate.pr.Module): # only show module name d = 'module %s' % self.module_name elif self.is_keyword: @@ -305,7 +305,7 @@ class Definition(BaseDefinition): `module.class.function` path. """ if self.module_path.endswith('.py') \ - and not isinstance(self.definition, parsing.Module): + and not isinstance(self.definition, pr.Module): position = '@%s' % (self.line) else: # is a builtin or module diff --git a/jedi/builtin.py b/jedi/builtin.py index e90a89b0..78dc656b 100644 --- a/jedi/builtin.py +++ b/jedi/builtin.py @@ -36,7 +36,7 @@ def get_sys_path(): class CachedModule(object): """ The base type for all modules, which is not to be confused with - `parsing.Module`. Caching happens here. + `parsing_representation.Module`. Caching happens here. """ def __init__(self, path=None, name=None): diff --git a/jedi/docstrings.py b/jedi/docstrings.py index a4cbf745..e943dcd0 100644 --- a/jedi/docstrings.py +++ b/jedi/docstrings.py @@ -3,7 +3,7 @@ import re import evaluate -import parsing +import parsing_representation as pr DOCSTRING_PARAM_PATTERNS = [ r'\s*:type\s+%s:\s*([^\n]+)', # Sphinx @@ -34,7 +34,7 @@ def follow_param(param): param_str) user_position = (2, 0) - p = parsing.Parser(param_str, None, user_position, + p = pr.Parser(param_str, None, user_position, no_docstr=True) return evaluate.follow_statement(p.user_stmt) return [] @@ -98,7 +98,7 @@ def find_return_types(func): if not type_str: return [] - p = parsing.Parser(type_str, None, (1, 0), no_docstr=True) + p = pr.Parser(type_str, None, (1, 0), no_docstr=True) p.user_stmt.parent = func return list(evaluate.follow_statement(p.user_stmt)) diff --git a/jedi/dynamic.py b/jedi/dynamic.py index e4fd432c..06ed0264 100644 --- a/jedi/dynamic.py +++ b/jedi/dynamic.py @@ -10,7 +10,7 @@ from __future__ import with_statement import os import cache -import parsing +import parsing_representation as pr import modules import evaluate import helpers @@ -124,7 +124,7 @@ def search_params(param): return [] for stmt in possible_stmts: - if not isinstance(stmt, parsing.Import): + if not isinstance(stmt, pr.Import): calls = _scan_array(stmt.get_assignment_calls(), func_name) for c in calls: # no execution means that params cannot be set @@ -141,10 +141,10 @@ def search_params(param): result += evaluate.follow_statement(p.parent) return result - func = param.get_parent_until(parsing.Function) + func = param.get_parent_until(pr.Function) current_module = param.get_parent_until() func_name = str(func.name) - if func_name == '__init__' and isinstance(func.parent, parsing.Class): + if func_name == '__init__' and isinstance(func.parent, pr.Class): func_name = str(func.parent.name) # get the param name @@ -189,13 +189,13 @@ def _scan_array(arr, search_name): result = [] for sub in arr: for s in sub: - if isinstance(s, parsing.Array): + if isinstance(s, pr.Array): result += _scan_array(s, search_name) - elif isinstance(s, parsing.Call): + elif isinstance(s, pr.Call): s_new = s while s_new is not None: n = s_new.name - if isinstance(n, parsing.Name) and search_name in n.names: + if isinstance(n, pr.Name) and search_name in n.names: result.append(s) if s_new.execution is not None: @@ -207,7 +207,7 @@ def _scan_array(arr, search_name): @cache.memoize_default([]) def _check_array_additions(compare_array, module, is_list): """ - Checks if a `parsing.Array` has "add" statements: + Checks if a `pr.Array` has "add" statements: >>> a = [""] >>> a.append(1) """ @@ -310,7 +310,7 @@ def check_array_instances(instance): return helpers.generate_param_array([ai], instance.var_args.parent_stmt) -class ArrayInstance(parsing.Base): +class ArrayInstance(pr.Base): """ Used for the usage of set() and list(). This is definitely a hack, but a good one :-) @@ -364,7 +364,7 @@ def related_names(definitions, search_name, mods): follow = [] # There might be multiple search_name's in one call_path call_path = list(call.generate_call_path()) for i, name in enumerate(call_path): - # name is `parsing.NamePart`. + # name is `pr.NamePart`. if name == search_name: follow.append(call_path[:i + 1]) @@ -392,7 +392,7 @@ def related_names(definitions, search_name, mods): except KeyError: continue for stmt in stmts: - if isinstance(stmt, parsing.Import): + if isinstance(stmt, pr.Import): count = 0 imps = [] for i in stmt.get_all_import_names(): @@ -420,7 +420,7 @@ def related_name_add_import_modules(definitions, search_name): """ Adds the modules of the imports """ new = set() for d in definitions: - if isinstance(d.parent, parsing.Import): + if isinstance(d.parent, pr.Import): s = imports.ImportPath(d.parent, direct_resolve=True) try: new.add(s.follow(is_goto=True)[0]) @@ -438,7 +438,7 @@ def check_flow_information(flow, search_name, pos): ensures that `k` is a string. """ result = [] - if isinstance(flow, (parsing.Scope, fast_parser.Module)) and not result: + if isinstance(flow, (pr.Scope, fast_parser.Module)) and not result: for ass in reversed(flow.asserts): if pos is None or ass.start_pos > pos: continue @@ -446,7 +446,7 @@ def check_flow_information(flow, search_name, pos): if result: break - if isinstance(flow, parsing.Flow) and not result: + if isinstance(flow, pr.Flow) and not result: if flow.command in ['if', 'while'] and len(flow.inits) == 1: result = check_statement_information(flow.inits[0], search_name) return result @@ -459,7 +459,7 @@ def check_statement_information(stmt, search_name): call = ass.get_only_subelement() except AttributeError: assert False - assert type(call) == parsing.Call and str(call.name) == 'isinstance' + assert type(call) == pr.Call and str(call.name) == 'isinstance' assert bool(call.execution) # isinstance check @@ -467,11 +467,11 @@ def check_statement_information(stmt, search_name): assert len(isinst) == 2 # has two params assert len(isinst[0]) == 1 assert len(isinst[1]) == 1 - assert isinstance(isinst[0][0], parsing.Call) + assert isinstance(isinst[0][0], pr.Call) # names fit? assert str(isinst[0][0].name) == search_name classes_call = isinst[1][0] # class_or_type_or_tuple - assert isinstance(classes_call, parsing.Call) + assert isinstance(classes_call, pr.Call) result = [] for c in evaluate.follow_call(classes_call): if isinstance(c, evaluate.Array): diff --git a/jedi/evaluate.py b/jedi/evaluate.py index 7bfbe7a7..468e4105 100644 --- a/jedi/evaluate.py +++ b/jedi/evaluate.py @@ -19,8 +19,7 @@ Evaluation of Python code in |jedi| is based on three assumptions: That said, there's mainly one entry point in this script: ``follow_statement``. This is where autocompletion starts. Everything you want to complete is either -a ``parsing.Statement`` or some special name like ``class``, which is easy to -complete. +a ``Statement`` or some special name like ``class``, which is easy to complete. Therefore you need to understand what follows after ``follow_statement``. Let's make an example: @@ -84,7 +83,7 @@ import copy import common import cache -import parsing +import parsing_representation as pr import debug import builtin import imports @@ -100,13 +99,13 @@ class DecoratorNotFound(LookupError): pass -class Executable(parsing.Base): +class Executable(pr.Base): """ An instance is also an executable - because __init__ is called """ def __init__(self, base, var_args=None): self.base = base # The param input array. if var_args is None: - var_args = parsing.Array(None, None) + var_args = pr.Array(None, None) self.var_args = var_args def get_parent_until(self, *args, **kwargs): @@ -161,7 +160,7 @@ class Instance(use_metaclass(cache.CachedMetaClass, Executable)): # This loop adds the names of the self object, copies them and removes # the self. for sub in self.base.subscopes: - if isinstance(sub, parsing.Class): + if isinstance(sub, pr.Class): continue # Get the self name, if there's one. self_name = self.get_func_self_name(sub) @@ -256,9 +255,9 @@ class InstanceElement(use_metaclass(cache.CachedMetaClass)): variable (e.g. self.variable or class methods). """ def __init__(self, instance, var, is_class_var=False): - if isinstance(var, parsing.Function): + if isinstance(var, pr.Function): var = Function(var) - elif isinstance(var, parsing.Class): + elif isinstance(var, pr.Class): var = Class(var) self.instance = instance self.var = var @@ -269,15 +268,15 @@ class InstanceElement(use_metaclass(cache.CachedMetaClass)): def parent(self): par = self.var.parent if isinstance(par, Class) and par == self.instance.base \ - or isinstance(par, parsing.Class) \ + or isinstance(par, pr.Class) \ and par == self.instance.base.base: par = self.instance - elif not isinstance(par, parsing.Module): + elif not isinstance(par, pr.Module): par = InstanceElement(self.instance, par, self.is_class_var) return par def get_parent_until(self, *args, **kwargs): - return parsing.Simple.get_parent_until(self, *args, **kwargs) + return pr.Simple.get_parent_until(self, *args, **kwargs) def get_decorated_func(self): """ Needed because the InstanceElement should not be stripped """ @@ -306,9 +305,9 @@ class InstanceElement(use_metaclass(cache.CachedMetaClass)): return "<%s of %s>" % (type(self).__name__, self.var) -class Class(use_metaclass(cache.CachedMetaClass, parsing.Base)): +class Class(use_metaclass(cache.CachedMetaClass, pr.Base)): """ - This class is not only important to extend `parsing.Class`, it is also a + This class is not only important to extend `pr.Class`, it is also a important for descriptors (if the descriptor methods are evaluated or not). """ def __init__(self, base): @@ -372,7 +371,7 @@ class Class(use_metaclass(cache.CachedMetaClass, parsing.Base)): return "" % (type(self).__name__, self.base) -class Function(use_metaclass(cache.CachedMetaClass, parsing.Base)): +class Function(use_metaclass(cache.CachedMetaClass, pr.Base)): """ Needed because of decorators. Decorators are evaluated here. """ @@ -419,7 +418,7 @@ class Function(use_metaclass(cache.CachedMetaClass, parsing.Base)): f = wrappers[0] debug.dbg('decorator end', f) - if f != self.base_func and isinstance(f, parsing.Function): + if f != self.base_func and isinstance(f, pr.Function): f = Function(f) return f @@ -489,12 +488,12 @@ class Execution(Executable): objects = follow_call_list([self.var_args[0]]) return [o.base for o in objects if isinstance(o, Instance)] elif func_name == 'super': - accept = (parsing.Function,) + accept = (pr.Function,) func = self.var_args.parent_stmt.get_parent_until(accept) if func.isinstance(*accept): - cls = func.get_parent_until(accept + (parsing.Class,), + cls = func.get_parent_until(accept + (pr.Class,), include_current=False) - if isinstance(cls, parsing.Class): + if isinstance(cls, pr.Class): cls = Class(cls) su = cls.get_super_classes() if su: @@ -546,7 +545,7 @@ class Execution(Executable): def get_params(self): """ This returns the params for an Execution/Instance and is injected as a - 'hack' into the parsing.Function class. + 'hack' into the pr.Function class. This needs to be here, because Instance can have __init__ functions, which act the same way as normal functions. """ @@ -556,7 +555,7 @@ class Execution(Executable): """ parent_stmt = self.var_args.parent_stmt pos = parent_stmt.start_pos if parent_stmt else None - calls = parsing.Array(pos, parsing.Array.NOARRAY, parent_stmt) + calls = pr.Array(pos, pr.Array.NOARRAY, parent_stmt) calls.values = values calls.keys = keys calls.type = array_type @@ -615,7 +614,7 @@ class Execution(Executable): array_type = None if assignment[0] == '*': # *args param - array_type = parsing.Array.TUPLE + array_type = pr.Array.TUPLE if value: values.append(value) for key, value in var_arg_iterator: @@ -626,7 +625,7 @@ class Execution(Executable): values.append(value) elif assignment[0] == '**': # **kwargs param - array_type = parsing.Array.DICT + array_type = pr.Array.DICT if non_matching_keys: keys, values = zip(*non_matching_keys) else: @@ -681,10 +680,10 @@ class Execution(Executable): if hasattr(array, 'get_contents'): for key, field in array.get_contents(): # Take the first index. - if isinstance(key, parsing.Name): + if isinstance(key, pr.Name): name = key else: - # `parsing`.[Call|Function|Class] lookup. + # `pr`.[Call|Function|Class] lookup. name = key[0].name yield name, field # Normal arguments (including key arguments). @@ -705,7 +704,7 @@ class Execution(Executable): Call the default method with the own instance (self implements all the necessary functions). Add also the params. """ - return self.get_params() + parsing.Scope.get_set_vars(self) + return self.get_params() + pr.Scope.get_set_vars(self) def copy_properties(self, prop): """ @@ -724,7 +723,7 @@ class Execution(Executable): else: copied = helpers.fast_parent_copy(element) copied.parent = self._scope_copy(copied.parent) - if isinstance(copied, parsing.Function): + if isinstance(copied, pr.Function): copied = Function(copied) objects.append(copied) return objects @@ -774,14 +773,14 @@ class Execution(Executable): return self.copy_properties('subscopes') def get_statement_for_position(self, pos): - return parsing.Scope.get_statement_for_position(self, pos) + return pr.Scope.get_statement_for_position(self, pos) def __repr__(self): return "<%s of %s>" % \ (type(self).__name__, self.base) -class Generator(use_metaclass(cache.CachedMetaClass, parsing.Base)): +class Generator(use_metaclass(cache.CachedMetaClass, pr.Base)): """ Cares for `yield` statements. """ def __init__(self, func, var_args): super(Generator, self).__init__() @@ -797,7 +796,7 @@ class Generator(use_metaclass(cache.CachedMetaClass, parsing.Base)): none_pos = (0, 0) executes_generator = ('__next__', 'send') for n in ('close', 'throw') + executes_generator: - name = parsing.Name(builtin.Builtin.scope, [(n, none_pos)], + name = pr.Name(builtin.Builtin.scope, [(n, none_pos)], none_pos, none_pos) if n in executes_generator: name.parent = self @@ -821,9 +820,9 @@ class Generator(use_metaclass(cache.CachedMetaClass, parsing.Base)): return "<%s of %s>" % (type(self).__name__, self.func) -class Array(use_metaclass(cache.CachedMetaClass, parsing.Base)): +class Array(use_metaclass(cache.CachedMetaClass, pr.Base)): """ - Used as a mirror to parsing.Array, if needed. It defines some getter + Used as a mirror to pr.Array, if needed. It defines some getter methods which are important in this module. """ def __init__(self, array): @@ -858,7 +857,7 @@ class Array(use_metaclass(cache.CachedMetaClass, parsing.Base)): def get_exact_index_types(self, index): """ Here the index is an int. Raises IndexError/KeyError """ - if self._array.type == parsing.Array.DICT: + if self._array.type == pr.Array.DICT: old_index = index index = None for i, key_elements in enumerate(self._array.keys): @@ -885,7 +884,7 @@ class Array(use_metaclass(cache.CachedMetaClass, parsing.Base)): def get_defined_names(self): """ - This method generates all ArrayElements for one parsing.Array. + This method generates all ArrayElements for one pr.Array. It returns e.g. for a list: append, pop, ... """ # `array.type` is a string with the type, e.g. 'list'. @@ -949,7 +948,7 @@ def get_defined_names_for_position(scope, position=None, start_scope=None): # because class variables are always valid and the `self.` variables, too. if (not position or isinstance(scope, (Array, Instance)) or start_scope != scope - and isinstance(start_scope, (parsing.Function, Execution))): + and isinstance(start_scope, (pr.Function, Execution))): return names names_new = [] for n in names: @@ -966,13 +965,13 @@ def get_names_for_scope(scope, position=None, star_search=True, the whole thing would probably start a little recursive madness. """ in_func_scope = scope - non_flow = scope.get_parent_until(parsing.Flow, reverse=True) + non_flow = scope.get_parent_until(pr.Flow, reverse=True) while scope: - # `parsing.Class` is used, because the parent is never `Class`. + # `pr.Class` is used, because the parent is never `Class`. # Ignore the Flows, because the classes and functions care for that. # InstanceElement of Class is ignored, if it is not the start scope. - if not (scope != non_flow and scope.isinstance(parsing.Class) - or scope.isinstance(parsing.Flow) + if not (scope != non_flow and scope.isinstance(pr.Class) + or scope.isinstance(pr.Flow) or scope.isinstance(Instance) and non_flow.isinstance(Function) ): @@ -985,14 +984,14 @@ def get_names_for_scope(scope, position=None, star_search=True, position, in_func_scope) except StopIteration: raise common.MultiLevelStopIteration('StopIteration raised') - if scope.isinstance(parsing.ForFlow) and scope.is_list_comp: + if scope.isinstance(pr.ForFlow) and scope.is_list_comp: # is a list comprehension yield scope, scope.get_set_vars(is_internal_call=True) scope = scope.parent # This is used, because subscopes (Flow scopes) would distort the # results. - if scope and scope.isinstance(Function, parsing.Function, Execution): + if scope and scope.isinstance(Function, pr.Function, Execution): in_func_scope = scope # Add star imports. @@ -1028,7 +1027,7 @@ def get_scopes_for_name(scope, name_str, position=None, search_global=False, res_new = [] for r in result: add = [] - if r.isinstance(parsing.Statement): + if r.isinstance(pr.Statement): check_instance = None if isinstance(r, InstanceElement) and r.is_class_var: check_instance = r.instance @@ -1037,14 +1036,14 @@ def get_scopes_for_name(scope, name_str, position=None, search_global=False, # Global variables handling. if r.is_global(): for token_name in r.token_list[1:]: - if isinstance(token_name, parsing.Name): + if isinstance(token_name, pr.Name): add = get_scopes_for_name(r.parent, str(token_name)) else: # generated objects are used within executions, but these # objects are in functions, and we have to dynamically # execute first. - if isinstance(r, parsing.Param): + if isinstance(r, pr.Param): func = r.parent # Instances are typically faked, if the instance is not # called from outside. Here we check it for __init__ @@ -1075,13 +1074,13 @@ def get_scopes_for_name(scope, name_str, position=None, search_global=False, if check_instance is not None: # class renames add = [InstanceElement(check_instance, a, True) - if isinstance(a, (Function, parsing.Function)) + if isinstance(a, (Function, pr.Function)) else a for a in add] res_new += add else: - if isinstance(r, parsing.Class): + if isinstance(r, pr.Class): r = Class(r) - elif isinstance(r, parsing.Function): + elif isinstance(r, pr.Function): r = Function(r) if r.isinstance(Function): try: @@ -1117,14 +1116,14 @@ def get_scopes_for_name(scope, name_str, position=None, search_global=False, no_break_scope = False par = name.parent - if par.isinstance(parsing.Flow): + if par.isinstance(pr.Flow): if par.command == 'for': result += handle_for_loops(par) else: debug.warning('Flow: Why are you here? %s' % par.command) - elif par.isinstance(parsing.Param) \ + elif par.isinstance(pr.Param) \ and par.parent is not None \ - and par.parent.parent.isinstance(parsing.Class) \ + and par.parent.parent.isinstance(pr.Class) \ and par.position_nr == 0: # This is where self gets added - this happens at another # place, if the var_args are clear. But sometimes the class is @@ -1136,14 +1135,14 @@ def get_scopes_for_name(scope, name_str, position=None, search_global=False, inst = Instance(Class(par.parent.parent)) inst.is_generated = True result.append(inst) - elif par.isinstance(parsing.Statement): + elif par.isinstance(pr.Statement): def is_execution(arr): for a in arr: a = a[0] # rest is always empty with assignees - if a.isinstance(parsing.Array): + if a.isinstance(pr.Array): if is_execution(a): return True - elif a.isinstance(parsing.Call): + elif a.isinstance(pr.Call): # Compare start_pos, because names may be different # because of executions. if a.name.start_pos == name.start_pos \ @@ -1185,7 +1184,7 @@ def get_scopes_for_name(scope, name_str, position=None, search_global=False, for name in sorted(name_list, key=comparison_func, reverse=True): p = name.parent.parent if name.parent else None if isinstance(p, InstanceElement) \ - and isinstance(p.var, parsing.Class): + and isinstance(p.var, pr.Class): p = p.var if name_str == name.get_code() and p not in break_scopes: r, no_break_scope = process(name) @@ -1249,7 +1248,7 @@ def get_scopes_for_name(scope, name_str, position=None, search_global=False, if isinstance(scope, Instance): scope_generator = scope.scope_generator() else: - if isinstance(scope, (Class, parsing.Module)): + if isinstance(scope, (Class, pr.Module)): # classes are only available directly via chaining? # strange stuff... names = scope.get_defined_names() @@ -1265,7 +1264,7 @@ def get_scopes_for_name(scope, name_str, position=None, search_global=False, def check_getattr(inst, name_str): result = [] # str is important to lose the NamePart! - name = parsing.Call(str(name_str), parsing.Call.STRING, (0, 0), inst) + name = pr.Call(str(name_str), pr.Call.STRING, (0, 0), inst) args = helpers.generate_param_array([name]) try: result = inst.execute_subscope_by_name('__getattr__', args) @@ -1330,7 +1329,7 @@ def assign_tuples(tup, results, seek_name): Here, if seek_name is "a", the number type will be returned. The first part (before `=`) is the param tuples, the second one result. - :type tup: parsing.Array + :type tup: pr.Array """ def eval_results(index): types = [] @@ -1347,10 +1346,10 @@ def assign_tuples(tup, results, seek_name): return types result = [] - if tup.type == parsing.Array.NOARRAY: + if tup.type == pr.Array.NOARRAY: # Here we have unnessecary braces, which we just remove. arr = tup.get_only_subelement() - if type(arr) == parsing.Call: + if type(arr) == pr.Call: if arr.name.names[-1] == seek_name: result = results else: @@ -1364,7 +1363,7 @@ def assign_tuples(tup, results, seek_name): t = t[0] # Check the left part, if there are still tuples in it or a Call. - if isinstance(t, parsing.Array): + if isinstance(t, pr.Array): # These are "sub"-tuples. result += assign_tuples(t, eval_results(i), seek_name) else: @@ -1382,7 +1381,7 @@ def follow_statement(stmt, seek_name=None): In case multiple names are defined in the statement, `seek_name` returns the result for this name. - :param stmt: A `parsing.Statement`. + :param stmt: A `pr.Statement`. :param seek_name: A string. """ debug.dbg('follow_stmt %s (%s)' % (stmt, seek_name)) @@ -1409,28 +1408,27 @@ def follow_statement(stmt, seek_name=None): def follow_call_list(call_list, follow_array=False): """ The call_list has a special structure. - This can be either `parsing.Array` or `list of list`. + This can be either `pr.Array` or `list of list`. It is used to evaluate a two dimensional object, that has calls, arrays and operators in it. """ def evaluate_list_comprehension(lc, parent=None): input = lc.input nested_lc = lc.input.token_list[0] - if isinstance(nested_lc, parsing.ListComprehension): + if isinstance(nested_lc, pr.ListComprehension): # is nested LC input = nested_lc.stmt module = input.get_parent_until() - loop = parsing.ForFlow(module, [input], lc.stmt.start_pos, + loop = pr.ForFlow(module, [input], lc.stmt.start_pos, lc.middle, True) loop.parent = lc.stmt.parent if parent is None else parent - if isinstance(nested_lc, parsing.ListComprehension): + if isinstance(nested_lc, pr.ListComprehension): loop = evaluate_list_comprehension(nested_lc, loop) return loop - if parsing.Array.is_type(call_list, parsing.Array.TUPLE, - parsing.Array.DICT): + if pr.Array.is_type(call_list, pr.Array.TUPLE, pr.Array.DICT): # Tuples can stand just alone without any braces. These would be # recognized as separate calls, but actually are a tuple. result = follow_call(call_list) @@ -1439,9 +1437,9 @@ def follow_call_list(call_list, follow_array=False): for calls in call_list: calls_iterator = iter(calls) for call in calls_iterator: - if parsing.Array.is_type(call, parsing.Array.NOARRAY): + if pr.Array.is_type(call, pr.Array.NOARRAY): result += follow_call_list(call, follow_array=True) - elif isinstance(call, parsing.ListComprehension): + elif isinstance(call, pr.ListComprehension): loop = evaluate_list_comprehension(call) stmt = copy.copy(call.stmt) stmt.parent = loop @@ -1449,7 +1447,7 @@ def follow_call_list(call_list, follow_array=False): # comprehensions result += follow_statement(stmt) else: - if isinstance(call, (parsing.Lambda)): + if isinstance(call, (pr.Lambda)): result.append(Function(call)) # With things like params, these can also be functions... elif isinstance(call, (Function, Class, Instance, @@ -1478,7 +1476,7 @@ def follow_call_list(call_list, follow_array=False): # if it is an iterable, ignore * operations next(calls_iterator) - if follow_array and isinstance(call_list, parsing.Array): + if follow_array and isinstance(call_list, pr.Array): # call_list can also be a two dimensional array call_path = call_list.generate_call_path() next(call_path, None) # the first one has been used already @@ -1497,18 +1495,18 @@ def follow_call(call): def follow_call_path(path, scope, position): - """ Follows a path generated by `parsing.Call.generate_call_path()` """ + """ Follows a path generated by `pr.Call.generate_call_path()` """ current = next(path) - if isinstance(current, parsing.Array): + if isinstance(current, pr.Array): result = [Array(current)] else: - if isinstance(current, parsing.NamePart): + if isinstance(current, pr.NamePart): # This is the first global lookup. scopes = get_scopes_for_name(scope, current, position=position, search_global=True) else: - if current.type in (parsing.Call.STRING, parsing.Call.NUMBER): + if current.type in (pr.Call.STRING, pr.Call.NUMBER): t = type(current.name).__name__ scopes = get_scopes_for_name(builtin.Builtin.scope, t) else: @@ -1559,12 +1557,12 @@ def follow_path(path, scope, call_scope, position=None): debug.dbg('follow %s in scope %s' % (current, scope)) result = [] - if isinstance(current, parsing.Array): + if isinstance(current, pr.Array): # This must be an execution, either () or []. - if current.type == parsing.Array.LIST: + if current.type == pr.Array.LIST: if hasattr(scope, 'get_index_types'): result = scope.get_index_types(current) - elif current.type not in [parsing.Array.DICT]: + elif current.type not in [pr.Array.DICT]: # Scope must be a class or func - make an instance or execution. debug.dbg('exe', scope) result = Execution(scope, current).get_return_types() @@ -1587,7 +1585,7 @@ def follow_path(path, scope, call_scope, position=None): def filter_private_variable(scope, call_scope, var_name): if isinstance(var_name, (str, unicode)) \ and var_name.startswith('__') and isinstance(scope, Instance): - s = call_scope.get_parent_until((parsing.Class, Instance)) + s = call_scope.get_parent_until((pr.Class, Instance)) if s != scope and s != scope.base.base: return True return False diff --git a/jedi/fast_parser.py b/jedi/fast_parser.py index dbc4eb59..477b46e7 100644 --- a/jedi/fast_parser.py +++ b/jedi/fast_parser.py @@ -4,10 +4,11 @@ import operator from _compatibility import use_metaclass, reduce, property import settings import parsing +import parsing_representation as pr import cache -class Module(parsing.Simple, parsing.Module): +class Module(pr.Simple, pr.Module): def __init__(self, parsers): self._end_pos = None, None super(Module, self).__init__(self, (1,0)) @@ -141,7 +142,7 @@ class CachedFastParser(type): return parsing.Parser(source, module_path, user_position) pi = cache.parser_cache.get(module_path, None) - if pi is None or isinstance(pi.parser, parsing.Parser): + if pi is None or isinstance(pi.parser, pr.Parser): p = super(CachedFastParser, self).__call__(source, module_path, user_position) else: @@ -152,7 +153,7 @@ class CachedFastParser(type): class FastParser(use_metaclass(CachedFastParser)): def __init__(self, code, module_path=None, user_position=None): - # set values like `parsing.Module`. + # set values like `pr.Module`. self.module_path = module_path self.user_position = user_position @@ -168,11 +169,11 @@ class FastParser(use_metaclass(CachedFastParser)): for p in self.parsers: if p.user_scope: if self._user_scope is not None and not \ - isinstance(self._user_scope, parsing.SubModule): + isinstance(self._user_scope, pr.SubModule): continue self._user_scope = p.user_scope - if isinstance(self._user_scope, parsing.SubModule): + if isinstance(self._user_scope, pr.SubModule): self._user_scope = self.module return self._user_scope @@ -193,10 +194,10 @@ class FastParser(use_metaclass(CachedFastParser)): def scan_user_scope(self, sub_module): """ Scan with self.user_position. - :type sub_module: parsing.SubModule + :type sub_module: pr.SubModule """ for scope in sub_module.statements + sub_module.subscopes: - if isinstance(scope, parsing.Scope): + if isinstance(scope, pr.Scope): if scope.start_pos <= self.user_position <= scope.end_pos: return self.scan_user_scope(scope) or scope return None diff --git a/jedi/helpers.py b/jedi/helpers.py index 84c46f41..97e7a862 100644 --- a/jedi/helpers.py +++ b/jedi/helpers.py @@ -1,6 +1,6 @@ import copy -import parsing +import parsing_representation as pr import evaluate import debug import builtin @@ -72,7 +72,7 @@ class RecursionNode(object): # Don't check param instances, they are not causing recursions # The same's true for the builtins, because the builtins are really # simple. - self.is_ignored = isinstance(stmt, parsing.Param) \ + self.is_ignored = isinstance(stmt, pr.Param) \ or (self.script == builtin.Builtin.scope) def __eq__(self, other): @@ -185,14 +185,14 @@ def fast_parent_copy(obj): continue elif isinstance(value, list): setattr(new_obj, key, list_rec(value)) - elif isinstance(value, (parsing.Simple, parsing.Call)): + elif isinstance(value, (pr.Simple, pr.Call)): setattr(new_obj, key, recursion(value)) return new_obj def list_rec(list_obj): copied_list = list_obj[:] # lists, tuples, strings, unicode for i, el in enumerate(copied_list): - if isinstance(el, (parsing.Simple, parsing.Call)): + if isinstance(el, (pr.Simple, pr.Call)): copied_list[i] = recursion(el) elif isinstance(el, list): copied_list[i] = list_rec(el) @@ -209,7 +209,7 @@ def generate_param_array(args_tuple, parent_stmt=None): else: values.append([arg]) pos = None - arr = parsing.Array(pos, parsing.Array.TUPLE, parent_stmt, values=values) + arr = pr.Array(pos, pr.Array.TUPLE, parent_stmt, values=values) return arr @@ -229,9 +229,9 @@ def array_for_pos(arr, pos): result = arr for sub in arr: for s in sub: - if isinstance(s, parsing.Array): + if isinstance(s, pr.Array): result = array_for_pos(s, pos)[0] or result - elif isinstance(s, parsing.Call): + elif isinstance(s, pr.Call): if s.execution: result = array_for_pos(s.execution, pos)[0] or result if s.next: @@ -250,13 +250,13 @@ def search_function_call(arr, pos): for sub in arr.values: call = None for s in sub: - if isinstance(s, parsing.Array): + if isinstance(s, pr.Array): new = search_function_call(s, pos) if new[0] is not None: call, index, stop = new if stop: return call, index, stop - elif isinstance(s, parsing.Call): + elif isinstance(s, pr.Call): start_s = s # check parts of calls while s is not None: @@ -275,8 +275,7 @@ def search_function_call(arr, pos): # next reset = c or s if reset.execution.type not in \ - [parsing.Array.TUPLE, - parsing.Array.NOARRAY]: + [pr.Array.TUPLE, pr.Array.NOARRAY]: return start_s, index, False reset.execution = None diff --git a/jedi/imports.py b/jedi/imports.py index 010c66c4..5e3c6358 100644 --- a/jedi/imports.py +++ b/jedi/imports.py @@ -8,7 +8,7 @@ import sys import builtin import modules import debug -import parsing +import parsing_representation as pr import evaluate import itertools import cache @@ -21,9 +21,9 @@ class ModuleNotFound(Exception): pass -class ImportPath(parsing.Base): +class ImportPath(pr.Base): """ - An ImportPath is the path of a `parsing.Import` object. + An ImportPath is the path of a `pr.Import` object. """ class _GlobalNamespace(object): def __init__(self): @@ -86,8 +86,8 @@ class ImportPath(parsing.Base): # 0 (0 is not a valid line number). zero = (0, 0) names = i.namespace.names[1:] - n = parsing.Name(i.module, names, zero, zero, self.import_stmt) - new = parsing.Import(i.module, zero, zero, n) + n = pr.Name(i.module, names, zero, zero, self.import_stmt) + new = pr.Import(i.module, zero, zero, n) new.parent = parent debug.dbg('Generated a nested import: %s' % new) return new @@ -113,7 +113,7 @@ class ImportPath(parsing.Base): except IOError: pass else: - if on_import_stmt and isinstance(scope, parsing.Module) \ + if on_import_stmt and isinstance(scope, pr.Module) \ and scope.path.endswith('__init__.py'): pkg_path = os.path.dirname(scope.path) names += self.get_module_names([pkg_path]) @@ -141,7 +141,7 @@ class ImportPath(parsing.Base): names = [] for module_loader, name, is_pkg in pkgutil.iter_modules(search_path): inf_pos = (float('inf'), float('inf')) - names.append(parsing.Name(self.GlobalNamespace, [(name, inf_pos)], + names.append(pr.Name(self.GlobalNamespace, [(name, inf_pos)], inf_pos, inf_pos, self.import_stmt)) return names @@ -295,7 +295,7 @@ def strip_imports(scopes): """ result = [] for s in scopes: - if isinstance(s, parsing.Import): + if isinstance(s, pr.Import): result += ImportPath(s).follow() else: result.append(s) diff --git a/jedi/modules.py b/jedi/modules.py index 60079470..64adcb3c 100644 --- a/jedi/modules.py +++ b/jedi/modules.py @@ -9,6 +9,7 @@ import os import cache import parsing +import parsing_representation as pr import fast_parser import builtin import debug @@ -255,7 +256,7 @@ def sys_path_with_modifications(module): except AttributeError: continue n = call.name - if not isinstance(n, parsing.Name) or len(n.names) != 3: + if not isinstance(n, pr.Name) or len(n.names) != 3: continue if n.names[:2] != ('sys', 'path'): continue @@ -268,7 +269,7 @@ def sys_path_with_modifications(module): continue if array_cmd == 'insert': - exe_type, exe.type = exe.type, parsing.Array.NOARRAY + exe_type, exe.type = exe.type, pr.Array.NOARRAY exe_pop = exe.values.pop(0) res = execute_code(exe.get_code()) if res is not None: