summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2023-09-29 06:10:22 (GMT)
committerGitHub <noreply@github.com>2023-09-29 06:10:22 (GMT)
commit69a9f471253ca58357c39a475872da7229c7b81e (patch)
tree86c09a1a8f56095a3e8b415c69c2e223df18262b
parent335e3d59e04d53c11574b37f320b22061bdcce41 (diff)
downloadcpython-69a9f471253ca58357c39a475872da7229c7b81e.zip
cpython-69a9f471253ca58357c39a475872da7229c7b81e.tar.gz
cpython-69a9f471253ca58357c39a475872da7229c7b81e.tar.bz2
[3.12] gh-110045: Update symtable module for PEP 695 (GH-110066) (#110070)
gh-110045: Update symtable module for PEP 695 (GH-110066) (cherry picked from commit 7dc2c5093ef027aab57bca953ac2d6477a4a440b) Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
-rw-r--r--Doc/library/symtable.rst12
-rw-r--r--Lib/symtable.py15
-rw-r--r--Lib/test/test_symtable.py31
-rw-r--r--Misc/NEWS.d/next/Library/2023-09-28-18-08-02.gh-issue-110045.0YIGKv.rst2
-rw-r--r--Modules/symtablemodule.c8
5 files changed, 63 insertions, 5 deletions
diff --git a/Doc/library/symtable.rst b/Doc/library/symtable.rst
index 65ff5bf..85eae5f 100644
--- a/Doc/library/symtable.rst
+++ b/Doc/library/symtable.rst
@@ -38,7 +38,13 @@ Examining Symbol Tables
.. method:: get_type()
Return the type of the symbol table. Possible values are ``'class'``,
- ``'module'``, and ``'function'``.
+ ``'module'``, ``'function'``, ``'annotation'``, ``'TypeVar bound'``,
+ ``'type alias'``, and ``'type parameter'``. The latter four refer to
+ different flavors of :ref:`annotation scopes <annotation-scopes>`.
+
+ .. versionchanged:: 3.12
+ Added ``'annotation'``, ``'TypeVar bound'``, ``'type alias'``,
+ and ``'type parameter'`` as possible return values.
.. method:: get_id()
@@ -49,6 +55,10 @@ Examining Symbol Tables
Return the table's name. This is the name of the class if the table is
for a class, the name of the function if the table is for a function, or
``'top'`` if the table is global (:meth:`get_type` returns ``'module'``).
+ For type parameter scopes (which are used for generic classes, functions,
+ and type aliases), it is the name of the underlying class, function, or
+ type alias. For type alias scopes, it is the name of the type alias.
+ For :class:`~typing.TypeVar` bound scopes, it is the name of the ``TypeVar``.
.. method:: get_lineno()
diff --git a/Lib/symtable.py b/Lib/symtable.py
index 5dd71ff..4b0bc6f 100644
--- a/Lib/symtable.py
+++ b/Lib/symtable.py
@@ -62,8 +62,8 @@ class SymbolTable:
def get_type(self):
"""Return the type of the symbol table.
- The values returned are 'class', 'module' and
- 'function'.
+ The values returned are 'class', 'module', 'function',
+ 'annotation', 'TypeVar bound', 'type alias', and 'type parameter'.
"""
if self._table.type == _symtable.TYPE_MODULE:
return "module"
@@ -71,8 +71,15 @@ class SymbolTable:
return "function"
if self._table.type == _symtable.TYPE_CLASS:
return "class"
- assert self._table.type in (1, 2, 3), \
- "unexpected type: {0}".format(self._table.type)
+ if self._table.type == _symtable.TYPE_ANNOTATION:
+ return "annotation"
+ if self._table.type == _symtable.TYPE_TYPE_VAR_BOUND:
+ return "TypeVar bound"
+ if self._table.type == _symtable.TYPE_TYPE_ALIAS:
+ return "type alias"
+ if self._table.type == _symtable.TYPE_TYPE_PARAM:
+ return "type parameter"
+ assert False, f"unexpected type: {self._table.type}"
def get_id(self):
"""Return an identifier for the table.
diff --git a/Lib/test/test_symtable.py b/Lib/test/test_symtable.py
index 25714ae..61fda76 100644
--- a/Lib/test/test_symtable.py
+++ b/Lib/test/test_symtable.py
@@ -40,6 +40,15 @@ def foo():
def namespace_test(): pass
def namespace_test(): pass
+
+type Alias = int
+type GenericAlias[T] = list[T]
+
+def generic_spam[T](a):
+ pass
+
+class GenericMine[T: int]:
+ pass
"""
@@ -59,6 +68,14 @@ class SymtableTest(unittest.TestCase):
internal = find_block(spam, "internal")
other_internal = find_block(spam, "other_internal")
foo = find_block(top, "foo")
+ Alias = find_block(top, "Alias")
+ GenericAlias = find_block(top, "GenericAlias")
+ GenericAlias_inner = find_block(GenericAlias, "GenericAlias")
+ generic_spam = find_block(top, "generic_spam")
+ generic_spam_inner = find_block(generic_spam, "generic_spam")
+ GenericMine = find_block(top, "GenericMine")
+ GenericMine_inner = find_block(GenericMine, "GenericMine")
+ T = find_block(GenericMine, "T")
def test_type(self):
self.assertEqual(self.top.get_type(), "module")
@@ -66,6 +83,15 @@ class SymtableTest(unittest.TestCase):
self.assertEqual(self.a_method.get_type(), "function")
self.assertEqual(self.spam.get_type(), "function")
self.assertEqual(self.internal.get_type(), "function")
+ self.assertEqual(self.foo.get_type(), "function")
+ self.assertEqual(self.Alias.get_type(), "type alias")
+ self.assertEqual(self.GenericAlias.get_type(), "type parameter")
+ self.assertEqual(self.GenericAlias_inner.get_type(), "type alias")
+ self.assertEqual(self.generic_spam.get_type(), "type parameter")
+ self.assertEqual(self.generic_spam_inner.get_type(), "function")
+ self.assertEqual(self.GenericMine.get_type(), "type parameter")
+ self.assertEqual(self.GenericMine_inner.get_type(), "class")
+ self.assertEqual(self.T.get_type(), "TypeVar bound")
def test_id(self):
self.assertGreater(self.top.get_id(), 0)
@@ -73,6 +99,11 @@ class SymtableTest(unittest.TestCase):
self.assertGreater(self.a_method.get_id(), 0)
self.assertGreater(self.spam.get_id(), 0)
self.assertGreater(self.internal.get_id(), 0)
+ self.assertGreater(self.foo.get_id(), 0)
+ self.assertGreater(self.Alias.get_id(), 0)
+ self.assertGreater(self.GenericAlias.get_id(), 0)
+ self.assertGreater(self.generic_spam.get_id(), 0)
+ self.assertGreater(self.GenericMine.get_id(), 0)
def test_optimized(self):
self.assertFalse(self.top.is_optimized())
diff --git a/Misc/NEWS.d/next/Library/2023-09-28-18-08-02.gh-issue-110045.0YIGKv.rst b/Misc/NEWS.d/next/Library/2023-09-28-18-08-02.gh-issue-110045.0YIGKv.rst
new file mode 100644
index 0000000..44a6df1
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-09-28-18-08-02.gh-issue-110045.0YIGKv.rst
@@ -0,0 +1,2 @@
+Update the :mod:`symtable` module to support the new scopes introduced by
+:pep:`695`.
diff --git a/Modules/symtablemodule.c b/Modules/symtablemodule.c
index 1cc319c..1f09c23 100644
--- a/Modules/symtablemodule.c
+++ b/Modules/symtablemodule.c
@@ -85,6 +85,14 @@ symtable_init_constants(PyObject *m)
if (PyModule_AddIntConstant(m, "TYPE_CLASS", ClassBlock) < 0) return -1;
if (PyModule_AddIntConstant(m, "TYPE_MODULE", ModuleBlock) < 0)
return -1;
+ if (PyModule_AddIntConstant(m, "TYPE_ANNOTATION", AnnotationBlock) < 0)
+ return -1;
+ if (PyModule_AddIntConstant(m, "TYPE_TYPE_VAR_BOUND", TypeVarBoundBlock) < 0)
+ return -1;
+ if (PyModule_AddIntConstant(m, "TYPE_TYPE_ALIAS", TypeAliasBlock) < 0)
+ return -1;
+ if (PyModule_AddIntConstant(m, "TYPE_TYPE_PARAM", TypeParamBlock) < 0)
+ return -1;
if (PyModule_AddIntMacro(m, LOCAL) < 0) return -1;
if (PyModule_AddIntMacro(m, GLOBAL_EXPLICIT) < 0) return -1;