From 2500112f6c8d9dfaffe454d0ee95547f9f03789f Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Tue, 3 Jul 2018 23:59:30 +0200 Subject: [PATCH] Don't follow builtin imports anymore by default when follow_imports is on (goto) --- CHANGELOG.rst | 2 ++ jedi/api/__init__.py | 19 ++++++++++++++++--- test/test_api/test_api.py | 8 ++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8b46ca3a..8069a1c6 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -7,6 +7,8 @@ Changelog +++++++++++++++++++ - Added ``include_builtins`` as a parameter to usages. +- ``goto_assignments`` has a new ``follow_builtin_imports`` parameter that + changes the previous behavior slightly. 0.12.1 (2018-06-30) +++++++++++++++++++ diff --git a/jedi/api/__init__.py b/jedi/api/__init__.py index 47dd19a6..3b8e54b0 100644 --- a/jedi/api/__init__.py +++ b/jedi/api/__init__.py @@ -204,20 +204,33 @@ class Script(object): # the API. return helpers.sorted_definitions(set(defs)) - def goto_assignments(self, follow_imports=False): + def goto_assignments(self, follow_imports=False, follow_builtin_imports=False): """ Return the first definition found, while optionally following imports. Multiple objects may be returned, because Python itself is a dynamic language, which means depending on an option you can have two different versions of a function. + :param follow_imports: The goto call will follow imports. + :param follow_builtin_imports: If follow_imports is True will decide if + it follow builtin imports. :rtype: list of :class:`classes.Definition` """ def filter_follow_imports(names, check): for name in names: if check(name): - for result in filter_follow_imports(name.goto(), check): - yield result + new_names = list(filter_follow_imports(name.goto(), check)) + found_builtin = False + if follow_builtin_imports: + for new_name in new_names: + if new_name.start_pos is None: + found_builtin = True + + if found_builtin and not isinstance(name, imports.SubModuleName): + yield name + else: + for new_name in new_names: + yield new_name else: yield name diff --git a/test/test_api/test_api.py b/test/test_api/test_api.py index 47c87833..3cbac36a 100644 --- a/test/test_api/test_api.py +++ b/test/test_api/test_api.py @@ -285,3 +285,11 @@ def test_backslash_continuation_and_bracket(Script): column = lines[-1].index('(') def_, = Script(code, line=len(lines), column=column).goto_definitions() assert def_.name == 'int' + + +def test_goto_follow_builtin_imports(Script): + s = Script('import sys; sys') + d, = s.goto_assignments(follow_imports=True) + assert d.in_builtin_module() is True + d, = s.goto_assignments(follow_imports=True, follow_builtin_imports=True) + assert d.in_builtin_module() is False