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


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