0

I would like to read in a dictionary from a config .txt file into argparse

Current main.py code:

parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
parser.add_argument('--config_1', action='store_true')
parser.add_argument('--config_2')
args = vars(parser.parse_args())

I can run my script like: python main.py @config.txt

Where config.txt contains --config_1

Specifically, I would like to read in config_2 from config.txt as a dictionary - something like:

--config_1
--config_2 {
    'key1': [], 
    'key2': ['value1', 'value2']
}

This is a follow-up question to: Passing configs from `.txt` file into argparse? (Similar to youtube-dl's `--config-location`)


Edit: For clarification, I'm getting an error:

error: unrecognized arguments:  --config_2 { 'key1': [], 'key2': ['value1', 'value2'] }
Wilan
  • 147
  • 1
  • 12
  • "This is a follow-up question to" I don't understand how it is a different question. – Karl Knechtel Mar 25 '22 at 19:04
  • Here I'm specifically asking how to pass dictionaries, where as the previous question was just a general question on how to use text files to write configs in. – Wilan Mar 25 '22 at 19:06
  • What actually is the difficulty? If you try your existing code, how does the result differ from your expectation? For example, does it correctly handle the `config_2` value being split across multiple lines? (If not, *what is the rule* that you want the code to use, in order to decide how many lines are in the value?) Does it create a dictionary? (Is the question really just "how do I create a dictionary from a string that represents it"?) Is something else wrong? – Karl Knechtel Mar 25 '22 at 19:12
  • As asked, the answer is "you need to write code that interprets the contents of the file properly", but that is too broad for a Stack Overflow question. Start by making sure you *understand* how the answer to the previous question works. – Karl Knechtel Mar 25 '22 at 19:13
  • I think the answer is that argparse doesn't have anything to do this automatically. It treats the file as if the contents were command-line arguments, it won't parse it as a dictionary. – Barmar Mar 25 '22 at 19:47

1 Answers1

0

The default reader, as documented should accept

--config_1
--config_2
value

The alternate that's also documented would accept

--config_1
--config_2 value

Both of these are equivalent to the user typing

python main.py --config_1 --config_2 value

This prefix mechanism does not add to the parsing power of argparse, it just provides a way of entering a large number of arguments as an editable file.

 --config_1
 --config_2 
 "{'key1': [], 'key2': ['value1', 'value2']}"

may work, resulting a args.config_2 string value as quoted. Parsing that as a dict is up to you.

Loading your file as json might be better.

The key point is that the @ file is read right at the start of parsing, and strings inserted into the sys.argv list, just as though the user had typed them. This is done before any real parsing is done. The custom file reader, if any, should return a list of strings.

Other posters have asked about entering generic key:value pairs. argparse does not handle this directly. The answers to such questions nearly always involve a user provided parser/splitter, either as a custom type, action class, or post parsing action. You don't get extra points for doing "everything" in `argparse.

hpaulj
  • 221,503
  • 14
  • 230
  • 353