bw2 / ConfigArgParse

A drop-in replacement for argparse that allows options to also be set via config files and/or environment variables.
MIT License
722 stars 121 forks source link

example is not working - Exception has occurred on "options = p.parse_args()" #218

Closed aisbergde closed 3 years ago

aisbergde commented 3 years ago

I tried to use the example as it is, but it doesn't work out of the box and the error message is not helpful I get an error on this line:

options = p.parse_args()

image

I am not an experienced python programmer, but I use Python when it has some functions which I need as a database developer. That's why I have no idea where to look and what to do.

some version info, if this could help

(env) PS D:\Repos\GitHub\DataHandwerk\DataHandwerk-toolkit-mssql\python\PythonApp_SqlParser> py -v
import _frozen_importlib # frozen
import _imp # builtin
import '_thread' # <class '_frozen_importlib.BuiltinImporter'>
import '_warnings' # <class '_frozen_importlib.BuiltinImporter'>
import '_weakref' # <class '_frozen_importlib.BuiltinImporter'>
import '_frozen_importlib_external' # <class '_frozen_importlib.FrozenImporter'>
import 'nt' # <class '_frozen_importlib.BuiltinImporter'>
import '_io' # <class '_frozen_importlib.BuiltinImporter'>
import 'marshal' # <class '_frozen_importlib.BuiltinImporter'>
import 'winreg' # <class '_frozen_importlib.BuiltinImporter'>
# installing zipimport hook
import 'time' # <class '_frozen_importlib.BuiltinImporter'>
import 'zipimport' # <class '_frozen_importlib.FrozenImporter'>
# installed zipimport hook
# C:\Python39\lib\encodings\__pycache__\__init__.cpython-39.pyc matches C:\Python39\lib\encodings\__init__.py
# code object from 'C:\\Python39\\lib\\encodings\\__pycache__\\__init__.cpython-39.pyc'
# C:\Python39\lib\__pycache__\codecs.cpython-39.pyc matches C:\Python39\lib\codecs.py
# code object from 'C:\\Python39\\lib\\__pycache__\\codecs.cpython-39.pyc'
import '_codecs' # <class '_frozen_importlib.BuiltinImporter'>
import 'codecs' # <_frozen_importlib_external.SourceFileLoader object at 0x000002587D0E58E0>
# C:\Python39\lib\encodings\__pycache__\aliases.cpython-39.pyc matches C:\Python39\lib\encodings\aliases.py
# code object from 'C:\\Python39\\lib\\encodings\\__pycache__\\aliases.cpython-39.pyc'
import 'encodings.aliases' # <_frozen_importlib_external.SourceFileLoader object at 0x000002587D281E80>
import 'encodings' # <_frozen_importlib_external.SourceFileLoader object at 0x000002587D0E56D0>
# C:\Python39\lib\encodings\__pycache__\utf_8.cpython-39.pyc matches C:\Python39\lib\encodings\utf_8.py
# code object from 'C:\\Python39\\lib\\encodings\\__pycache__\\utf_8.cpython-39.pyc'
import 'encodings.utf_8' # <_frozen_importlib_external.SourceFileLoader object at 0x000002587D0E5B20>
# C:\Python39\lib\encodings\__pycache__\cp1252.cpython-39.pyc matches C:\Python39\lib\encodings\cp1252.py
# code object from 'C:\\Python39\\lib\\encodings\\__pycache__\\cp1252.cpython-39.pyc'
import 'encodings.cp1252' # <_frozen_importlib_external.SourceFileLoader object at 0x000002587D281F40>
import '_signal' # <class '_frozen_importlib.BuiltinImporter'>
# C:\Python39\lib\encodings\__pycache__\latin_1.cpython-39.pyc matches C:\Python39\lib\encodings\latin_1.py
# code object from 'C:\\Python39\\lib\\encodings\\__pycache__\\latin_1.cpython-39.pyc'
import 'encodings.latin_1' # <_frozen_importlib_external.SourceFileLoader object at 0x000002587D298310>
# C:\Python39\lib\__pycache__\io.cpython-39.pyc matches C:\Python39\lib\io.py
# code object from 'C:\\Python39\\lib\\__pycache__\\io.cpython-39.pyc'
# C:\Python39\lib\__pycache__\abc.cpython-39.pyc matches C:\Python39\lib\abc.py
# code object from 'C:\\Python39\\lib\\__pycache__\\abc.cpython-39.pyc'
import '_abc' # <class '_frozen_importlib.BuiltinImporter'>
import 'abc' # <_frozen_importlib_external.SourceFileLoader object at 0x000002587D2987F0>
import 'io' # <_frozen_importlib_external.SourceFileLoader object at 0x000002587D2984F0>
# C:\Python39\lib\__pycache__\site.cpython-39.pyc matches C:\Python39\lib\site.py
# code object from 'C:\\Python39\\lib\\__pycache__\\site.cpython-39.pyc'
# C:\Python39\lib\__pycache__\os.cpython-39.pyc matches C:\Python39\lib\os.py
# code object from 'C:\\Python39\\lib\\__pycache__\\os.cpython-39.pyc'
# C:\Python39\lib\__pycache__\stat.cpython-39.pyc matches C:\Python39\lib\stat.py
# code object from 'C:\\Python39\\lib\\__pycache__\\stat.cpython-39.pyc'
import '_stat' # <class '_frozen_importlib.BuiltinImporter'>
import 'stat' # <_frozen_importlib_external.SourceFileLoader object at 0x000002587D2C3160>
# C:\Python39\lib\__pycache__\_collections_abc.cpython-39.pyc matches C:\Python39\lib\_collections_abc.py
# code object from 'C:\\Python39\\lib\\__pycache__\\_collections_abc.cpython-39.pyc'
import '_collections_abc' # <_frozen_importlib_external.SourceFileLoader object at 0x000002587D2C31F0>
# C:\Python39\lib\__pycache__\ntpath.cpython-39.pyc matches C:\Python39\lib\ntpath.py
# code object from 'C:\\Python39\\lib\\__pycache__\\ntpath.cpython-39.pyc'
# C:\Python39\lib\__pycache__\genericpath.cpython-39.pyc matches C:\Python39\lib\genericpath.py
# code object from 'C:\\Python39\\lib\\__pycache__\\genericpath.cpython-39.pyc'
import 'genericpath' # <_frozen_importlib_external.SourceFileLoader object at 0x000002587D2E6A00>
import 'ntpath' # <_frozen_importlib_external.SourceFileLoader object at 0x000002587D2C3910>
import 'os' # <_frozen_importlib_external.SourceFileLoader object at 0x000002587D2A2820>
# C:\Python39\lib\__pycache__\_sitebuiltins.cpython-39.pyc matches C:\Python39\lib\_sitebuiltins.py
# code object from 'C:\\Python39\\lib\\__pycache__\\_sitebuiltins.cpython-39.pyc'
import '_sitebuiltins' # <_frozen_importlib_external.SourceFileLoader object at 0x000002587D2BA4F0>
import 'site' # <_frozen_importlib_external.SourceFileLoader object at 0x000002587D298FD0>
Python 3.9.2 (tags/v3.9.2:1a79785, Feb 19 2021, 13:44:55) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
import 'atexit' # <class '_frozen_importlib.BuiltinImporter'>
>>>
aisbergde commented 3 years ago

I tried to comment out some parts. The following works:

import configargparse

p = configargparse.ArgParser(default_config_files=['/etc/app/conf.d/*.conf', '~/.my_settings'])
# p.add('-c', '--my-config', required=True, is_config_file=True, help='config file path')
# p.add('--genome', required=True, help='path to genome file')  # this option can be set in a config file because it starts with '--'
p.add('-v', help='verbose', action='store_true')
p.add('-d', '--dbsnp', help='known variants .vcf', env_var='DBSNP_PATH')  # this option can be set in a config file because it starts with '--'
# p.add('vcf', nargs='+', help='variant file(s)')

options = p.parse_args()

print(options)
print("----------")
print(p.format_help())
print("----------")
print(p.format_values())    # useful for logging where different settings came from

Some more comments in the example would be helpful. for example it looks like required=True has some meaning and if a required parameter is missing the script will create an error (whithout some information about the reason)

it is also not clear why p.add('vcf', nargs='+', help='variant file(s)') causes an error.

It would be fine to extend the example to make it executable without errors or some additional comments in the example would be helpful why some content will cause an error in some situations.

aisbergde commented 3 years ago

I think I got the idea: the errors are by intention and the error message is in the output of the program. But anyway the documentation is not 100% clear. What about this:

DBSNP_PATH=/data/dbsnp/variants_v2.vcf python config_test.py --my-config config.txt f1.vcf f2.vcf

What is the meaning of this DBSNP_PATH=/data/dbsnp/variants_v2.vcf? Or should this be the environment?

Maybe my questions are stupid, but I try to use Python as I can, but it looks like I have some deficites :-)

bw2 commented 3 years ago

You mostly figured it out.. by convention, environment variables are written in all capital letters and DBSNP_PATH=/data/dbsnp/variants_v2.vcf is meant to be an environment variable. Are you running your python code inside a code editor or an interactive console like ipython? If yes, this is why you're seeing long error messages that don't make sense. configargparse is meant to be used in stand-alone python scripts that you run non-interactively (by passing them to python.exe).