=======
visitor
=======

`visitor` uses the `compiler` module to browse the AST, then provide a
mapping with filtered functions.

Registering code
================

The `CodeSeeker` class scans the code of the filename provided::

    >>> from visitor import CodeSeeker
    >>> import os
    >>> seeker = CodeSeeker(os.path.join(data_dir, 'source1.py'))

The code is then registered in a dictionary::

    >>> seeker.registered_code
    {'/.../data/source1.py ...': <visitor.CleanNode object at ...>, ...}

A global dictionnary can be used to register code from several modules,
and that's what `register_module` does::

    >>> from visitor import register_module
    >>> register_module(os.path.join(data_dir, 'source1.py'))

The code is then registered in a global dictionary::

    >>> from visitor import registered_code
    >>> registered_code
    {'/.../data/source1.py ...': <visitor.CleanNode object at ...>, ...}

This allow us to register a folder. The treshold parameter allow us
to filter methods that are added given the number of nodes the function
has::

    >>> from visitor import register_folder
    >>> register_folder(data_dir, treshold=1)
    >>> len(registered_code.items())
    4

The code registered can be saved on the filesystem to speed up the
calculations::

    >>> from visitor import save_register
    >>> save_register(os.path.join(data_dir, 'code.reg'))

Then reloaded::

    >>> from visitor import load_register
    >>> load_register(os.path.join(data_dir, 'code.reg'))

This is useful to speed up registration, because before walking through
a module, we calculate its MD5 to avoid a rescan when the code didn't move::

    >>> from visitor import visited_modules
    >>> items = visited_modules.items()
    >>> items.sort()
    >>> items
    [('/.../source1.py', 'd828d85b0bbdeecc9a43aab6b370d8e1'),
     ('/.../source2.py', '2c481cb957529b2c645a78c37b645f9e')]

It is used transparently in register_folder.

