diff --git a/evaluate.py b/evaluate.py index 5b5e7005..8702d218 100644 --- a/evaluate.py +++ b/evaluate.py @@ -647,7 +647,7 @@ class Generator(object): content of a generator. """ names = [] - none_pos = (None,None) + none_pos = (0, 0) executes_generator = ('__next__', 'send') for n in ('close', 'throw') + executes_generator: name = parsing.Name([n], none_pos, none_pos) diff --git a/functions.py b/functions.py index 884f6ddf..c74363c0 100644 --- a/functions.py +++ b/functions.py @@ -162,7 +162,6 @@ def complete(source, line, column, source_path): if not isinstance(s, evaluate.Function): completions += s.get_defined_names() - #completions[0]. completions = [c for c in completions if c.names[-1].lower().startswith(like.lower())] diff --git a/imports.py b/imports.py index a74cc45a..6f46cd48 100644 --- a/imports.py +++ b/imports.py @@ -14,7 +14,9 @@ class ModuleNotFound(Exception): class ImportPath(object): - global_namespace = object() + class GlobalNamespace(object): + pass + def __init__(self, import_stmt, is_like_search=False): """ replace """ #print import_stmt @@ -24,6 +26,7 @@ class ImportPath(object): if import_stmt.namespace: self.import_path += import_stmt.namespace.names + self.is_like_search = is_like_search if is_like_search: # drop one path part, because that is used by the like search self.import_path.pop() @@ -33,7 +36,7 @@ class ImportPath(object): def get_defined_names(self): names = [] for scope in self.follow(): - if scope is ImportPath.global_namespace: + if scope is ImportPath.GlobalNamespace: names += self.get_module_names() names += self.get_module_names([self.file_path]) else: @@ -49,8 +52,8 @@ class ImportPath(object): def get_module_names(self, search_path=None): names = [] for module_loader, name, is_pkg in pkgutil.iter_modules(search_path): - names.append(parsing.Name([name], (float('inf'), float('inf')), - (float('inf'), float('inf')))) + inf = float('inf') + names.append(parsing.Name([name], (inf, inf), (inf, inf))) return names def follow(self): @@ -58,7 +61,9 @@ class ImportPath(object): """ if self.import_path: scope, rest = self.follow_file_system() - if rest: + if len(rest) > 1 or rest and self.is_like_search: + scopes = [] + elif rest: scopes = evaluate.follow_path(iter(rest), scope) else: scopes = [scope] @@ -68,7 +73,7 @@ class ImportPath(object): new += remove_star_imports(scope) scopes += new else: - scopes = [ImportPath.global_namespace] + scopes = [ImportPath.GlobalNamespace] debug.dbg('after import', scopes) return scopes diff --git a/parsing.py b/parsing.py index 2c1bc12b..d3063ec0 100644 --- a/parsing.py +++ b/parsing.py @@ -934,7 +934,7 @@ class PyFuzzyParser(object): :param user_position: The line/column, the user is currently on. :type user_position: tuple(int, int) """ - def __init__(self, code, module_path=None, user_position=(None,None)): + def __init__(self, code, module_path=None, user_position=None): self.user_position = user_position self.user_stmt = None self.code = code + '\n' # end with \n, because the parser needs it @@ -969,18 +969,19 @@ class PyFuzzyParser(object): return (self._line_of_tokenize_restart + self._tokenize_end_pos[0], self._tokenize_end_pos[1]) - def check_user_stmt(self, i): + def check_user_stmt(self, simple): + if not self.user_position: + return # the position is right - if i.start_pos < self.user_position <= i.end_pos: + if simple.start_pos < self.user_position <= simple.end_pos: if self.user_stmt is not None: # if there is already a user position (another import, because # imports are splitted) the names are checked. - for n in i.get_defined_names(): + for n in simple.get_defined_names(): if n.start_pos < self.user_position <= n.end_pos: - self.user_stmt = i + self.user_stmt = simple else: - self.user_stmt = i - #print 'up', self.user_stmt + self.user_stmt = simple def _parsedotname(self, pre_used_token=None): @@ -1246,6 +1247,7 @@ class PyFuzzyParser(object): if self.freshscope and len(tok_list) > 1 \ and self.last_token[1] == tokenize.STRING: self.scope.add_docstr(self.last_token[1]) + print('i want to see you') else: stmt = stmt_class(string, set_vars, used_funcs, used_vars, \ tok_list, first_pos, self.end_pos) @@ -1265,7 +1267,7 @@ class PyFuzzyParser(object): """ Generate the next tokenize pattern. """ type, tok, self._tokenize_start_pos, self._tokenize_end_pos, \ self.parserline = next(self.gen) - if self.start_pos[0] == self.user_position[0]: + if self.user_position and self.start_pos[0] == self.user_position[0]: debug.dbg('user scope found [%s] =%s' % \ (self.parserline.replace('\n', ''), repr(self.scope))) self.user_scope = self.scope @@ -1344,7 +1346,6 @@ class PyFuzzyParser(object): i = Import(first_pos, self.end_pos, m, alias, defunct=defunct) self.check_user_stmt(i) - self.user_stmt = i self.scope.add_import(i) debug.dbg("new import: %s" % (i), self.current) if not imports: diff --git a/test/completion/imports.py b/test/completion/imports.py index 344e38bf..013ae6f5 100644 --- a/test/completion/imports.py +++ b/test/completion/imports.py @@ -64,7 +64,13 @@ import sqlite import classes #? ['timedelta'] -from datetime import timedelta +from datetime import timedel + +# should not be possible, because names can only be looked up 1 level deep. +#? [] +from datetime.timedelta import resolution +#? [] +from datetime.timedelta import #? ['Cursor'] from sqlite3 import Cursor