mirror of https://github.com/python/cpython
gh-110045: Update symtable module for PEP 695 (#110066)
This commit is contained in:
parent
2e37a38bcb
commit
7dc2c5093e
|
@ -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()
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
Update the :mod:`symtable` module to support the new scopes introduced by
|
||||
:pep:`695`.
|
|
@ -86,6 +86,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;
|
||||
|
|
Loading…
Reference in New Issue