Skip to content

Commit a51bf70

Browse files
authored
gh-143504: Expose CELL status of a symbol in symtable (#143549)
1 parent 979d92f commit a51bf70

File tree

5 files changed

+37
-0
lines changed

5 files changed

+37
-0
lines changed

Doc/library/symtable.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,12 @@ Examining Symbol Tables
180180
Return a tuple containing names of :term:`free (closure) variables <closure variable>`
181181
in this function.
182182

183+
.. method:: get_cells()
184+
185+
Return a tuple containing names of :term:`cell variables <closure variable>` in this table.
186+
187+
.. versionadded:: next
188+
183189

184190
.. class:: Class
185191

@@ -291,6 +297,12 @@ Examining Symbol Tables
291297
Return ``True`` if the symbol is referenced in its block, but not assigned
292298
to.
293299

300+
.. method:: is_cell()
301+
302+
Return ``True`` if the symbol is referenced but not assigned in a nested block.
303+
304+
.. versionadded:: next
305+
294306
.. method:: is_free_class()
295307

296308
Return *True* if a class-scoped symbol is free from

Doc/whatsnew/3.15.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,13 @@ ssl
737737
(Contributed by Ron Frederick in :gh:`138252`.)
738738

739739

740+
symtable
741+
--------
742+
743+
* Add :meth:`symtable.Function.get_cells` and :meth:`symtable.Symbol.is_cell` methods.
744+
(Contributed by Yashp002 in :gh:`143504`.)
745+
746+
740747
sys
741748
---
742749

Lib/symtable.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ class Function(SymbolTable):
184184
__frees = None
185185
__globals = None
186186
__nonlocals = None
187+
__cells = None
187188

188189
def __idents_matching(self, test_func):
189190
return tuple(ident for ident in self.get_identifiers()
@@ -229,6 +230,14 @@ def get_frees(self):
229230
self.__frees = self.__idents_matching(is_free)
230231
return self.__frees
231232

233+
def get_cells(self):
234+
"""Return a tuple of cell variables in the function.
235+
"""
236+
if self.__cells is None:
237+
is_cell = lambda x: _get_scope(x) == CELL
238+
self.__cells = self.__idents_matching(is_cell)
239+
return self.__cells
240+
232241

233242
class Class(SymbolTable):
234243

@@ -342,6 +351,10 @@ def is_free(self):
342351
"""
343352
return bool(self.__scope == FREE)
344353

354+
def is_cell(self):
355+
"""Return *True* if the symbol is a cell variable."""
356+
return bool(self.__scope == CELL)
357+
345358
def is_free_class(self):
346359
"""Return *True* if a class-scoped symbol is free from
347360
the perspective of a method."""

Lib/test/test_symtable.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ def test_function_info(self):
255255
self.assertEqual(sorted(func.get_locals()), expected)
256256
self.assertEqual(sorted(func.get_globals()), ["bar", "glob", "some_assigned_global_var"])
257257
self.assertEqual(self.internal.get_frees(), ("x",))
258+
self.assertEqual(self.spam.get_cells(), ("some_var", "x",))
258259

259260
def test_globals(self):
260261
self.assertTrue(self.spam.lookup("glob").is_global())
@@ -284,6 +285,9 @@ def test_local(self):
284285
def test_free(self):
285286
self.assertTrue(self.internal.lookup("x").is_free())
286287

288+
def test_cells(self):
289+
self.assertTrue(self.spam.lookup("x").is_cell())
290+
287291
def test_referenced(self):
288292
self.assertTrue(self.internal.lookup("x").is_referenced())
289293
self.assertTrue(self.spam.lookup("internal").is_referenced())
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add :meth:`symtable.Function.get_cells` and :meth:`symtable.Symbol.is_cell` methods.

0 commit comments

Comments
 (0)