[3.12] gh-119698: fix a special case in symtable.Class.get_methods (GH-121802) (#121910)

(cherry picked from commit 6682d91678)

Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
This commit is contained in:
Miss Islington (bot) 2024-07-18 00:32:29 +02:00 committed by GitHub
parent a6516de08b
commit 3279a4fbff
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 64 additions and 2 deletions

View file

@ -1,6 +1,8 @@
"""
Test the API of the symtable module.
"""
import textwrap
import symtable
import unittest
@ -350,7 +352,7 @@ class SymtableTest(unittest.TestCase):
self.assertEqual(self.spam.lookup("x").get_name(), "x")
self.assertEqual(self.Mine.get_name(), "Mine")
def test_class_info(self):
def test_class_get_methods(self):
self.assertEqual(self.Mine.get_methods(), ('a_method',))
top = symtable.symtable(TEST_COMPLEX_CLASS_CODE, "?", "exec")
@ -371,6 +373,54 @@ class SymtableTest(unittest.TestCase):
'glob_assigned_async_meth', 'glob_assigned_async_meth_pep_695',
))
# Test generator expressions that are of type TYPE_FUNCTION
# but will not be reported by get_methods() since they are
# not functions per se.
#
# Other kind of comprehensions such as list, set or dict
# expressions do not have the TYPE_FUNCTION type.
def check_body(body, expected_methods):
indented = textwrap.indent(body, ' ' * 4)
top = symtable.symtable(f"class A:\n{indented}", "?", "exec")
this = find_block(top, "A")
self.assertEqual(this.get_methods(), expected_methods)
# statements with 'genexpr' inside it
GENEXPRS = (
'x = (x for x in [])',
'x = (x async for x in [])',
'genexpr = (x for x in [])',
'genexpr = (x async for x in [])',
)
for gen in GENEXPRS:
# test generator expression
with self.subTest(gen=gen):
check_body(gen, ())
# test generator expression + variable named 'genexpr'
with self.subTest(gen=gen, isvar=True):
check_body('\n'.join((gen, 'genexpr = 1')), ())
check_body('\n'.join(('genexpr = 1', gen)), ())
for paramlist in ('()', '(x)', '(x, y)', '(z: T)'):
for func in (
f'def genexpr{paramlist}:pass',
f'async def genexpr{paramlist}:pass',
f'def genexpr[T]{paramlist}:pass',
f'async def genexpr[T]{paramlist}:pass',
):
with self.subTest(func=func):
# test function named 'genexpr'
check_body(func, ('genexpr',))
for gen in GENEXPRS:
with self.subTest(gen=gen, func=func):
# test generator expression + function named 'genexpr'
check_body('\n'.join((gen, func)), ('genexpr',))
check_body('\n'.join((func, gen)), ('genexpr',))
def test_filename_correct(self):
### Bug tickler: SyntaxError file name correct whether error raised
### while parsing or building symbol table.