Merge pull request #2124 from Don-Yin/fix-comprehension-full-name

Preserve comprehension scopes in full_name
This commit is contained in:
Dave Halter authored and GitHub committed 2026-10-25 10:21:19 +00:00
commit c7ceec72f1
3 files changed
+49

No files matched your search

+1
View File
@@ -72,6 +72,7 @@ Code Contributors
- Charan Rathore (@charan-rathore)
- Abdullah Ahmed (@abdull-ah-med)
- spicysharkco (@spicysharkco)
- Don Yin (@Don-Yin) <Don_Yin@outlook.com>
And a few more "anonymous" contributors.
+6
View File
@@ -395,6 +395,12 @@ class CompForContext(TreeContextMixin, AbstractContext):
def py__name__(self):
return '<comprehension context>'
def get_qualified_names(self) -> Any:
names = self.parent_context.get_qualified_names()
if names is None:
return None
return names + ('<comprehension>',)
def __repr__(self):
return '%s(%s)' % (self.__class__.__name__, self.tree_node)
+42
View File
@@ -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.<comprehension>.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.<comprehension>.word'}
@pytest.mark.parametrize('source, expected', [
('[word for word in words]', '__main__.<comprehension>.word'),
('def f():\n return [[word for word in words] for words in rows]',
'__main__.f.<comprehension>.<comprehension>.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}