patternpythonMinor
Load modules conditionally Python
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.
Only one is required for every running instance. I'm thinking load it by command line:
I wrote this code in order to select the parser to load when the main module is called:
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?
parser_class1.py
parser_class2.py
parser_class3.pyOnly one is required for every running instance. I'm thinking load it by command line:
mmain.py -p parser_class1I 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 eBut, 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
Let's assume for example that somewhere in your program, you have sensitive data elements such as:
And let's also assume that someone calls your program like this:
Then your
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
But, you should, whenever possible also examine the input from a user before using it to execute any dynamic code.
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_shareAnd 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_sharemmain.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.