pythonargparseargv

Python argparse parse_known_args(namespace=); use of namespace?


Trying to understand pymol-open-source setup.py, I came accross this use of argparse.parse_know_args() namespace keyword:

import argparse
...

class options:
    osx_frameworks = True
    jobs = int(os.getenv('JOBS', 0))
    no_libxml = False
    no_glut = True
    use_msgpackc = 'guess'
    testing = False
    openvr = False
    use_openmp = 'no' if MAC else 'yes'
    use_vtkm = 'no'
    vmd_plugins = True
...

parser = argparse.ArgumentParser()
parser.add_argument('--glut', dest='no_glut', action="store_false",
                    help="link with GLUT (legacy GUI)")
parser.add_argument('--no-osx-frameworks', dest='osx_frameworks',
                    help="on MacOS use XQuartz instead of native frameworks",
                    action="store_false")
parser.add_argument('--jobs', '-j', type=int, help="for parallel builds "
                    "(defaults to number of processors)")
parser.add_argument('--no-libxml', action="store_true",
                    help="skip libxml2 dependency, disables COLLADA export")
parser.add_argument('--use-openmp', choices=('yes', 'no'),
                    help="Use OpenMP")
parser.add_argument('--use-vtkm', choices=('1.5', '1.6', '1.7', 'no'),
                    help="Use VTK-m for isosurface generation")
parser.add_argument('--use-msgpackc', choices=('c++11', 'c', 'guess', 'no'),
                    help="c++11: use msgpack-c header-only library; c: link against "
                    "shared library; no: disable fast MMTF load support")
parser.add_argument('--testing', action="store_true",
                    help="Build C-level tests")
parser.add_argument('--openvr', dest='openvr', action='store_true')
parser.add_argument('--no-vmd-plugins', dest='vmd_plugins',
                    action='store_false',
                    help='Disable VMD molfile plugins (libnetcdf dependency)')
options, sys.argv[1:] = parser.parse_known_args(namespace=options)
...

where in options, sys.argv[1:] = parser.parse_known_args(namespace=options), the namespace points to the options class.

I guess it is used to filter sysy.argv to be passed to setuptools.setup?

Is it the preferred / pythonic / correct way to use parser.parse_known_args namespace?

Usually namespace type returns <class 'argparse.Namespace'> while using this.

I got <class '__main__.Namespace'>.

Is this behaviour documented for argparse, do namespace keywords accept other kind of objects which could be useful to navigate pre-setup options?

Please bear with me, not expert in Python, setptools, and argparse.


Solution

  • Yes, normally one would simply use the default behavior of parse_known_args creating an instance of argparse.Namespace to store the results, and using the set_defaults method to provide default values. Something like

    import argparse
    
    [...]
    
    
    
    parser = argparse.ArgumentParser()
    [...]
    parser.set_defaults(osx_frameworks=True,
                        jobs=int(os.getenv('JOBS', 0)),
                        no_libxml=False,
                        # etc)
    
    options, sys.argv[1:] = parser.parse_known_args()
    

    The author of this library chose instead to use a class (an instance of type) instead of an instance of Namespace to store the arguments, and to initialize the class attributes with their default values.

    (Note, too, one could specify defaults for each argument in the appropriate call to add_argument. set_defaults is useful for initializing targets that might be set by multiple arguments, or that are only conditionally created after parsing.)