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 for key-value pairs

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 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 has 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!(...).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.

Both settings render through Config.helpPrinterFactory if it's set: full prints the whole help screen and usage prints only 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.helpPrinterFactory is a function that creates an object that renders help text. It receives the following parameters and returns an implementation of HelpPrinter interface:

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

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

  • void delegate(string) sink - where the created object should print help text to. argparse passes a different sink depending on what is printed: for example, stdout for -h and stderr for the usage line printed on error. The created object is expected to print to this sink: argparse also reads back from it the text that it embeds into error messages.

argparse calls this function every time it needs to format help text, so a single implementation is used for all of them: help screen, usage line printed on error and lists of arguments in error messages. The usual way to provide one is to derive from DefaultHelpPrinter and to override the functions that should behave differently - everything else keeps the standard behavior.

Default is null which means that DefaultHelpPrinter is used as is.

Example:

import argparse; // Custom help printer that puts every argument name in square brackets. // Only one function is overridden, yet it changes the help screen, the usage line and // the lists of arguments in error messages. static class MyHelpPrinter : DefaultHelpPrinter { this(const Config config, Style style, void delegate(string) sink) { super(config, style, sink); } override string formatArgumentUsage(in ArgumentHelpInfo helpInfo, bool usageString) { return "[" ~ super.formatArgumentUsage(helpInfo, usageString) ~ "]"; } } struct T { string a; } enum Config cfg = { helpPrinterFactory: (config, style, sink) => new MyHelpPrinter(config, style, sink) }; 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 an exit code in case of error.

Default value is 1.

Last modified: 25 September 2026