argparse documentation Help

Config

argparse provides decent amount of settings to customize the parser. All customizations can be done by creating Config object with required settings (see below) and passing it to CLI API.

Assign character

Config.assignChar is an assignment character used in arguments with value: -a=5, -boo=foo.

Default is equal sign =.

Example:

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

Assign character

Config.assignKeyValueChar is an assignment character used in arguments that have associative array type: -a=key=value, -boo=key=value.

Default is equal sign =.

Example:

import argparse; struct T { int[string] a; } enum Config cfg = { assignKeyValueChar: ':' }; T t; assert(CLI!(cfg, T).parseArgs(t, ["-a=A:1","-a=B:2,C:3"])); assert(t == T(["A":1,"B":2,"C":3]));

Value separator

Config.valueSep is a separator that is used to extract argument values: -a=5,6,7, --boo=foo,far,zoo.

Default is ,.

Example:

import argparse; struct T { string[] a; } T t1; assert(CLI!T.parseArgs(t1, ["-a=1:2:3","-a","4"])); assert(t1 == T(["1:2:3","4"])); enum Config cfg = { valueSep: ':' }; T t2; assert(CLI!(cfg, T).parseArgs(t2, ["-a=1:2:3","-a","4"])); assert(t2 == T(["1","2","3","4"]));

Prefix for short argument name

Config.shortNamePrefix is a string that short names of arguments begin with.

Default is dash (-).

Example:

import argparse; struct T { string a; string baz; } enum Config cfg = { shortNamePrefix: "+", longNamePrefix: "==" }; T t; assert(CLI!(cfg, T).parseArgs(t, ["+a","foo","==baz","BAZZ"])); assert(t == T("foo","BAZZ"));

Prefix for long argument name

Config.longNamePrefix is a string that long names of arguments begin with.

Default is double dash (--).

Example:

import argparse; struct T { string a; string baz; } enum Config cfg = { shortNamePrefix: "+", longNamePrefix: "==" }; T t; assert(CLI!(cfg, T).parseArgs(t, ["+a","foo","==baz","BAZZ"])); assert(t == T("foo","BAZZ"));

Variadic named arguments

Config.variadicNamedArgument flag controls whether named arguments should be follow POSIX.1-2024 guidelines which allows only one value per named argument: -a value1 -a value2.

Setting this flag to true allows multiple values to be passed to a named argument: -a value1 value2.

Default is false.

Example:

import argparse; struct T { @NamedArgument int[] a; } { T t; assert(CLI!T.parseArgs(t, ["-a", "1", "-a", "2", "-a", "3"])); assert(t == T([1, 2, 3])); } { enum Config config = { variadicNamedArgument: true }; T t; assert(CLI!(config, T).parseArgs(t, ["-a", "1", "2", "3"])); assert(t == T([1, 2, 3])); }

End of named arguments

Config.endOfNamedArgs is a string that marks the end of all named arguments. All arguments that are specified after this one are treated as positional regardless to the value which can start with Config.shortNamePrefix or Config.longNamePrefix or be a subcommand.

Default is double dash (--).

Example:

import argparse; struct T { @NamedArgument string a; @PositionalArgument string b; @PositionalArgument string[] c; } enum Config cfg = { endOfNamedArgs: "---" }; T t; assert(CLI!(cfg, T).parseArgs(t, ["B","-a","foo","---","--","-a","boo"])); assert(t == T("foo","B",["--","-a","boo"]));

Case sensitivity

Config type hase three data members to allow fine-grained tuning of case sensitivity:

  • Config.caseSensitiveShortName to control case sensitivity for short argument names.

  • Config.caseSensitiveLongName to control case sensitivity for long argument names.

  • Config.caseSensitiveSubCommand to control case sensitivity for subcommands.

Default value for all of them is true.

Example:

import argparse; struct T { string[] param; string[] s; } enum Config cfg = { caseSensitiveShortName: false, caseSensitiveLongName: false }; T t; assert(CLI!(cfg, T).parseArgs(t, ["--param","1","--PARAM","2","--PaRaM","3","-s","a","-S","b"])); assert(t == T(["1","2","3"],["a","b"]));

Bundling of single-character arguments

Config.bundling controls whether single-character arguments (usually boolean flags) can be bundled together. If it is set to true then -abc is the same as -a -b -c.

Default is false.

Example:

import argparse; struct T { bool a; bool b; string c; } enum Config cfg = { bundling: true }; T t; assert(CLI!(cfg, T).parseArgs(t, ["-ab"])); assert(t == T(true, true)); assert(CLI!(cfg, T).parseArgs(t, ["-abc=foo"])); assert(t == T(true, true, "foo")); assert(CLI!(cfg, T).parseArgs(t, ["-a","-bc=foo"])); assert(t == T(true, true, "foo")); assert(CLI!(cfg, T).parseArgs(t, ["-a","-bcfoo"])); assert(t == T(true, true, "foo"));

Require subcommand

Config.requireSubCommand controls whether a subcommand is required in the command line. If it is set to true then parsing fails when a command that has subcommands got none of them in the command line:

Error: Subcommand is required: cmd1, cmd2

The following are not affected by this setting:

  • a command that has a default subcommand, because such command always has a subcommand chosen;

  • a subcommand member that is marked with @Optional UDA.

Default is false.

Example:

import argparse; struct cmd1 {} struct cmd2 {} struct T { SubCommand!(cmd1, cmd2) cmd; } enum Config cfg = { requireSubCommand: true }; T t; // parsing fails because no subcommand is provided in the command line assert(!CLI!(cfg, T).parseArgs(t, [])); assert(CLI!(cfg, T).parseArgs(t, ["cmd1"])); assert(t == T(typeof(T.cmd)(cmd1.init))); assert(CLI!(cfg, T).parseArgs(t, ["cmd2"])); assert(t == T(typeof(T.cmd)(cmd2.init)));

Adding help generation

Config.addHelpArgument can be used to add (if true) or not (if false) -h/--help argument. In case if the command line has -h or --help, then the corresponding help text is printed and the parsing is stopped. If CLI!(...).parseArgs(alias newMain) or CLI!(...).main(alias newMain) is used, then provided newMain function will not be called.

Default is true.

Example:

import argparse; struct T { string a, b; } T t1; CLI!T.parseArgs(t1, ["-a", "A", "-h", "-b", "B"]); assert(t1 == T("A")); enum Config cfg = { addHelpArgument: false }; T t2; string[] unrecognizedArgs; CLI!(cfg, T).parseKnownArgs(t2, ["-a", "A", "-h", "-b", "B"], unrecognizedArgs); assert(t2 == T("A","B")); assert(unrecognizedArgs == ["-h"]);

Help text from the first part of the example code above:

Config help example

Help on error

Config.helpOnError controls what is printed to stderr in front of the error message when command line parsing failed. It has the following type: enum HelpOnError { none, usage, full }:

  • Config.HelpOnError.none: nothing is printed, only the error message itself.

  • Config.HelpOnError.usage: the usage line is printed:

    Usage: prog sub --req REQ [-h] Error: The following argument is required: --req REQ Value that is required
  • Config.HelpOnError.full: the whole help screen is printed, the same one that -h/--help prints.

Whatever is printed belongs to the command that was being parsed when the error happened, so an error in a subcommand refers to that subcommand rather than to the top level command.

Config.helpPrinter is used for Config.HelpOnError.full only, since that is the setting that customizes the help screen. There is no such hook for the usage line.

Note that this setting is independent from Config.errorHandler: the latter receives the error message only, so providing a custom error handler does not suppress the usage line or the help screen.

Default is Config.HelpOnError.none.

Example:

import argparse; struct T { @(NamedArgument.Required) string a; } // Only the error message is printed (default) T t1; assert(CLI!T.parseArgs(t1, []).isError); // Usage line is printed to stderr in front of the error message enum Config cfgUsage = { helpOnError: Config.HelpOnError.usage }; T t2; assert(CLI!(cfgUsage, T).parseArgs(t2, []).isError); // The whole help screen is printed instead enum Config cfgFull = { helpOnError: Config.HelpOnError.full }; T t3; assert(CLI!(cfgFull, T).parseArgs(t3, []).isError);

Styling mode

Config.stylingMode controls whether styling for help text and errors should be enabled. It has the following type: enum StylingMode { autodetect, on, off }:

  • Config.StylingMode.on: styling is always enabled.

  • Config.StylingMode.off: styling is always disabled.

  • Config.StylingMode.autodetect: styling will be enabled when possible.

See ANSI coloring and styling for details.

Default value is Config.StylingMode.autodetect.

Example:

import argparse; struct T { string a, b; } enum Config cfg = { stylingMode: Config.StylingMode.off }; T t; CLI!(cfg, T).parseArgs(t, ["-a", "A", "-h", "-b", "B"]); assert(t == T("A"));

Help text from the first part of the example code above:

Config stylingMode example

Styling scheme

Config.styling contains style for the text output (error messages and help text). It has the following members:

  • programName: style for the program name. Default is bold.

  • subcommandName: style for the subcommand name. Default is bold.

  • argumentGroupTitle: style for the title of argument group. Default is bold.underline.

  • argumentName: style for the argument name. Default is lightYellow.

  • namedArgumentValue: style for the value of named argument. Default is italic.

  • positionalArgumentValue: style for the value of positional argument. Default is lightYellow.

  • errorMessagePrefix: style for Error: prefix in error messages. Default is red.

See ANSI coloring and styling for details.

Example:

import argparse; import argparse.ansi; struct T { string a, b; } enum Config cfg = { styling: { programName: blue, argumentName: green.italic } }; T t; CLI!(cfg, T).parseArgs(t, ["-a", "A", "-h", "-b", "B"]); assert(t == T("A"));

Help text from the first part of the example code above:

Config styling example

Help printer

Config.helpPrinter is a handler function to print help screen. It receives the following parameters:

  • Config config - config object that was provided to parsing API.

  • Style style - style that should be applied to help screen.

  • CommandHelpInfo[] cmds - current stack of (sub)commands starting with top-level command. For example, if command line contains tool subcmd1 subcmd2 -h then cmd will contain array of CommandHelpInfo objects that corresponds to tool, subcmd1, subcmd2 commands respectively.

Example:

import argparse; struct T { string a; } enum Config cfg = { helpPrinter: function (Config config, Style style, CommandHelpInfo[] cmds) { import std.stdio : stderr; scope auto output = stderr.lockingTextWriter(); new DefaultHelpPrinter(config, style).printHelp(_ => output.put(_), cmds); } }; T t; assert(!CLI!(cfg, T).parseArgs(t, ["-h"]));

Error handling

Config.errorHandler is a handler function for all errors occurred during command line parsing. It is a function that receives string parameter which would contain an error message.

Command line parsing can detect more than one error at a time, in which case the handler is called once per error message.

The default behavior is to print error message to stderr.

Example:

import argparse; struct T { string a; } enum Config cfg = { errorHandler: (text) { try { import std.stdio : stderr; stderr.writeln("Detected an error: ", text); } catch(Exception e) { throw new Error(e.msg); } } }; T t; assert(!CLI!(cfg, T).parseArgs(t, ["-b"]));

This code prints Detected an error: Unrecognized arguments: ["-b"] to stderr.

Error exit code

Config.errorExitCode holds and exit code in case of error.

Default value is 1.

Last modified: 11 September 2026