.. _ast:

Abstract Syntax Trees
=====================

.. module:: ast
   :synopsis: Abstract Syntax Tree classes and manipulation.

.. sectionauthor:: Martin v. Löwis <martin@v.loewis.de>
.. sectionauthor:: Georg Brandl <georg@python.org>


The :mod:`ast` module helps Python applications to process trees of the Python
abstract syntax grammar.  The abstract syntax itself might change with each
Python release; this module helps to find out programmatically what the current
grammar looks like.

An abstract syntax tree can be generated by passing :data:`ast.PyCF_ONLY_AST` as
a flag to the :func:`compile` builtin function, or using the :func:`parse`
helper provided in this module.  The result will be a tree of objects whose
classes all inherit from :class:`ast.AST`.  An abstract syntax tree can be
compiled into a Python code object using the built-in :func:`compile` function.


Node classes
------------

.. class:: AST

   This is the base of all AST node classes.  The actual node classes are
   derived from the :file:`Parser/Python.asdl` file, which is reproduced
   :ref:`below <abstract-grammar>`.  They are defined in the :mod:`_ast` C
   module and re-exported in :mod:`ast`.

   There is one class defined for each left-hand side symbol in the abstract
   grammar (for example, :class:`ast.stmt` or :class:`ast.expr`).  In addition,
   there is one class defined for each constructor on the right-hand side; these
   classes inherit from the classes for the left-hand side trees.  For example,
   :class:`ast.BinOp` inherits from :class:`ast.expr`.  For production rules
   with alternatives (aka "sums"), the left-hand side class is abstract: only
   instances of specific constructor nodes are ever created.

   .. attribute:: _fields

      Each concrete class has an attribute :attr:`_fields` which gives the names
      of all child nodes.

      Each instance of a concrete class has one attribute for each child node,
      of the type as defined in the grammar.  For example, :class:`ast.BinOp`
      instances have an attribute :attr:`left` of type :class:`ast.expr`.

      If these attributes are marked as optional in the grammar (using a
      question mark), the value might be ``None``.  If the attributes can have
      zero-or-more values (marked with an asterisk), the values are represented
      as Python lists.  All possible attributes must be present and have valid
      values when compiling an AST with :func:`compile`.

   .. attribute:: lineno
                  col_offset

      Instances of :class:`ast.expr` and :class:`ast.stmt` subclasses have
      :attr:`lineno` and :attr:`col_offset` attributes.  The :attr:`lineno` is
      the line number of source text (1-indexed so the first line is line 1) and
      the :attr:`col_offset` is the UTF-8 byte offset of the first token that
      generated the node.  The UTF-8 offset is recorded because the parser uses
      UTF-8 internally.

   The constructor of a class :class:`ast.T` parses its arguments as follows:

   * If there are positional arguments, there must be as many as there are items
     in :attr:`T._fields`; they will be assigned as attributes of these names.
   * If there are keyword arguments, they will set the attributes of the same
     names to the given values.

   For example, to create and populate an :class:`ast.UnaryOp` node, you could
   use ::

      node = ast.UnaryOp()
      node.op = ast.USub()
      node.operand = ast.Num()
      node.operand.n = 5
      node.operand.lineno = 0
      node.operand.col_offset = 0
      node.lineno = 0
      node.col_offset = 0

   or the more compact ::

      node = ast.UnaryOp(ast.USub(), ast.Num(5, lineno=0, col_offset=0),
                         lineno=0, col_offset=0)


.. _abstract-grammar:

Abstract Grammar
----------------

The module defines a string constant ``__version__`` which is the decimal
Subversion revision number of the file shown below.

The abstract grammar is currently defined as follows:

.. literalinclude:: ../../Parser/Python.asdl


:mod:`ast` Helpers
------------------

Apart from the node classes, :mod:`ast` module defines these utility functions
and classes for traversing abstract syntax trees:

.. function:: parse(expr, filename='<unknown>', mode='exec')

   Parse an expression into an AST node.  Equivalent to ``compile(expr,
   filename, mode, ast.PyCF_ONLY_AST)``.


.. function:: literal_eval(node_or_string)

   Safely evaluate an expression node or a string containing a Python
   expression.  The string or node provided may only consist of the following
   Python literal structures: strings, numbers, tuples, lists, dicts, booleans,
   and ``None``.

   This can be used for safely evaluating strings containing Python expressions
   from untrusted sources without the need to parse the values oneself.


.. function:: get_docstring(node, clean=True)

   Return the docstring of the given *node* (which must be a
   :class:`FunctionDef`, :class:`ClassDef` or :class:`Module` node), or ``None``
   if it has no docstring.  If *clean* is true, clean up the docstring's
   indentation with :func:`inspect.cleandoc`.


.. function:: fix_missing_locations(node)

   When you compile a node tree with :func:`compile`, the compiler expects
   :attr:`lineno` and :attr:`col_offset` attributes for every node that supports
   them.  This is rather tedious to fill in for generated nodes, so this helper
   adds these attributes recursively where not already set, by setting them to
   the values of the parent node.  It works recursively starting at *node*.


.. function:: increment_lineno(node, n=1)

   Increment the line number of each node in the tree starting at *node* by *n*.
   This is useful to "move code" to a different location in a file.


.. function:: copy_location(new_node, old_node)

   Copy source location (:attr:`lineno` and :attr:`col_offset`) from *old_node*
   to *new_node* if possible, and return *new_node*.


.. function:: iter_fields(node)

   Yield a tuple of ``(fieldname, value)`` for each field in ``node._fields``
   that is present on *node*.


.. function:: iter_child_nodes(node)

   Yield all direct child nodes of *node*, that is, all fields that are nodes
   and all items of fields that are lists of nodes.


.. function:: walk(node)

   Recursively yield all child nodes of *node*, in no specified order.  This is
   useful if you only want to modify nodes in place and don't care about the
   context.


.. class:: NodeVisitor()

   A node visitor base class that walks the abstract syntax tree and calls a
   visitor function for every node found.  This function may return a value
   which is forwarded by the :meth:`visit` method.

   This class is meant to be subclassed, with the subclass adding visitor
   methods.

   .. method:: visit(node)

      Visit a node.  The default implementation calls the method called
      :samp:`self.visit_{classname}` where *classname* is the name of the node
      class, or :meth:`generic_visit` if that method doesn't exist.

   .. method:: generic_visit(node)

      This visitor calls :meth:`visit` on all children of the node.

      Note that child nodes of nodes that have a custom visitor method won't be
      visited unless the visitor calls :meth:`generic_visit` or visits them
      itself.

   Don't use the :class:`NodeVisitor` if you want to apply changes to nodes
   during traversal.  For this a special visitor exists
   (:class:`NodeTransformer`) that allows modifications.


.. class:: NodeTransformer()

   A :class:`NodeVisitor` subclass that walks the abstract syntax tree and
   allows modification of nodes.

   The :class:`NodeTransformer` will walk the AST and use the return value of
   the visitor methods to replace or remove the old node.  If the return value
   of the visitor method is ``None``, the node will be removed from its
   location, otherwise it is replaced with the return value.  The return value
   may be the original node in which case no replacement takes place.

   Here is an example transformer that rewrites all occurrences of name lookups
   (``foo``) to ``data['foo']``::

      class RewriteName(NodeTransformer):

          def visit_Name(self, node):
              return copy_location(Subscript(
                  value=Name(id='data', ctx=Load()),
                  slice=Index(value=Str(s=node.id)),
                  ctx=node.ctx
              ), node)

   Keep in mind that if the node you're operating on has child nodes you must
   either transform the child nodes yourself or call the :meth:`generic_visit`
   method for the node first.

   For nodes that were part of a collection of statements (that applies to all
   statement nodes), the visitor may also return a list of nodes rather than
   just a single node.

   Usually you use the transformer like this::

      node = YourTransformer().visit(node)


.. function:: dump(node, annotate_fields=True, include_attributes=False)

   Return a formatted dump of the tree in *node*.  This is mainly useful for
   debugging purposes.  The returned string will show the names and the values
   for fields.  This makes the code impossible to evaluate, so if evaluation is
   wanted *annotate_fields* must be set to False.  Attributes such as line
   numbers and column offsets are not dumped by default.  If this is wanted,
   *include_attributes* can be set to ``True``.
