开发者

Python dependencies?

Is it possible to programmatically detect 开发者_StackOverflow中文版dependencies given a python project residing in SVN?


Here is a twist which adds some precision, and which might be useful if you find you're frequently checking dependencies of miscellaneous code:

  • Catches only import statements executed by the code being analyzed.
  • Automatically excludes all system-loaded modules, so you don't have to weed through it.
  • Also reports the symbols imported from each module.

Code:

import __builtin__
import collections
import sys

IN_USE = collections.defaultdict(set)
_IMPORT = __builtin__.__import__

def _myimport(name, globs=None, locs=None, fromlist=None, level=-1):
    global IN_USE
    if fromlist is None:
        fromlist = []
    IN_USE[name].update(fromlist)
    return _IMPORT(name, globs, locs, fromlist, level)

# monkey-patch __import__
setattr(__builtin__, '__import__', _myimport)

# import and run the target project here and run the routine
import foobar
foobar.do_something()

# when it finishes running, dump the imports
print 'modules and symbols imported by "foobar":'
for key in sorted(IN_USE.keys()):
    print key
    for name in sorted(IN_USE[key]):
        print '  ', name

Example foobar module:

import byteplay
import cjson

def _other():
    from os import path
    from sys import modules

def do_something():
    import hashlib
    import lxml
    _other()

Output:

modules and symbols imported by "foobar":
_hashlib
array
   array
byteplay
cStringIO
   StringIO
cjson
dis
   findlabels
foobar
hashlib
itertools
lxml
opcode
   *
   __all__
operator
os
   path
sys
   modules
types
warnings


Absolutely! If you are working from a UNIX or Linux shell, a simple combination of grep and awk would work; basically, all you want to do is search for lines containing the "import" keyword.

However, if you are working from any environment, you could just write a small Python script to do the searching for you (don't forget that strings are treated as immutable sequences, so you can do something like if "import" in line: ....

The one sticky spot, would be associating those imported modules to their package name (the first one that comes to mind is the PIL module, in Ubuntu it's provided by the python-imaging package).


Python code can import modules using runtime-constructed strings, so the only surefire way would be to run the code. Real-world example: when you open a database with SQLAlchemy's dbconnect, the library will load one or more db-api modules depending on the content of your database string.

If you're willing to run the code, here is a relatively simple way to do this by examining sys.modules when it finishes:

>>> from sys import modules
>>> import codeofinterest
>>> execute_code_of_interest()
>>> print modules
[ long, list, of, loaded, modules ]

Here, too, you should keep in mind that this could theoretically fail if execute_code_of_interest() modifies sys.modules, but I believe that's quite rare in production code.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜