1
0
forked from VimPlug/jedi

Merge branch 'master' into typeshed

This commit is contained in:
Dave Halter
2019-04-09 22:58:30 +02:00
4 changed files with 53 additions and 4 deletions

View File

@@ -235,7 +235,12 @@ def _try_get_same_env():
def get_cached_default_environment(): def get_cached_default_environment():
var = os.environ.get('VIRTUAL_ENV') var = os.environ.get('VIRTUAL_ENV')
environment = _get_cached_default_environment() environment = _get_cached_default_environment()
if var and var != environment.path:
# Under macOS in some cases - notably when using Pipenv - the
# sys.prefix of the virtualenv is /path/to/env/bin/.. instead of
# /path/to/env so we need to fully resolve the paths in order to
# compare them.
if var and os.path.realpath(var) != os.path.realpath(environment.path):
_get_cached_default_environment.clear_cache() _get_cached_default_environment.clear_cache()
return _get_cached_default_environment() return _get_cached_default_environment()
return environment return environment

View File

@@ -8,7 +8,7 @@ from contextlib import contextmanager
from parso.python import tree from parso.python import tree
from jedi._compatibility import unicode from jedi._compatibility import unicode
from jedi.parser_utils import get_parent_scope from jedi.parser_utils import get_parent_scope, is_name_of_func_or_class_def
def is_stdlib_path(path): def is_stdlib_path(path):
@@ -166,13 +166,33 @@ def get_module_names(module, all_scopes):
Returns a dictionary with name parts as keys and their call paths as Returns a dictionary with name parts as keys and their call paths as
values. values.
""" """
names = chain.from_iterable(module.get_used_names().values()) names = list(chain.from_iterable(module.get_used_names().values()))
if not all_scopes: if not all_scopes:
# We have to filter all the names that don't have the module as a # We have to filter all the names that don't have the module as a
# parent_scope. There's None as a parent, because nodes in the module # parent_scope. There's None as a parent, because nodes in the module
# node have the parent module and not suite as all the others. # node have the parent module and not suite as all the others.
# Therefore it's important to catch that case. # Therefore it's important to catch that case.
names = [n for n in names if get_parent_scope(n) == module]
def is_module_scope_name(name):
parent_scope = get_parent_scope(name)
if is_name_of_func_or_class_def(name, parent_scope):
# XXX: In syntax tree function- and class-name nodes are immediate children of
# their respective class-definition or function-definition nodes. Technically,
# get_parent_scope(...) for them should return the parent of the definition node,
# because
#
# def foo(...): pass
#
# is equivalent to
#
# foo = lambda(...): None
#
# but that would be a big change that could break type inference, whereas for now
# this discrepancy looks like only a problem for "get_module_names".
parent_scope = parent_scope.parent
return parent_scope in (module, None)
names = [n for n in names if is_module_scope_name(n)]
return names return names

View File

@@ -242,6 +242,14 @@ def is_scope(node):
return node.type in ('file_input', 'classdef', 'funcdef', 'lambdef', 'comp_for') return node.type in ('file_input', 'classdef', 'funcdef', 'lambdef', 'comp_for')
def is_name_of_func_or_class_def(name_node, func_or_class_def_node):
"""Return True if name_node is the name of the func_or_class_def_node."""
return (
name_node.parent is func_or_class_def_node and
name_node.type == 'name' and
func_or_class_def_node.type in ('classdef', 'funcdef'))
def get_parent_scope(node, include_flows=False): def get_parent_scope(node, include_flows=False):
""" """
Returns the underlying scope. Returns the underlying scope.

View File

@@ -79,6 +79,22 @@ class TestDefinedNames(TestCase):
self.assert_definition_names(subsubdefs, ['L3', 'f']) self.assert_definition_names(subsubdefs, ['L3', 'f'])
self.assert_definition_names(subsubdefs[0].defined_names(), ['f']) self.assert_definition_names(subsubdefs[0].defined_names(), ['f'])
def test_class_fields_with_all_scopes_false(self):
definitions = self.check_defined_names("""
from module import f
g = f(f)
class C:
h = g
def foo(x=a):
bar = x
return bar
""", ['f', 'g', 'C', 'foo'])
C_subdefs = definitions[-2].defined_names()
foo_subdefs = definitions[-1].defined_names()
self.assert_definition_names(C_subdefs, ['h'])
self.assert_definition_names(foo_subdefs, ['x', 'bar'])
def test_follow_imports(environment): def test_follow_imports(environment):
# github issue #344 # github issue #344