:mod:`!symtable` --- Access to the compiler's symbol tables
===========================================================

.. module:: symtable
   :synopsis: Interface to the compiler's internal symbol tables.

**Source code:** :source:`Lib/symtable.py`

--------------

.. moduleauthor:: Jeremy Hylton <jeremy@alum.mit.edu>
.. sectionauthor:: Benjamin Peterson <benjamin@python.org>


Symbol tables are generated by the compiler from AST just before bytecode is
generated.  The symbol table is responsible for calculating the scope of every
identifier in the code.  :mod:`symtable` provides an interface to examine these
tables.


Generating Symbol Tables
------------------------

.. function:: symtable(code, filename, compile_type, *, module=None)

   Return the toplevel :class:`SymbolTable` for the Python source *code*.
   *filename* is the name of the file containing the code.  *compile_type* is
   like the *mode* argument to :func:`compile`.
   The optional argument *module* specifies the module name.
   It is needed to unambiguous :ref:`filter <warning-filter>` syntax warnings
   by module name.

   .. versionadded:: 3.15
      Added the *module* parameter.


Examining Symbol Tables
-----------------------

.. class:: SymbolTableType

   An enumeration indicating the type of a :class:`SymbolTable` object.

   .. attribute:: MODULE
      :value: "module"

      Used for the symbol table of a module.

   .. attribute:: FUNCTION
      :value: "function"

      Used for the symbol table of a function.

   .. attribute:: CLASS
      :value: "class"

      Used for the symbol table of a class.

   The following members refer to different flavors of
   :ref:`annotation scopes <annotation-scopes>`.

   .. attribute:: ANNOTATION
      :value: "annotation"

      Used for annotations if ``from __future__ import annotations`` is active.

   .. attribute:: TYPE_ALIAS
      :value: "type alias"

      Used for the symbol table of :keyword:`type` constructions.

   .. attribute:: TYPE_PARAMETERS
      :value: "type parameters"

      Used for the symbol table of :ref:`generic functions <generic-functions>`
      or :ref:`generic classes <generic-classes>`.

   .. attribute:: TYPE_VARIABLE
      :value: "type variable"

      Used for the symbol table of the bound, the constraint tuple or the
      default value of a single type variable in the formal sense, i.e.,
      a TypeVar, a TypeVarTuple or a ParamSpec object (the latter two do
      not support a bound or a constraint tuple).

   .. versionadded:: 3.13

.. class:: SymbolTable

   A namespace table for a block.  The constructor is not public.

   .. method:: get_type()

      Return the type of the symbol table.  Possible values are members
      of the :class:`SymbolTableType` enumeration.

      .. versionchanged:: 3.12
         Added ``'annotation'``,  ``'TypeVar bound'``, ``'type alias'``,
         and ``'type parameter'`` as possible return values.

      .. versionchanged:: 3.13
         Return values are members of the :class:`SymbolTableType` enumeration.

         The exact values of the returned string may change in the future,
         and thus, it is recommended to use :class:`SymbolTableType` members
         instead of hard-coded strings.

   .. method:: get_id()

      Return the table's identifier.

   .. method:: get_name()

      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()

      Return the number of the first line in the block this table represents.

   .. method:: is_optimized()

      Return ``True`` if the locals in this table can be optimized.

   .. method:: is_nested()

      Return ``True`` if the block is a nested class or function.

   .. method:: has_children()

      Return ``True`` if the block has nested namespaces within it.  These can
      be obtained with :meth:`get_children`.

   .. method:: get_identifiers()

      Return a view object containing the names of symbols in the table.
      See the :ref:`documentation of view objects <dict-views>`.

   .. method:: lookup(name)

      Lookup *name* in the table and return a :class:`Symbol` instance.

   .. method:: get_symbols()

      Return a list of :class:`Symbol` instances for names in the table.

   .. method:: get_children()

      Return a list of the nested symbol tables.


.. class:: Function

   A namespace for a function or method.  This class inherits from
   :class:`SymbolTable`.

   .. method:: get_parameters()

      Return a tuple containing names of parameters to this function.

   .. method:: get_locals()

      Return a tuple containing names of locals in this function.

   .. method:: get_globals()

      Return a tuple containing names of globals in this function.

   .. method:: get_nonlocals()

      Return a tuple containing names of explicitly declared nonlocals in this function.

   .. method:: get_frees()

      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

   A namespace of a class.  This class inherits from :class:`SymbolTable`.

   .. method:: get_methods()

      Return a tuple containing the names of method-like functions declared
      in the class.

      Here, the term 'method' designates *any* function defined in the class
      body via :keyword:`def` or :keyword:`async def`.

      Functions defined in a deeper scope (e.g., in an inner class) are not
      picked up by :meth:`get_methods`.

      For example:

      .. testsetup:: symtable.Class.get_methods

         import warnings
         context = warnings.catch_warnings()
         context.__enter__()
         warnings.simplefilter("ignore", category=DeprecationWarning)

      .. testcleanup:: symtable.Class.get_methods

         context.__exit__()

      .. doctest:: symtable.Class.get_methods

         >>> import symtable
         >>> st = symtable.symtable('''
         ... def outer(): pass
         ...
         ... class A:
         ...    def f():
         ...        def w(): pass
         ...
         ...    def g(self): pass
         ...
         ...    @classmethod
         ...    async def h(cls): pass
         ...
         ...    global outer
         ...    def outer(self): pass
         ... ''', 'test', 'exec')
         >>> class_A = st.get_children()[2]
         >>> class_A.get_methods()
         ('f', 'g', 'h')

      Although ``A().f()`` raises :exc:`TypeError` at runtime, ``A.f`` is still
      considered as a method-like function.

      .. deprecated-removed:: 3.14 3.16


.. class:: Symbol

   An entry in a :class:`SymbolTable` corresponding to an identifier in the
   source.  The constructor is not public.

   .. method:: get_name()

      Return the symbol's name.

   .. method:: is_referenced()

      Return ``True`` if the symbol is used in its block.

   .. method:: is_imported()

      Return ``True`` if the symbol is created from an import statement.

   .. method:: is_parameter()

      Return ``True`` if the symbol is a parameter.

   .. method:: is_type_parameter()

      Return ``True`` if the symbol is a type parameter.

      .. versionadded:: 3.14

   .. method:: is_global()

      Return ``True`` if the symbol is global.

   .. method:: is_nonlocal()

      Return ``True`` if the symbol is nonlocal.

   .. method:: is_declared_global()

      Return ``True`` if the symbol is declared global with a global statement.

   .. method:: is_local()

      Return ``True`` if the symbol is local to its block.

   .. method:: is_annotated()

      Return ``True`` if the symbol is annotated.

      .. versionadded:: 3.6

   .. method:: is_free()

      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
      the perspective of a method.

      Consider the following example::

         def f():
             x = 1  # function-scoped
             class C:
                 x = 2  # class-scoped
                 def method(self):
                     return x

      In this example, the class-scoped symbol ``x`` is considered to
      be free from the perspective of ``C.method``, thereby allowing
      the latter to return *1* at runtime and not *2*.

      .. versionadded:: 3.14

   .. method:: is_assigned()

      Return ``True`` if the symbol is assigned to in its block.

   .. method:: is_comp_iter()

      Return ``True`` if the symbol is a comprehension iteration variable.

      .. versionadded:: 3.14

   .. method:: is_comp_cell()

      Return ``True`` if the symbol is a cell in an inlined comprehension.

      .. versionadded:: 3.14

   .. method:: is_namespace()

      Return ``True`` if name binding introduces new namespace.

      If the name is used as the target of a function or class statement, this
      will be true.

      For example::

         >>> table = symtable.symtable("def some_func(): pass", "string", "exec")
         >>> table.lookup("some_func").is_namespace()
         True

      Note that a single name can be bound to multiple objects.  If the result
      is ``True``, the name may also be bound to other objects, like an int or
      list, that does not introduce a new namespace.

   .. method:: get_namespaces()

      Return a list of namespaces bound to this name.

   .. method:: get_namespace()

      Return the namespace bound to this name. If more than one or no namespace
      is bound to this name, a :exc:`ValueError` is raised.


.. _symtable-cli:

Command-Line Usage
------------------

.. versionadded:: 3.13

The :mod:`symtable` module can be executed as a script from the command line.

.. code-block:: sh

   python -m symtable [infile...]

Symbol tables are generated for the specified Python source files and
dumped to stdout.
If no input file is specified, the content is read from stdin.
