1

I would like to check if all modules imported by a script are installed before I actually run the script, because the script is quite complex and is usually running for many hours. Also, it may import different modules depending on the options passed to it, so just running it once may not check everything. So, I wouldn't like to run this script on a new system for few hours only to see it failing before completion because of a missing module.

Apparently, pyflakes and pychecker are not helpful here, correct me if I'm wrong. I can do something like this:

$ python -c "$(cat *.py|grep import|sed 's/^\s\+//g'|tr '\n' ';')"

but it's not very robust, it will break if the word 'import' appears in a string, for example.

So, how can I do this task properly?

piokuc
  • 25,594
  • 11
  • 72
  • 102
  • The simple solution is changing your grep to `grep '^\s*import'`, because no Python line may start with import (correct me if I'm wrong). – Brigand Mar 04 '13 at 11:38
  • http://stackoverflow.com/questions/2875232/list-python-package-dependencies-without-loading-them might be relevant. Particularly: http://furius.ca/snakefood/ looks like it does what you want – entropy Mar 04 '13 at 11:39
  • @FakeRainBrigand what about `from import `? No, any regex-based solution will be too brittle. The best way is to work at the AST-level not the textual level which is what snakefood, linked in my previous comment, does(or at least claims to, never tried it) – entropy Mar 04 '13 at 11:41
  • Thanks, you're correct. I also recommend going through imports your self and creating a [requirements.txt](http://www.pip-installer.org/en/1.3.X/logic.html#requirements-file-format) file which allows you to simply run `pip install` and get all your depends at once. – Brigand Mar 04 '13 at 11:42
  • @FakeRainBrigand Thanks a lot for the tip on requirements.txt, that is the best what one can do really, however I am often dealing with other people's modules/scripts which don't have the requirements.txt, so the solution with modulefinder seems the best. – piokuc Mar 04 '13 at 12:13
  • @entropy Thanks for the link, I'll check it out. – piokuc Mar 04 '13 at 12:14

2 Answers2

7

You could use ModuleFinder from the standard lib modulefinder Using the example from the docs

from modulefinder import ModuleFinder
finder = ModuleFinder()
finder.run_script('bacon.py')

print 'Loaded modules:'
for name, mod in finder.modules.iteritems():
    print '%s: ' % name,
    print ','.join(mod.globalnames.keys()[:3])

print '-'*50
print 'Modules not imported:'
print '\n'.join(finder.badmodules.iterkeys())
0

You could write a test.py that just contains all the possible imports for example:

import these
import are
import some
import modules

Run it and if there are any problems python will let you know

Awalias
  • 2,027
  • 6
  • 31
  • 51
  • Thanks for the answer. That's quite a good approach, the only problem is that if this test is being edited manually then it is easy to forget about updating it. – piokuc Mar 04 '13 at 12:16