
Security News
Browserslist-rs Gets Major Refactor, Cutting Binary Size by Over 1MB
Browserslist-rs now uses static data to reduce binary size by over 1MB, improving memory use and performance for Rust-based frontend tools.
Supercharged argparse for Python
pip install -U argx
exit_on_void
: Exit with error if no arguments are providedparser.add_subparsers()
--foo.bar
as args.foo.bar
append
and extend
, the initial value is cleared.order
attribute to groups to change the order of groups in help messageargx
as a drop-in replacement for argparse
.exit_on_void
If all arguments are optional, argparse
will not raise an error if no arguments are provided. This is not always desirable. argx
provides the option exit_on_void
to change this behavior. If exit_on_void
is set to True
and no arguments are provided, argx
will exit with an error (No arguments provided).
import argx as argparse
parser = argparse.ArgumentParser(exit_on_void=True)
parser.add_argument('--foo', action='store_true')
args = parser.parse_args([])
# No arguments provided
# standard argparse produces: Namespace(foo=False)
argparse
requires to create subparsers first and then add the subcommands to the subparsers.
argx
allows to add subcommands directly to the main parser.
# standard argparse
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(title='subcommands')
parser_a = subparsers.add_parser('a')
parser_b = subparsers.add_parser('b')
# argx
parser = argparse.ArgumentParser()
parser.add_command('a') # or parser.add_subparser('a')
parser.add_command('b')
# args = parser.parse_args(['a'])
# Namespace(COMMAND='a')
The subparsers
is added automatically with the title subcommands
and the dest
is set to COMMAND
. You can add subcommands to subcommands directly, then the dest
is set to COMMAND2
, COMMAND3
, etc. If you want to change the behavior, you can always fall back to the standard argparse
way.
The values of arguments like --foo.bar
can be accessed as vars(args)['foo.bar']
. With argx
you can access them as args.foo.bar
.
The arguments --foo.bar
, --foo.baz
and --foo.qux
are automatically grouped in a namespace foo
.
import argx as argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo.bar', type=int)
parser.add_argument('--foo.baz', type=int)
parser.add_argument('--foo.qux', type=int)
parser.print_help()
Usage: test.py [-h] [--foo.bar BAR] [--foo.baz BAZ] [--foo.qux QUX]
Optional arguments:
-h, --help show this help message and exit
Namespace <foo>:
--foo.bar BAR
--foo.baz BAZ
--foo.qux QUX
You can modify the namespace by adding the namespace manually before adding the arguments.
import argx as argparse
parser = argparse.ArgumentParser()
parser.add_namespace('foo', title="Foo's options")
parser.add_argument('--foo.bar', type=int)
parser.add_argument('--foo.baz', type=int)
parser.add_argument('--foo.qux', type=int)
parser.print_help()
Usage: test.py [-h] [--foo.bar BAR] [--foo.baz BAZ] [--foo.qux QUX]
Optional Arguments:
-h, --help show this help message and exit
Foo's Options:
--foo.bar BAR
--foo.baz BAZ
--foo.qux QUX
You can also add a namespace action argument to take a json that can be parsed as a dict:
import argx as argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', action="namespace") # or action="ns"
parser.add_argument('--foo.bar', type=int)
parser.add_argument('--foo.baz', type=int)
parser.add_argument('--foo.qux', type=int)
parser.parse_args(['--foo', '{"bar": 1, "baz": 2, "qux": 3}', '--foo.qux', '4'])
# Namespace(foo=Namespace(bar=1, baz=2, qux=4))
If you have a lot of arguments, the help message can be very long. argx
allows to show only the most important arguments in the help message.
import argx as argparse
# Advanced help options to show the brief help message or the full help message
parser = argparse.ArgumentParser(add_help='h,help,h+,help+')
parser.add_argument('--foo', type=int)
parser.add_argument('--bar', type=int, show=False)
parser.parse_args(['--help'])
Usage: test.py [-h] [--foo FOO]
Optional Arguments:
-h, --help, -h+, --help+
show help message (with + to show more options) and exit
--foo FOO
With parser.parse_args(['--help+'])
you can show the full help message.
Usage: test.py [-h] [--foo FOO] [--bar BAR]
Optional Arguments:
-h, --help, -h+, --help+
show help message (with + to show more options) and exit
--foo FOO
--bar BAR
You can also set show=False
for argument groups.
With argparse
, the default value is not shown in the help message. With argx
, the default value is added to the help message automatically.
import argx as argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', type=int, default=1)
parser.add_argument('--bar', type=int, default=2, help='bar [default: two]')
parser.add_argument('--baz', type=int, default=3, help='baz [nodefault]')
parser.print_help()
Usage: test.py [-h] [--foo FOO]
Optional Arguments:
-h, --help show help message and exit
--foo FOO [default: 1]
--bar BAR bar [default: two]
--baz BAZ baz
By default, argparse
replaces the newlines with spaces in the argument help message. However, sometimes you want to keep the newlines. With argx
, if there is not newline, it is handled as the default behavior. If there is a newline, the newlines and spaces are kept.
import argx as argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', help='foo\n- bar\n indent also kept')
parser.print_help()
Usage: test.py [-h] [--foo FOO]
Optional Arguments:
-h, --help show this help message and exit
--foo FOO foo
- bar
indent also kept
With standard argparse
, when fromfile_prefix_chars
is set, the arguments can be read from a file. The file can be specified with @filename
. The arguments in the file are separated by newlines by default.
With argx
, Other than a text file to provide command line arguments, you can also provide other types of configuration files. The extension of the file can be .json
, .yaml
, .ini
, .env
or .toml
.
import argx as argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', type=int)
parser.add_argument('--bar', type=int)
parser.add_argument('--baz', type=int)
# config.json
# { "foo": 1, "bar": 2, "baz": 3 }
args = parser.parse_args(['@config.json'])
# Namespace(foo=1, bar=2, baz=3)
You can also use set_defaults_from_configs
method:
parser.set_defaults_from_configs('config.json')
The clear_append
/clear_extend
action is similar to append
and extend
, but the initial value is cleared.
This is useful when you want to accept a new list of values from the command line, instead of append/extend to the existing list or default.
import argx as argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', action='clear_append', default=[1, 2, 3], type=int)
parser.add_argument('--bar', action='append', default=[1, 2, 3], type=int)
args = parser.parse_args('--foo 4 --foo 5 --bar 4 --bar 5'.split())
# Namespace(foo=[4, 5], bar=[1, 2, 3, 4, 5])
By default, argparse
puts both required=True
and required=False
arguments in the same group (optional arguments), which is sometimes confusing. argx
groups required=True
arguments in a separate group (required arguments).
import argx as argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo')
parser.add_argument('--bar', required=True)
parser.print_help()
Usage: test.py [-h] [--foo FOO] --bar BAR
Required Arguments:
--bar BAR
Optional Arguments:
-h, --help show help message and exit
--foo FOO
Allow to add an order
attribute to groups to change the order of groups in help message
import argx as argparse
parser = argparse.ArgumentParser()
group1 = parser.add_argument_group('group1', order=2)
group1.add_argument('--foo')
group2 = parser.add_argument_group('group2', order=1)
group2.add_argument('--bar')
parser.print_help()
Usage: test.py [-h] [--bar BAR] [--foo FOO]
Optional arguments:
-h, --help show help message and exit
Group2:
--bar BAR
Group1:
--foo FOO
The order by default is 0. The groups with the same order are sorted by title. Groups with small numbers are displayed first. required arguments
has a order
of -1.
parser.add_argument()
accepts type
as a function to convert the argument value. It has to be a callable that accepts a single string argument and returns the converted value. While argx
supports string for type
so it can be configured in the configuration file. Builtin functions and types can also be specified by its name.
We also have additional types:
import argx as argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', type='py')
parser.add_argument('--bar', type='json')
parser.add_argument('--baz', type='path')
parser.add_argument('--qux', type='auto')
args = parser.parse_args(
'--foo 1 --bar {"a":1} --baz path/to/file --qux true'.split()
)
# Namespace(foo=1, bar={'a': 1}, baz=PosixPath('path/to/file'), qux=True)
py
: Python expression. The string is evaluated by ast.literal_eval
.json
: JSON string. The string is loaded by json.loads
.path
: Path string. The string is converted by pathlib.Path
.auto
: Automatic type conversion.
True
if the string is True/TRUE/true
False
if the string is False/FALSE/false
None
if the string is None/NONE/none
You can create the parser from a configuration file.
import argx as argparse
# config.json
# {
# "prog": "myprog",
# "arguments": [ {"flags": ["-a", "--abc"], "help": "Optiona a help"} ]
# }
parser = argparse.ArgumentParser.from_configs('config.json')
parser.print_help()
Usage: myprog [-h] [-a ABC]
Optional Arguments:
-h, --help show help message and exit
-a ABC, --abc ABC Optiona a help
You can get the actions of the parser by .get_action()
.
import argx
parser = argx.ArgumentParser()
parser.add_argument('--foo', type=int)
action = parser.get_action('foo')
# StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None,
# default=None, type=<class 'int'>, choices=None, required=False, help=None,
# metavar=None)
You can add a pre-parse hook to the parser. The hook is called before parsing the arguments. It can be used to modify the arguments before parsing.
import argx as argparse
def pre_parse(parser, args, namespace):
"""We can modify the parser (i.e. add arguments)
the arguments to be parsed, and even manipulate the namespace.
"""
parser.add_argument('--foo', type=int)
parser.add_argument('--bar', type=int)
namespace.baz = 2
return args + ["--bar", "3"]
parser = argparse.ArgumentParser()
parser.add_command('command1', pre_parse=pre_parse)
parsed = parser.parse_args('command1 --foo 1'.split())
# Namespace(COMMAND='command1', baz=2, foo=1, bar=3)
This is especially useful when you have a lot of subcommands and each has a lot of arguments, when it takes time to add these arguments, for example, some of the values need to be parsed from a file. Using this hook, you can add the arguments only when the subcommand is called, instead of adding them all at the beginning.
All features are optional. You can use argx
as a drop-in replacement for argparse
.
argx
supports python 3.7+
. Some of the later-introduced features are also supported in python 3.7. For example, extend
action is added in python 3.8, argx
supports in python 3.7.
FAQs
Super-charged argparse for python
We found that argx demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Browserslist-rs now uses static data to reduce binary size by over 1MB, improving memory use and performance for Rust-based frontend tools.
Research
Security News
Eight new malicious Firefox extensions impersonate games, steal OAuth tokens, hijack sessions, and exploit browser permissions to spy on users.
Security News
The official Go SDK for the Model Context Protocol is in development, with a stable, production-ready release expected by August 2025.