]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-143504: Expose CELL status of a symbol in symtable (#143549)
authorYashraj <yashrajpala8@gmail.com>
Sun, 25 Jan 2026 15:21:27 +0000 (20:51 +0530)
committerGitHub <noreply@github.com>
Sun, 25 Jan 2026 15:21:27 +0000 (15:21 +0000)
Doc/library/symtable.rst
Doc/whatsnew/3.15.rst
Lib/symtable.py
Lib/test/test_symtable.py
Misc/NEWS.d/next/Library/2026-01-24-13-49-05.gh-issue-143594.nilGlg.rst [new file with mode: 0644]

index f5e6f9f8acfdb8f1c3ff18b430a0a13a4c0f7887..0b722d7d4e35cf4c3a7ffb8b7c5df50169f5ce17 100644 (file)
@@ -180,6 +180,12 @@ Examining Symbol Tables
       Return a tuple containing names of :term:`free (closure) variables <closure variable>`
       in this function.
 
+   .. method:: get_cells()
+
+      Return a tuple containing names of :term:`cell variables <closure variable>` in this table.
+
+      .. versionadded:: next
+
 
 .. class:: Class
 
@@ -291,6 +297,12 @@ Examining Symbol Tables
       Return ``True`` if the symbol is referenced in its block, but not assigned
       to.
 
+   .. method:: is_cell()
+
+      Return ``True`` if the symbol is referenced but not assigned in a nested block.
+
+      .. versionadded:: next
+
    .. method:: is_free_class()
 
       Return *True* if a class-scoped symbol is free from
index 8c92ac8e0319dad5b7485f79536319145ff57609..8c3223d9a784a14783308d560f58da7f4bcef3a1 100644 (file)
@@ -737,6 +737,13 @@ ssl
    (Contributed by Ron Frederick in :gh:`138252`.)
 
 
+symtable
+--------
+
+* Add :meth:`symtable.Function.get_cells` and :meth:`symtable.Symbol.is_cell` methods.
+  (Contributed by Yashp002 in :gh:`143504`.)
+
+
 sys
 ---
 
index 4c832e68f94cbdaf455af743c9d1a132da930d2b..45610fd5612995b177ccde18a41b3a604faf75e5 100644 (file)
@@ -184,6 +184,7 @@ class Function(SymbolTable):
     __frees = None
     __globals = None
     __nonlocals = None
+    __cells = None
 
     def __idents_matching(self, test_func):
         return tuple(ident for ident in self.get_identifiers()
@@ -229,6 +230,14 @@ class Function(SymbolTable):
             self.__frees = self.__idents_matching(is_free)
         return self.__frees
 
+    def get_cells(self):
+        """Return a tuple of cell variables in the function.
+        """
+        if self.__cells is None:
+            is_cell = lambda x: _get_scope(x) == CELL
+            self.__cells = self.__idents_matching(is_cell)
+        return self.__cells
+
 
 class Class(SymbolTable):
 
@@ -342,6 +351,10 @@ class Symbol:
         """
         return bool(self.__scope == FREE)
 
+    def is_cell(self):
+        """Return *True* if the symbol is a cell variable."""
+        return bool(self.__scope == CELL)
+
     def is_free_class(self):
         """Return *True* if a class-scoped symbol is free from
         the perspective of a method."""
index 094ab8f573e7bae93c2d389d4cad409a6bb107e5..c748243110df9ff340232df7bb28247f7edcb9d6 100644 (file)
@@ -255,6 +255,7 @@ class SymtableTest(unittest.TestCase):
         self.assertEqual(sorted(func.get_locals()), expected)
         self.assertEqual(sorted(func.get_globals()), ["bar", "glob", "some_assigned_global_var"])
         self.assertEqual(self.internal.get_frees(), ("x",))
+        self.assertEqual(self.spam.get_cells(), ("some_var", "x",))
 
     def test_globals(self):
         self.assertTrue(self.spam.lookup("glob").is_global())
@@ -284,6 +285,9 @@ class SymtableTest(unittest.TestCase):
     def test_free(self):
         self.assertTrue(self.internal.lookup("x").is_free())
 
+    def test_cells(self):
+        self.assertTrue(self.spam.lookup("x").is_cell())
+
     def test_referenced(self):
         self.assertTrue(self.internal.lookup("x").is_referenced())
         self.assertTrue(self.spam.lookup("internal").is_referenced())
diff --git a/Misc/NEWS.d/next/Library/2026-01-24-13-49-05.gh-issue-143594.nilGlg.rst b/Misc/NEWS.d/next/Library/2026-01-24-13-49-05.gh-issue-143594.nilGlg.rst
new file mode 100644 (file)
index 0000000..e0c2c28
--- /dev/null
@@ -0,0 +1 @@
+Add :meth:`symtable.Function.get_cells` and :meth:`symtable.Symbol.is_cell` methods.