I have multiple Python scripts which use docopt.
My issue is that the available options for the two scripts differ slightly - one option is present in one script, but not the other.
I've included a minimum working example below.
If I run:
python main.py --num=7 --name=John
the script does not run, as --name=John is also passed to module1.py, where it is not a valid option.
With my actual script, I have several imports after docopt parses the arguments, and so I cannot simply move the docopt call to the bottom of the script (if __name__ == '__main__':
). If I do this, the imports in the imported script never get called, and I get undefined name errors.
I have found a workaround, but I don't think it is good practice at all.
What I am doing is adding:
if __name__ == '__main__':
arguments = docopt.docopt(__doc__, version=0.1)
just after the import docopt
.
However, I believe that having two of these statements in a script is bad practice. I cannot think of any other workarounds at this time though.
Can someone suggest a better solution? Thanks in advance.
main.py
"""
main.py
Usage:
main.py [--num=<num>] [--name=<name>] [--lib=<lib-dir>]
main.py -h | --help
main.py --version
Options:
--num=<num> A number
--name=<name> A name
--lib=<lib-dir> Path to the directory containing lib
--version
"""
import docopt
arguments = docopt.docopt(__doc__, version=0.1)
library_path = os.path.abspath(arguments['--lib'])
sys.path.insert(1, library_path)
NUM = arguments['--num']
from other_file import x, y
from module1 import function
def main():
print 'In main()'
function()
print NUM
if __name__ == '__main__':
print '{} being executed directly'.format(__name__)
main()
module1.py:
"""
module1.py
Usage:
module1.py [--num=<num>] [--lib=<lib-dir>]
module1.py -h | --help
module1.py --version
Options:
--num=<num> A number
--lib=<lib-dir> Path to the directory containing lib
--version
"""
import docopt
arguments = docopt.docopt(__doc__, version=0.1)
library_path = os.path.abspath(arguments['--lib'])
sys.path.insert(1, library_path)
NUM = arguments['--num']
from other_file import z
def main():
print 'In main()'
print NUM
def function():
print 'In function in {}'.format(__name__)
# print NUM
if __name__ == '__main__':
print '{} being executed directly'.format(__name__)
main()
EDIT:
I forgot to mention that the other_file module has many different versions. Because of this, one of the docopt options is the path to the file. This is then added to sys.path as follows:
library_path = os.path.abspath(arguments['--lib'])
sys.path.insert(1, library_path)
For this reason, the import of docopt in the global scope is needed to add the path to the other_file module to my system path.
The global variable (NUM below, DEBUG in my actual file) I can live without.
The clean solution is to refactor your code so it doesn't rely on a global, neither in
main.py
normodule1.py
:And: