summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorClaudiu Popa <pcmanticore@gmail.com>2018-06-12 12:25:48 +0200
committerClaudiu Popa <pcmanticore@gmail.com>2018-06-12 12:25:48 +0200
commitf3d4e140f218f4e2b6f938eca2f0510574270f55 (patch)
tree90935c3dcb34c6237e8bd92d7bb4103267ffdd8d /doc
parent1bd42a772deed579312d990692ca57373cfed49d (diff)
downloadastroid-git-f3d4e140f218f4e2b6f938eca2f0510574270f55.tar.gz
Add super minimal documentation regarding inference. Close #480
Diffstat (limited to 'doc')
-rw-r--r--doc/inference.rst80
1 files changed, 80 insertions, 0 deletions
diff --git a/doc/inference.rst b/doc/inference.rst
index 6ae42a3d..008e65e4 100644
--- a/doc/inference.rst
+++ b/doc/inference.rst
@@ -29,3 +29,83 @@ Namely, the special singleton :obj:`Uninferable()` is yielded when the inference
a point where it can't follow the code and is so unable to guess a value; and
instances of the :class:`Instance` class are yielded when the current node is
inferred to be an instance of some known class.
+
+
+Crash course into astroid's inference
+--------------------------------------
+
+Let's see some examples on how the inference might work in in ``astroid``.
+
+First we'll need to do a detour through some of the ``astroid``'s APIs.
+
+``astroid`` offers a relatively similar API to the builtin ``ast`` module,
+that is, you can do ``astroid.parse(string)`` to get an AST out of the given
+string::
+
+ >>> tree = astroid.parse('a + b')
+ >>> tree
+ >>> <Module l.0 at 0x10d8a68d0>
+
+ >>> print(tree.repr_tree())
+ Module(
+ name='',
+ doc=None,
+ file='<?>',
+ path=['<?>'],
+ package=False,
+ pure_python=True,
+ future_imports=set(),
+ body=[Expr(value=BinOp(
+ op='+',
+ left=Name(name='a'),
+ right=Name(name='b')))])
+
+
+The :meth:`repr_tree` is super useful to inspect how a tree actually looks.
+Most of the time you can access the same fields as those represented
+in the output of :meth:`repr_tree` so you can do ``tree.body[0].value.left``
+to get the left hand side operand of the addition operation.
+
+Another useful function that you can use is :func`astroid.extract_node`,
+which given a string, tries to extract one or more nodes from the given string::
+
+ >>> node = astroid.extract_node('''
+ ... a = 1
+ ... b = 2
+ ... c
+ ''')
+
+In that example, the node that is going to be returned is the last node
+from the tree, so it will be the ``Name(c)`` node.
+You can also use :func:`astroid.extract_node` to extract multiple nodes::
+
+ >>> nodes = astroid.extract_node('''
+ ... a = 1 #@
+ ... b = 2 #@
+ ... c
+ ''')
+
+You can use ``#@`` comment to annotate the lines for which you want the
+corresponding nodes to be extracted. In that example, what we're going to
+extract is two ``Expr`` nodes, which is in astroid's parlance, two statements,
+but you can access their underlying ``Assign`` nodes using the ``.value`` attribute.
+
+Now let's see how can we use ``astroid`` to infer what's going on with your code.
+
+The main method that you can use is :meth:`infer`. It returns a generator
+with all the potential values that ``astroid`` can extract for a piece of code::
+
+ >>> name_node = astroid.extract_node('''
+ ... a = 1
+ ... b = 2
+ ... c = a + b
+ ... c
+ ''')
+ >>> inferred = next(name_node.infer())
+ >>> inferred
+ <Const.int l.None at 0x10d913128>
+ >>> inferred.value
+ 3
+
+From this example you can see that ``astroid`` is capable of *inferring* what ``c``
+might hold, which is a constant value with the number 3.