HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Load modules conditionally Python

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
conditionallymodulespythonload

Problem

I wrote a python module that needs to load a file parser to work. Initially it was just one text parsing module but I need to add more parsers for different cases.

parser_class1.py

parser_class2.py

parser_class3.py


Only one is required for every running instance. I'm thinking load it by command line:

mmain.py -p parser_class1


I wrote this code in order to select the parser to load when the main module is called:

#!/usr/bin/env python

import argparse
aparser = argparse.ArgumentParser()
aparser.add_argument('-p',
            action='store',
            dest='module',
            help='-i module to import')
results = aparser.parse_args()

if not results.module:
    aparser.error('Error! no module')
try:
    exec("import %s" %(results.module))
    print '%s imported done!'%(results.module)
except ImportError, e:
    print e


But, I was reading that this way is dangerous, maybe not standard.

Then is this approach ok?

Or must I find another way to do it?

Why?

Solution

Regarding the safety aspect of your question.

The reason why exec() can be dangerous is that is can allow a nefarious agent to execute code that you never intended.

Let's assume for example that somewhere in your program, you have sensitive data elements such as:

username = secret_username
password = never_share


And let's also assume that someone calls your program like this:

mmain.py -p 'parser_class1;print globals()'


Then your exec() statement would actually be:

exec("import %s" %('parser_class1;print globals()'))


And this would result in your program printing out all variables in your global space for them... including your username and password.

By making your program utilize the __import__ method as mentioned by @Jaime, you can at least prevent people from executing non-import statements in your code.

But, you should, whenever possible also examine the input from a user before using it to execute any dynamic code.

Code Snippets

username = secret_username
password = never_share
mmain.py -p 'parser_class1;print globals()'
exec("import %s" %('parser_class1;print globals()'))

Context

StackExchange Code Review Q#24349, answer score: 4

Revisions (0)

No revisions yet.