diff --git a/AUTHORS.txt b/AUTHORS.txt index fb5e3a50..732eb7b6 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -72,6 +72,7 @@ Code Contributors - Charan Rathore (@charan-rathore) - Abdullah Ahmed (@abdull-ah-med) - spicysharkco (@spicysharkco) +- Don Yin (@Don-Yin) And a few more "anonymous" contributors. diff --git a/jedi/inference/context.py b/jedi/inference/context.py index 080fc8fd..538e0f97 100644 --- a/jedi/inference/context.py +++ b/jedi/inference/context.py @@ -395,6 +395,12 @@ class CompForContext(TreeContextMixin, AbstractContext): def py__name__(self): return '' + def get_qualified_names(self) -> Any: + names = self.parent_context.get_qualified_names() + if names is None: + return None + return names + ('',) + def __repr__(self): return '%s(%s)' % (self.__class__.__name__, self.tree_node) diff --git a/test/test_api/test_full_name.py b/test/test_api/test_full_name.py index 2d8f996f..02ab9136 100644 --- a/test/test_api/test_full_name.py +++ b/test/test_api/test_full_name.py @@ -128,3 +128,45 @@ def test_variable_in_func(Script): x = names[-1] assert x.name == 'x' assert x.full_name == '__main__.f.x' + + +def test_comprehension_full_name_issue_1944(Script): + source = textwrap.dedent('''\ + def pig_latin(text): + translated_words = [translate(word) for word in words] + ''') + names = Script(source).get_names(all_scopes=True, references=True) + word_names = [name for name in names if name.name == 'word'] + assert len(word_names) == 2 + assert {name.full_name for name in word_names} == { + '__main__.pig_latin..word' + } + + +@pytest.mark.parametrize('expression', [ + '[word for word in words]', + '{word for word in words}', + '{word: word for word in words}', + '(word for word in words)', + '[word for row in rows for word in row]', + '[word for row in rows if row for word in row]', +]) +def test_comprehension_full_name(Script, expression): + source = 'def f():\n return ' + expression + names = Script(source).get_names(all_scopes=True, references=True) + word_names = [name for name in names if name.name == 'word'] + assert len(word_names) >= 2 + assert {name.full_name for name in word_names} == {'__main__.f..word'} + + +@pytest.mark.parametrize('source, expected', [ + ('[word for word in words]', '__main__..word'), + ('def f():\n return [[word for word in words] for words in rows]', + '__main__.f...word'), + ('def outer():\n def f():\n return [word for word in words]', None), +]) +def test_comprehension_parent_full_name(Script, source, expected): + names = Script(source).get_names(all_scopes=True, references=True) + word_names = [name for name in names if name.name == 'word'] + assert len(word_names) == 2 + assert {name.full_name for name in word_names} == {expected}