argparse documentation Help

Supported types

When command line entries are mapped to the annotated data members, the text value is converted to the type of the data member.

Boolean flags

Boolean types usually represent command line flags. argparse supports multiple ways of providing flag value including negation (i.e., --no-flag):

Command line entries

Result

-b/--boo

true

-b=<value>/--boo=<value>

<value>

--no-b/--no-boo

false

-b <value>/--boo <value>

error

argparse supports the following strings as a <value> (comparison is case-insensitive):

<value>

Result

true, yes, y

true

false, no, n

false

Numbers and strings

Numeric (according to std.traits.isNumeric) and string (according to std.traits.isSomeString) data types are seamlessly converted to destination type using std.conv.to:

import argparse; struct T { int i; uint u; double f; string s; wstring w; dstring d; } T t; assert(CLI!T.parseArgs(t, ["-i","-5","-u","8","-f","12.345","-s","sss","-w","www","-d","ddd"])); assert(t == T(-5,8,12.345,"sss","www","ddd"));

Arrays

argparse supports 1D and 2D arrays:

  • If an argument is bound to 1D array, a new element is appended to this array each time the argument is provided in command line.

  • In case of 2D array, new elements are grouped in a way as they appear in command line and then each group is appended to this array.

The difference can be easily shown in the following example:

import argparse; struct T { int[] a; int[][] b; } T t; assert(CLI!T.parseArgs(t, ["-a","1","2","3","-a","4","5"])); assert(t.a == [1,2,3,4,5]); assert(CLI!T.parseArgs(t, ["-b","1","2","3","-b","4","5"])); assert(t.b == [[1,2,3],[4,5]]);

Alternatively one can set Config.arraySep to allow multiple elements in one command line entry:

import argparse; struct T { int[] a; } enum Config cfg = { arraySep: ',' }; T t; assert(CLI!(cfg, T).parseArgs(t, ["-a=1,2,3","-a","4,5"])); assert(t == T([1,2,3,4,5]));

Associative arrays

argparse also supports associative array where simple value type (e.g. numbers, strings etc.). In this case, expected format of the value is key=value (equal sign can be customized with Config.assignChar):

import argparse; struct T { int[string] a; } T t; assert(CLI!T.parseArgs(t, ["-a=foo=3","-a","boo=7"])); assert(t == T(["foo":3,"boo":7]));

Alternatively one can set Config.arraySep to allow multiple elements in one command line entry:

import argparse; struct T { int[string] a; } enum Config cfg = { arraySep: ',' }; T t; assert(CLI!(cfg, T).parseArgs(t, ["-a=foo=3,boo=7","-a","bar=4,baz=9"])); assert(t == T(["foo":3,"boo":7,"bar":4,"baz":9]));

Enums

It is encouraged to use enum types for arguments that have a limited set of valid values. In this case, argparse validates that the value specified in command line matches one of enum identifiers:

import argparse; struct T { enum Fruit { apple, pear }; Fruit a; } T t; assert(CLI!T.parseArgs(t, ["-a","apple"])); assert(t == T(T.Fruit.apple)); assert(CLI!T.parseArgs(t, ["-a=pear"])); assert(t == T(T.Fruit.pear));

In some cases the value for command line argument might have characters that are not allowed in enum identifiers. Actual values that are allowed in command line can be adjusted with ArgumentValue UDA:

import argparse; struct T { enum Fruit { apple, @ArgumentValue("no-apple","noapple") noapple }; Fruit a; } T t; assert(CLI!T.parseArgs(t, ["-a=no-apple"])); assert(t == T(T.Fruit.noapple)); assert(CLI!T.parseArgs(t, ["-a","noapple"])); assert(t == T(T.Fruit.noapple));

Counter

Counter is an argument that tracks the number of times it's specified in the command line:

import argparse; struct T { @(NamedArgument.Counter) int v; } T t; assert(CLI!T.parseArgs(t, ["-v","-v","-v"])); assert(t == T(3));

The same example with enabled bundling:

import argparse; struct T { @(NamedArgument.Counter) int v; } enum Config cfg = { bundling: true }; T t; assert(CLI!(cfg, T).parseArgs(t, ["-vv","-v"])); assert(t == T(3));

Callback

If member type is a function, argparse will try to call it when the corresponding argument is specified in the command line.

argparse supports the following function signatures (return value is ignored, if any):

  • ... func() - argument is treated as a boolean flag.

  • ... func(string) - argument has exactly one value. The value specified in command line is provided into string parameter.

  • ... func(string[]) - argument has zero or more values. Values specified in command line are provided into string[] parameter.

  • ... func(RawParam) - argument has zero or more values. Values specified in command line are provided into parameter.

Example:

import argparse; struct T { int a_; string[] b_; string[][] c_; @NamedArgument { void a() { a_++; } void b(string s) { b_ ~= s; } void c(string[] s) { c_ ~= s; } } } T t; assert(CLI!T.parseArgs(t, ["-a","-b","1","-c","q","w", "-a","-b","2","-c","e","r", "-a","-b","3","-c","t","y",])); assert(t == T(3, ["1","2","3"], [["q","w"],["e","r"],["t","y"]]));

Custom types

argparse can actually work with any arbitrary type - just provide parsing function (see Parsing customization for details):

import argparse; struct Value { string a; } struct T { @(NamedArgument.Parse!((string s) { return Value(s); })) Value s; } T t; assert(CLI!T.parseArgs(t, ["-s","foo"])); assert(t == T(Value("foo")));
Last modified: 07 August 2024