diff --git a/api.py b/api.py index e444e40e..e58dcf34 100644 --- a/api.py +++ b/api.py @@ -163,8 +163,8 @@ class Script(object): try: scopes = self._prepare_goto(path, True) except NotFoundError: - scope_generator = evaluate.get_names_for_scope(self.parser.user_scope, - self.pos) + scope_generator = evaluate.get_names_for_scope( + self.parser.user_scope, self.pos) completions = [] for scope, name_list in scope_generator: for c in name_list: @@ -173,7 +173,7 @@ class Script(object): completions = [] debug.dbg('possible scopes', scopes) for s in scopes: - # TODO is this really the right way? just ignore the functions? \ + # TODO is this really the right way? just ignore the funcs? \ # do the magic functions first? and then recheck here? if not isinstance(s, evaluate.Function): if isinstance(s, imports.ImportPath): @@ -184,12 +184,13 @@ class Script(object): completions.append((c, s)) completions = [(c, s) for c, s in completions - if settings.case_insensitive_completion - and c.names[-1].lower().startswith(like.lower()) - or c.names[-1].startswith(like)] + if settings.case_insensitive_completion + and c.names[-1].lower().startswith(like.lower()) + or c.names[-1].startswith(like)] needs_dot = not dot and path - c = [Completion(c, needs_dot, len(like), s) for c, s in set(completions)] + completions = set(completions) + c = [Completion(c, needs_dot, len(like), s) for c, s in completions] _clear_caches() return c @@ -201,8 +202,8 @@ class Script(object): user_stmt = self.parser.user_stmt if not user_stmt and len(goto_path.split('\n')) > 1: # If the user_stmt is not defined and the goto_path is multi line, - # something's strange. Most probably the backwards tokenizer matched to - # much. + # something's strange. Most probably the backwards tokenizer + # matched to much. return [] if isinstance(user_stmt, parsing.Import): @@ -218,7 +219,8 @@ class Script(object): kill_count=kill_count, direct_resolve=True)] else: # just parse one statement, take it and evaluate it - r = parsing.PyFuzzyParser(goto_path, self.source_path, no_docstr=True) + r = parsing.PyFuzzyParser(goto_path, self.source_path, + no_docstr=True) try: stmt = r.module.statements[0] except IndexError: @@ -229,11 +231,10 @@ class Script(object): scopes = evaluate.follow_statement(stmt) return scopes - def get_definition(self): """ - Returns the definitions of a the path under the cursor. - This is not a goto function! This follows complicated paths and returns the + Returns the definitions of a the path under the cursor. This is + not a goto function! This follows complicated paths and returns the end, not the first definition. :param source: The source code of the current file @@ -275,7 +276,6 @@ class Script(object): _clear_caches() return sorted(d, key=lambda x: (x.module_path, x.start_pos)) - def goto(self): goto_path = self.module.get_path_under_cursor() goto_path, dot, search_name = self._get_completion_parts(goto_path) @@ -298,13 +298,12 @@ class Script(object): _clear_caches() return sorted(d, key=lambda x: (x.module_path, x.start_pos)) - def related_names(self): """ - Returns `dynamic.RelatedName` objects, which contain all names, that are - defined by the same variable, function, class or import. - This function can be used either to show all the usages of a variable or - for renaming purposes. + Returns `dynamic.RelatedName` objects, which contain all names, that + are defined by the same variable, function, class or import. + This function can be used either to show all the usages of a variable + or for renaming purposes. """ goto_path = self.module.get_path_under_cursor() goto_path, dot, search_name = self._get_completion_parts(goto_path) @@ -323,7 +322,8 @@ class Script(object): else: e = evaluate.Class(self.module.parser.user_scope) definitions = [e] - elif isinstance(self.module.parser.user_stmt, (parsing.Param, parsing.Import)): + elif isinstance(self.module.parser.user_stmt, + (parsing.Param, parsing.Import)): definitions = [self.module.parser.user_stmt] else: scopes = self._prepare_goto(goto_path) @@ -348,11 +348,12 @@ class Script(object): elif isinstance(d, parsing.Import): is_user = d == self.module.parser.user_stmt check_names = [d.namespace, d.alias, d.from_ns] if is_user \ - else d.get_defined_names() + else d.get_defined_names() for name in check_names: if name: for n in name.names: - if n.start_pos <= self.pos <= n.end_pos or not is_user: + if n.start_pos <= self.pos <= n.end_pos \ + or not is_user: names.append(dynamic.RelatedName(n, d)) elif isinstance(d, parsing.Name): names.append(dynamic.RelatedName(d.names[0], d)) @@ -364,7 +365,9 @@ class Script(object): def get_in_function_call(self): def scan_array_for_pos(arr, pos): - """ Returns the function Call that match search_name in an Array. """ + """ + Returns the function Call that match search_name in an Array. + """ index = None call = None for index, sub in enumerate(arr): @@ -381,7 +384,8 @@ class Script(object): if s.execution is not None: if s.execution.start_pos <= pos: call = s - c, index = scan_array_for_pos(s.execution, pos) + c, index = scan_array_for_pos(s.execution, + pos) if c is not None: call = c else: @@ -404,7 +408,8 @@ class Script(object): if len(origins) == 0: return None - executable = origins[0] # just take entry zero, because we need just one. + # just take entry zero, because we need just one. + executable = origins[0] return CallDef(executable, index) def _get_completion_parts(self, path): diff --git a/evaluate.py b/evaluate.py index 3c69f7ce..90497933 100644 --- a/evaluate.py +++ b/evaluate.py @@ -1183,7 +1183,7 @@ def get_scopes_for_name(scope, name_str, position=None, search_global=False): scope_generator = scope.scope_generator() else: if isinstance(scope, Class): - # classes are only available directly via chaining? + # classes are only available directly via chaining? # strange stuff... names = scope.get_defined_names() else: @@ -1192,6 +1192,7 @@ def get_scopes_for_name(scope, name_str, position=None, search_global=False): return descriptor_check(remove_statements(filter_name(scope_generator))) + def check_getattr(inst, name_str): result = [] # str is important to lose the NamePart! diff --git a/test/regression.py b/test/regression.py index 2f5aab78..7bf6a49c 100755 --- a/test/regression.py +++ b/test/regression.py @@ -90,7 +90,7 @@ class TestRegression(unittest.TestCase): assert len(s) == 1 assert list(s)[0].word == 'str' - s = self.complete("", (1,0)) + s = self.complete("", (1, 0)) assert len(s) > 0 def test_get_definition_on_import(self): @@ -115,13 +115,13 @@ class TestRegression(unittest.TestCase): s2 = "isinstance(), " check = lambda call_def, index: call_def and call_def.index == index - assert check(self.get_in_function_call(s, (1,11)), 0) - assert check(self.get_in_function_call(s, (1,14)), 1) - assert check(self.get_in_function_call(s, (1,15)), 1) - assert check(self.get_in_function_call(s, (1,18)), 0) + assert check(self.get_in_function_call(s, (1, 11)), 0) + assert check(self.get_in_function_call(s, (1, 14)), 1) + assert check(self.get_in_function_call(s, (1, 15)), 1) + assert check(self.get_in_function_call(s, (1, 18)), 0) - #assert check(self.get_in_function_call(s2, (1,11)), 0) # TODO uncomment - assert self.get_in_function_call(s2, (1,12)) is None + ##assert check(self.get_in_function_call(s2, (1, 11)), 0) # TODO uncomment + assert self.get_in_function_call(s2, (1, 12)) is None assert self.get_in_function_call(s2) is None if __name__ == '__main__':