Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python convert dictionary to argparse

Right now, I have a script that can accept command line arguments using argparse. For example, like this:

#foo.py
def function_with_args(optional_args=None):
  parser = argparse.ArgumentParser()
  # add some arguments
  args = parser.parse_args(optional_args)
  # do something with args

However, I'd like to be able to use this function with a dictionary instead, for example with something like this:

def function_using_dict(**kwargs):
  # define parser and add some arguments
  args = parser.parse_dict_args(kwargs)
  # everything else is the same

Note that I have a lot of arguments with default values in argparse which I'd like to use, so the following wouldn't work:

def function_no_default_args(**kwargs):
  args = kwargs # not using default values that we add to the parser!
like image 934
William Avatar asked Aug 31 '25 10:08

William


1 Answers

argparse.Namespace is a relatively simple object subclass, with most of its code devoted to displaying the attributes (as print(args) shows). Internally parse_args uses get_attr and set_attr to access the namespace, minimizing the assumptions about attributes names.

When using subparsers, the subparser starts with a 'blank' namespace, and uses the following code to copy its values to the main namespace.

    # In case this subparser defines new defaults, we parse them
    # in a new namespace object and then update the original
    # namespace for the relevant parts.
    subnamespace, arg_strings = parser.parse_known_args(arg_strings, None)
    for key, value in vars(subnamespace).items():
        setattr(namespace, key, value)

Originally the main namespace was passed to the subparser, eg. parser.parse_known_args(arg_strings, namespace), but the current version lets the subparser defaults take priority.

Handling defaults is a bit complicated. If you don't have any required arguments then

 args = parser.parse_args([])

will set all the defaults. Or you could look at the start of parse.parse_known_args to see how defaults are inserted into the namespace at the start of parsing. Just beware that there's an added step at the end of parsing that runs remaining defaults through their respective type functions.

like image 127
hpaulj Avatar answered Sep 03 '25 00:09

hpaulj