2011/3/9 Daπid <davidmen...@gmail.com>:
> Pues si encuentras algún sitio resumido, te agradezco que me lo hagas
> saber. Hasta el momento, me he apañado a base de prueba y error con
> los más gordos y a ojo.

A lo tonto, he hecho el script que paso adjunto. Se puede usar para
generar un grafo que muestra las dependencias de todo un árbol de
directorios (con restricciones). Lo usé para generar el del directorio
raíz de módulos estándar de Python (escupe sintaxis de GraphViz) y es
una locura.

Si es importa como módulo, se puede usar para estudiar las
dependencias de un grupo escogido de ficheros (basta pasar el path del
fichero a estudiar a dependencies_for_file.
#!/usr/bin/env python

import sys
import os, os.path
import os.path as ospt
import re
import ast
import imp
from ast import Import, ImportFrom

re1 = re.compile(r'from\s+([^\s]+)\s+import')
re2 = re.compile(r'import\s+([^\s;]+)')

remove = ('__future__', '__phello__', '__builtin__')

def is_reachable(module):
    try:
        imp.find_module(module)
        return True
    except ImportError:
        return False

def dependencies_for_file(path):
    deps = set()

    tree = ast.parse(open(path).read())
    for node in (x for x in ast.walk(tree) if isinstance(x, (Import, ImportFrom))):
        if isinstance(node, ImportFrom):
            names = [node.module.split('.')[0]]
        else:
            names = [mod.name.split('.')[0] for mod in node.names]

        for reachable in [x for x in names if is_reachable(x)]:
            deps.add(reachable)

    return [x for x in deps if x not in remove]

def dependencies_for_package(path):
    deps = None

    init = ospt.join(path, '__init__.py')
    if ospt.exists(init):
        dep1 = dependencies_for_dir(path)
        deps = set(sum([list(x) for x in dep1.values()], []))

    return deps

def dependencies_for_dir(path):
    modules = {}

    for fname in os.listdir(path):
        newpath = ospt.join(path, fname)
        if fname.endswith('.py'):
            modules[fname[:-3]] = dependencies_for_file(newpath)
        elif ospt.isdir(newpath):
            dp = dependencies_for_package(newpath)
            if dp is not None:
                modules[fname] = dp

    return modules

def print_graph(nodes):
    print "strict digraph modules {"
    for origin, destinations in nodes.items():
        for dest in destinations:
            print origin, '->', dest
    print "}"

def main():
    args = sys.argv[1:]

    print_graph(dependencies_for_dir(args[0]))

if __name__ == '__main__':
    sys.exit(main())
_______________________________________________
Python-es mailing list
Python-es@python.org
http://mail.python.org/mailman/listinfo/python-es
FAQ: http://python-es-faq.wikidot.com/

Responder a