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?

6
  • 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). Commented Mar 4, 2013 at 11:38
  • stackoverflow.com/questions/2875232/… might be relevant. Particularly: furius.ca/snakefood looks like it does what you want Commented Mar 4, 2013 at 11:39
  • @FakeRainBrigand what about from <module> import <stuff>? 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) Commented Mar 4, 2013 at 11:41
  • Thanks, you're correct. I also recommend going through imports your self and creating a requirements.txt file which allows you to simply run pip install and get all your depends at once. Commented Mar 4, 2013 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. Commented Mar 4, 2013 at 12:13

2 Answers 2

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())
Sign up to request clarification or add additional context in comments.

4 Comments

Great, thank you very much. This seems to be exactly what I need. I didn't know modulefinder even though it's a standard module!
Doesn't that run the script though? He explicitly said he didn't want to do that
@entropy Not really -> gist.github.com/ephexeve/5081940
@BenMezger aha, nice, I guess run_script() is a bit misleading then :)
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

1 Comment

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.