aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/test/test_symtable.py
diff options
context:
space:
mode:
authorBénédikt Tran <10796600+picnixz@users.noreply.github.com>2024-07-17 15:27:35 +0200
committerGitHub <noreply@github.com>2024-07-17 06:27:35 -0700
commit6682d916780c1cb305e679a057ee6992b114118e (patch)
treec48a8d6a4e7bbe9681d9c28e9db3fd5d84290cb7 /Lib/test/test_symtable.py
parentcffad5c6ef9371b26e32556296cea2bfe8358b1a (diff)
downloadcpython-6682d916780c1cb305e679a057ee6992b114118e.tar.gz
cpython-6682d916780c1cb305e679a057ee6992b114118e.zip
gh-119698: fix a special case in `symtable.Class.get_methods` (#121802)
Diffstat (limited to 'Lib/test/test_symtable.py')
-rw-r--r--Lib/test/test_symtable.py56
1 files changed, 55 insertions, 1 deletions
diff --git a/Lib/test/test_symtable.py b/Lib/test/test_symtable.py
index 0cc19265593..82f667d3687 100644
--- a/Lib/test/test_symtable.py
+++ b/Lib/test/test_symtable.py
@@ -1,6 +1,8 @@
"""
Test the API of the symtable module.
"""
+
+import textwrap
import symtable
import unittest
@@ -356,7 +358,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")
@@ -377,6 +379,58 @@ 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 [])',
+ 'type x[genexpr = (x for x in [])] = (x for x in [])',
+ 'type x[genexpr = (x async for x in [])] = (x async for x in [])',
+ 'genexpr = (x for x in [])',
+ 'genexpr = (x async for x in [])',
+ 'type genexpr[genexpr = (x for x in [])] = (x for x in [])',
+ 'type genexpr[genexpr = (x async for x in [])] = (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.