forked from VimPlug/jedi
new evaluate docstring
This commit is contained in:
@@ -17,12 +17,61 @@ Evaluation of Python code in |jedi| is based on three assumptions:
|
|||||||
* The programmer is not a total dick, e.g. like `this
|
* The programmer is not a total dick, e.g. like `this
|
||||||
<https://github.com/davidhalter/jedi/issues/24>`_ :-)
|
<https://github.com/davidhalter/jedi/issues/24>`_ :-)
|
||||||
|
|
||||||
|
That said, there's mainly one entry point in this script: ``follow_statement``.
|
||||||
|
This is where autocompletion starts. Everything you want to complete is either
|
||||||
|
a ``parsing.Statement`` or some special name like ``class``, which is easy to
|
||||||
|
complete.
|
||||||
|
|
||||||
|
Therefore you need to understand what follows after ``follow_statement``. Let's
|
||||||
|
make an example:
|
||||||
|
|
||||||
|
>>> import datetime
|
||||||
|
>>> datetime.date.toda# <-- cursor here
|
||||||
|
|
||||||
|
First of it all, this module doesn't care about completion. It really just
|
||||||
|
cares about ``datetime.date``. At the end of the procedure
|
||||||
|
``follow_statement`` will return the ``datetime`` class.
|
||||||
|
|
||||||
|
To *visualize* this (simplified):
|
||||||
|
|
||||||
|
- ``follow_statement`` - ``<Statement: datetime.date>``
|
||||||
|
|
||||||
|
- Unpacking of the statement into ``[[<Call: datetime.date>]]``
|
||||||
|
- ``follow_call_list``, calls ``follow_call`` with ``<Call: datetime.date>``
|
||||||
|
- ``follow_call`` - searches the ``datetime`` name within the module.
|
||||||
|
|
||||||
|
This is exactly where it starts to get complicated. Now recursions start to
|
||||||
|
kick in. The statement has not been resolved fully, but now we need to resolve
|
||||||
|
the datetime import. So it continues
|
||||||
|
|
||||||
|
- follow import, which happens in the :mod:imports module.
|
||||||
|
- now the same ``follow_call`` as above calls ``follow_paths`` to follow the
|
||||||
|
second part of the statement ``date``.
|
||||||
|
- After ``follow_paths`` returns with the desired ``datetime.date`` class, the
|
||||||
|
result is being returned and the recursion finishes.
|
||||||
|
|
||||||
|
Now what would happen if we wanted ``datetime.date.foo.bar``? Just two more
|
||||||
|
calls to ``follow_paths`` (which calls itself with a recursion). What if the
|
||||||
|
import would contain another Statement like this:
|
||||||
|
|
||||||
|
>>> from foo import bar
|
||||||
|
>>> Date = bar.baz
|
||||||
|
|
||||||
|
Well... You get it. Just another ``follow_statement`` recursion. It's really
|
||||||
|
easy. Just that Python is not that easy sometimes. To understand tuple
|
||||||
|
assignments and different class scopes, a lot more code had to be written. Yet
|
||||||
|
we're still not talking about Descriptors and Nested List Comprehensions, just
|
||||||
|
the simple stuff.
|
||||||
|
|
||||||
|
So if you want to change something, write a test and then just change what you
|
||||||
|
want. This module has been tested by about 600 tests. Don't be afraid to break
|
||||||
|
something. The tests are good enough.
|
||||||
|
|
||||||
|
I need to mention now that this recursive approach is really good because it
|
||||||
|
only *executes* what needs to be *executed*. All the statements and modules
|
||||||
|
that are not used are just being ignored. It's a little bit similar to the
|
||||||
|
backtracking algorithm.
|
||||||
|
|
||||||
The functions should be described in their docstrings. However, there are some
|
|
||||||
classes, which are used to store the values. After those classes, there are the
|
|
||||||
search functions `get_names_for_scope` and `get_scopes_for_name`. At the end
|
|
||||||
there are the `follow_` functions, which evaluate a statement, or parts of a
|
|
||||||
statement.
|
|
||||||
|
|
||||||
.. todo:: nonlocal statement, needed or can be ignored? (py3k)
|
.. todo:: nonlocal statement, needed or can be ignored? (py3k)
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user