I need to pass a dictionary to a python module via a command line. I have not found a way to get Python to cooperate. The following is a very simplified example of what I'd like to accomplish. This produces the following error TypeError: _get_positional_kwargs() missing 1 required positional argument: 'dest'
. Adding a dest
argument to the add_argument line results in TypeError: __init__() got an unexpected keyword argument 'kwargs'
, indicating the sad possibility that argparse simply may not take a dictionary as an argument. Is a pickle file truly the only option for passing dictionaries back and forth from command line calls?
def run(**kwargs):
for i in kwargs.items():
print(f'{i}: {kwargs[i]}')
# ...some code to manipulate the dictionary
return kwargs
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="Test script")
parser.add_argument(kwargs='**', description='A dictionary to be manipulated and returned')
args = parser.parse_args()
x = run(args)
pass
Additional info - I know that I can pass a list to a *nargs
argument with a command line that includes space-delimited arguments, but I need to do something similar with a dictionary.
UPDATE - WHAT WORKED: Based on the helpful input from @chepner, I was able to get it to work with the json solution he mentioned in his answer. On my Windows platform, I did have to remove all spaces from the dictionary string and escape characters are required in the final command line string.
{\"this\":1,\"is\":2,\"a\":5,\"dictionary\":7}
Arguments are strings, period. What you want to pass is a string that contains an encoded dict
, for example using JSON.
import argparse
import json
parser = argparse.ArgumentParser()
parser.add_argument('data', type=json.loads)
args = parser.parse_args()
If you run your script with something like
myscript '{"foo": 3, "bar": "hello"}'
then args.data["foo"] == 3
and args.data["bar"] == "hello"
.