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

   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`.


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

.. 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 ``'class'``,
      ``'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()

      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 nonlocals in this function.

   .. method:: get_frees()

      Return a tuple containing names of free variables in this function.


.. class:: Class

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

   .. method:: get_methods()

      Return a tuple containing the names of methods declared in the class.


.. 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_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_assigned()

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

   .. 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.
