jsonargparse
Docs: https://jsonargparse.readthedocs.io/ | Source: https://github.com/mauvilsa/jsonargparse/
jsonargparse is a library for creating command-line interfaces (CLIs) and
making Python apps easily configurable. It is a well-maintained project with
frequent releases, adhering to high standards of development: semantic
versioning, deprecation periods, changelog, automated testing, and full test
coverage.
Although jsonargparse might not be widely recognized yet, it already boasts
a substantial user base. Most notably,
it serves as the framework behind pytorch-lightning’s LightningCLI.
The documentation is a reference that describes each feature in isolation, which is not always the best way to learn. If you would rather see the why behind the features and complete use cases built end to end, have a look at the talks and articles page, which collects presentations, blog posts and example projects.
Features
jsonargparse is user-friendly and encourages the development of clean,
high-quality code. It encompasses numerous powerful features, some unique to
jsonargparse, while also combining advantages found in similar packages:
Automatic creation of CLIs, like Fire, Typer, Clize and Tyro.
Use type hints for argument validation, like Typer, Tap and Tyro.
Use of docstrings for automatic generation of help, like Tap, Tyro and SimpleParsing.
Parse from configuration files and environment variables, like OmegaConf, dynaconf, confuse and configargparse.
Dataclasses support, like SimpleParsing and Tyro.
Other notable features include:
Extensive type hint support: nested types (union, optional), containers (list, dict, etc.), protocols, user-defined generics, restricted types (regex, numbers), paths, URLs, types from stubs (
*.pyi), future annotations (PEP 563), and backports (PEP 604).Keyword arguments introspection: resolving of parameters used via
**kwargs.Dependency injection: support types that expect a class instance and callables that return a class instance.
Structured configs: parse config files with more understandable non-flat hierarchies.
Config file formats: json, yaml, toml, jsonnet and extensible to more formats.
Relative paths: within config files and parsing of config paths referenced inside other configs.
Argument linking: directing parsed values to multiple parameters, preventing unnecessary interpolation in configs.
Variable interpolation: powered by OmegaConf.
Tab completion: powered by shtab or argcomplete.
Design principles
Non-intrusive/decoupled:
There is no requirement for unrelated modifications throughout a codebase, maintaining the separation of concerns principle. In simpler terms, changes should make sense even without the CLI. No need to inherit from a special class, add decorators, or use CLI-specific type hints.
Minimal boilerplate:
A recommended practice is to write code with function/class parameters having meaningful names, accurate type hints, and descriptive docstrings. Reuse these wherever they appear to automatically generate the CLI, following the don’t repeat yourself principle. A notable advantage is that when parameters are added or types changed, the CLI will remain synchronized, avoiding the need to update the CLI’s implementation.
Dependency injection:
Using as type hint a class or a callable that instantiates a class, a practice known as dependency injection, is a sound design pattern for developing loosely coupled and highly configurable software. Such type hints should be supported with minimal restrictions.
Installation
You can install using pip as:
pip install jsonargparse
By default, the only dependency installed with jsonargparse is PyYAML. However, several optional features can be
enabled by specifying one or more of the following extras (optional
dependencies): signatures, jsonschema, jsonnet, urls,
fsspec, toml, ruamel, omegaconf, shtab, and argcomplete.
Additionally, the all extras can be used to enable all optional features
(excluding tab completion ones). To install jsonargparse with extras, use
the following syntax:
pip install "jsonargparse[signatures,urls]" # Enable signatures and URLs features
pip install "jsonargparse[all]" # Enable all optional features
To install the latest development version, use the following command:
pip install "jsonargparse[signatures] @ https://github.com/mauvilsa/jsonargparse/zipball/main"
Basic usage
There are two ways of using jsonargparse. One is to build a parser step by step
(see Parsers), which is almost a drop-in replacement of argparse. But
argparse is verbose and duplicates information that the code already has. The
simpler and recommended way is the auto_cli() function, which builds the
parser from the signatures of the given functions and classes. For example:
from jsonargparse import auto_cli
def command(name: str, prize: int = 100):
"""Prints the prize won by a person.
Args:
name: Name of winner.
prize: Amount won.
"""
print(f"{name} won {prize}€!")
if __name__ == "__main__":
auto_cli(command)
The name and prize parameters have type hints and are described in the
docstring. Both are shown in the help. In a shell:
$ python example.py --help
...
Prints the prize won by a person:
name Name of winner. (required, type: str)
--prize PRIZE Amount won. (type: int, default: 100)
$ python example.py Lucky --prize=1000
Lucky won 1000€!
Note
Parsing of docstrings is optional. For the help to show the descriptions,
install jsonargparse with the signatures extra, see Installation.
Given a single class, the first arguments are the class init parameters, then comes a method name (methods become Subcommands), and then the parameters of that method:
from random import randint
from jsonargparse import auto_cli
class Main:
def __init__(self, max_prize: int = 100):
"""
Args:
max_prize: Maximum prize that can be awarded.
"""
self.max_prize = max_prize
def person(self, name: str):
"""
Args:
name: Name of winner.
"""
return f"{name} won {randint(0, self.max_prize)}€!"
if __name__ == "__main__":
print(auto_cli(Main))
In a shell:
$ python example.py --max_prize=1000 person Lucky
Lucky won 632€!
If the class has no public methods, there are no subcommands and
auto_cli() returns an instance of the class:
from dataclasses import dataclass
from jsonargparse import auto_cli
@dataclass
class Settings:
name: str
prize: int = 100
if __name__ == "__main__":
print(auto_cli(Settings, as_positional=False))
In a shell:
$ python example.py --name=Lucky
Settings(name='Lucky', prize=100)
Note the as_positional=False, which makes required arguments non-positional.
To get an instance even when the class does have public methods, use
return_instance=True. Then only the init arguments are parsed and no method
subcommands are added.
If several functions are given, each one becomes a subcommand, i.e. example.py
function [arguments]. If several classes are given, or a mix of classes and
functions, running a method needs two levels of subcommands, i.e. example.py
class [init_arguments] method [arguments].
A dict defines subcommands with custom names and any number of levels:
class Raffle:
def __init__(self, prize: int):
self.prize = prize
def __call__(self, name: str):
return f"{name} won {self.prize}€!"
components = {
"weekday": {
"_help": "Raffles for weekdays",
"tier1": Raffle(prize=100),
"tier2": Raffle(prize=50),
},
"weekend": {
"_help": "Raffles for weekends",
"tier1": Raffle(prize=300),
"tier2": Raffle(prize=75),
},
}
if __name__ == "__main__":
print(auto_cli(components))
In a shell:
$ python example.py weekend tier1 Lucky
Lucky won 300€!
Note
These examples only use str and int type hints. jsonargparse
supports a much wider range of types, see Type hints. Classes can
also be used as type hints, which makes configurable dependency injection
(object composition)
easy, see Class type and subclasses.
Writing configuration files
Tools created with auto_cli() have a --config option to give settings
in a config file (see Configuration files). This helps when there are
many parameters. The --print_config option prints all supported settings
with their default values, which is a good starting point:
# Dump default config to have as reference
python example.py --print_config > config.yaml
# Modify the config as needed (all default settings can be removed)
nano config.yaml
# Run the tool using the adapted config
python example.py --config config.yaml
Parsers
A parser is created just like with Python’s argparse: import the module, create a parser and add arguments to it.
from jsonargparse import ArgumentParser
parser = ArgumentParser(prog="app", description="Description for my app.")
parser.add_argument("--opt1", type=int, default=0, help="Help for option 1.")
parser.add_argument("--opt2", type=float, default=1.0, help="Help for option 2.")
parse_args returns an object with the
parsed values, or the defaults, as attributes. In the examples a list of
arguments is given to it, instead of taking them from the command line:
>>> cfg = parser.parse_args(["--opt2", "2.3"])
>>> cfg.opt1, type(cfg.opt1)
(0, <class 'int'>)
>>> cfg.opt2, type(cfg.opt2)
(2.3, <class 'float'>)
If parsing fails, by default the usage is printed and the program exits. With
exit_on_error=False an ArgumentError is raised instead.
Override order
Parsed values can come from several sources: the source code, command line arguments, Configuration files and Environment variables. Later sources in the following list override earlier ones:
Defaults defined in the source code.
Existing default config files in the order defined in
default_config_files, e.g.~/.config/myapp.yaml.Full config environment variable, e.g.
APP_CONFIG.Individual key environment variables, e.g.
APP_OPT1.Command line arguments in order left to right (might include config files).
Some of these sources might not apply, depending on the parse method used (see
ArgumentParser) and how the parser was built. Environment variables
must be enabled explicitly, except when using parse_env. Without an action="config" argument there is
no full config environment variable and no way to give a config file from the
command line.
Capturing parsers
A common pattern is a single function that builds a parser, possibly depending on some parameters, and then parses:
from jsonargparse import ArgumentParser
def main_cli():
parser = ArgumentParser()
...
cfg = parser.parse_args()
...
if __name__ == "__main__":
main_cli()
Sometimes the parser object is needed without parsing. For instance
sphinx-argparse
includes the help of CLIs in generated documentation, and requires a function
that returns the parser. capture_parser() provides it:
from jsonargparse import capture_parser
def get_parser():
return capture_parser(main_cli)
Note
For tools based on auto_cli(), the way to get the parser is
auto_parser(), a shorthand that calls capture_parser().
Optionals as positionals
Optional arguments can be accepted both by name, e.g. --key=val, and as
positional, e.g. val. Enable this with
set_parsing_settings(parse_optionals_as_positionals=True). Key points:
Only optionals that take exactly one value qualify, i.e. no
nargsornargs=1.Optionals with subclass types are excluded.
Extra positional values are assigned after the real positionals, in the order in which the optionals were added to the parser. The usage in the help shows which optionals accept this and in which order.
In a parser with subcommands, only the subparsers support this, after the subcommand name(s) are given.
For instance, for a parser defined as:
from jsonargparse import set_parsing_settings
set_parsing_settings(parse_optionals_as_positionals=True)
parser.add_argument("p1")
parser.add_argument("--o2")
parser.add_argument("--o3")
the help shows p1 [o2 [o3]] and a note saying that the feature is enabled.
Giving values by name still works, e.g. --o2=val2 --o3=val3 val1. Also valid
are --o3=val3 val1 val2 and val1 val2 val3.
Note
Positionals take precedence. If a value is given both ways, the positional
one is used, no matter the order. With the parser above, val1 val2a
--o2=val2b gives o2=val2a.
Always fail arguments
The ActionFail action adds an argument that always fails when given. A
use case is a feature that is only available if some package is installed:
from jsonargparse import ActionFail
if some_package_installed:
parser.add_argument("--module", type=SomeClass)
else:
parser.add_argument(
"--module",
action=ActionFail(message="install 'package' to enable %(option)s"),
help="Option unavailable due to missing 'package'",
)
Then giving --module=..., or a nested form like --module.child=...,
fails with the configured message. The message accepts the %(option)s and
%(value)s placeholders.
Unset values
By default jsonargparse follows argparse: an argument that is not given gets the
value None. This makes it impossible to tell apart an argument that was
explicitly set to None, e.g. --opt=null, from one that was simply not
given.
set_parsing_settings(unset_sentinel=True) solves this by using the
Unset sentinel as the default of the arguments that were not given a
default. An argument then has three possible states:
Unset– not given, andadd_argumentreceived nodefault.None– either explicitly set tonull, oradd_argumentreceiveddefault=None.Any other value – the given value, or the default.
Example:
from jsonargparse import ArgumentParser, Unset, set_parsing_settings
set_parsing_settings(unset_sentinel=True)
parser = ArgumentParser()
parser.add_argument("--num", type=int | None) # no default given
parser.add_argument("--flag", type=int | None, default=None) # explicit None
cfg = parser.parse_args([])
assert cfg.num is Unset # no default → Unset
assert cfg.flag is None # explicit default=None → None
cfg = parser.parse_args(["--num=null"])
assert cfg.num is None # explicitly set to null
cfg = parser.parse_args(["--num=5"])
assert cfg.num == 5 # provided value
The skip_unset parameter of dump, save and validate decides
whether Unset entries are excluded, and defaults to True. From the
command line the same is done with --print_config=skip_unset.
Relation to argument_default=SUPPRESS
Argparse’s argument_default=SUPPRESS, and the per-argument
default=SUPPRESS, are complementary: an argument that is not given is
completely absent from the namespace, i.e. it has no key at all. The two
features work well together and express different levels of absence.
Type hints
jsonargparse supports a wide range of argument types and validates values
against them, using Python’s type hint syntax. For example, an argument that
accepts None, a float in the range (0, 1), or a positive int:
from jsonargparse.typing import PositiveInt, OpenUnitInterval
parser.add_argument("--op", type=PositiveInt | OpenUnitInterval | None)
The types in jsonargparse.typing are a convenience for cases that
standard Python does not cover. Using them is not required.
Types can be nested with any complexity. Notes about the support:
Nested types, i.e. child types inside
list,dict, etc., work as long as at least one child type is supported. There is no limit in nesting depth.Supported PEPs: 563 postponed evaluation (
from __future__ import annotations), 585 (list[<type>]instead ofList[<type>]) and 604 (<type> | <type>instead ofUnion[<type>, <type>]).Types that use components imported inside
TYPE_CHECKINGblocks work, and so do forward references, including names defined only in the body of the class that owns the method, e.g. a nested class referred to without qualifying it.Fully supported types are:
str,bool(see Booleans),int,float,Decimal,complex,bytes/bytearray(Base64 encoding),range,list(see List append),Deque,Iterable,Sequence,MutableSequence,Collection,Container,Reversible,Any/object,Union/Optional(see Union types),Literal,Type,Enum,PathLike,UUID,timedelta, the restricted types of Restricted numbers and Restricted strings, and the path and URL types of Parsing paths and Parsing URLs.dict,Mapping,MutableMapping,MappingProxyType,OrderedDictandTypedDictare supported, but only withstrorintkeys, see Dict items.TypedDictacceptsRequiredandNotRequiredto mark single keys as required or optional, andUnpackto type**kwargsprecisely, see PEP 692. A--*.helpoption, e.g.--data.help, shows the accepted keys. It takes no value, unless theTypedDictis in a union with other types that have their own help, in which case the value is the name of the typed dict, e.g.--data.help SomeTypedDict.add_class_argumentsalso accepts aTypedDict, adding one argument per key and giving the corresponding dict oninstantiate. As the argument oftype, e.g.type[SomeTypedDict], the value is an import path to a class. SinceTypedDictclasses don’t supportissubclass, the given class is accepted when it is structurally compatible, as specified in PEP 589, i.e. it has all the expected keys with the same types and requiredness. A genericTypedDictworks both unsubscripted and subscripted, e.g.SomeDictandSomeDict[int], as does one that inherits from a subscripted one. Subscripting doesn’t change which keys are accepted, only the types of the keys annotated with aTypeVar. A key whose type can’t be validated accepts any value, see Unvalidated types.tuple,set,frozenset,AbstractSetandMutableSetare supported, even though on the command line, in config files and in environment variables they are all written as an array, like alist. Eachtupleposition can have its own type, which is validated as such, andtuple[type, ...]is also accepted. Asetorfrozensetof a class type is kept as a list when parsing, since subclass specs are not hashable, and becomes a set oninstantiate.Noneis written asnull, as JSON/YAML define it. For the same reason the help showsNoneTypeasnull, e.g. a parameter with type and defaultOptional[str] = Noneis shown astype: Union[str, null], default: null.Normal classes can be used as a type. The value is a dict with a
class_pathand optionallyinit_args, andinstantiateinstantiates all classes in a config object, see Class type and subclasses.Protocoltypes work the same as subclasses and don’t need to beruntime_checkable. An accepted class must implement all public methods of the protocol with a compatible signature, i.e. be callable in every way that the protocol’s methods can be called, like static type checkers verify. Parameter and return types must match exactly, subtypes are not accepted, except where the protocol has no annotation orAny, which accept any type. A generic protocol works both unsubscripted and subscripted, e.g.ProtoandProto[int]. Subscripting substitutes the type arguments in the protocol’s methods, soProto[int]andProto[str]accept different implementations. ATypeVarthat remains, in the protocol or in the implementation, matches any type, as static type checkers do. A protocol whose only method is__call__is also implemented by a function with a compatible signature, in which case the value is the function itself, instead of a class to instantiate.dataclasses, final classes, attrs’define, pydantic’sdataclassand pydantic’sBaseModelare supported, even when nested. By default they don’t accept subclasses, see Class types with subclasses disabled and Enable/disable subclasses. A dataclass that also inherits from a normal class does accept subclasses by default.User-defined
Generictypes are supported, see Generic types.Annotatedtypes are supported. If the metadata is a pydantic type, it is used for validation.pydantic.SecretStris supported and, as expected, the actual value is not serialized.jsonargparse.typing.SecretStrgives the same behavior without the pydantic dependency. Dumps only have the mask**********, and parsing this mask as a secret fails, so that a config bootstrapped with--print_configis not used with the mask as the secret.pydantic.FilePathandpydantic.DirectoryPathrun the corresponding pydantic validation when parsing. Arguments with these types also get file and directory tab completions, see Completion scripts.Callableaccepts either a dot import path to a callable object, or a dict withclass_pathand optionallyinit_args. The named class must either instantiate into a callable or be a subclass of the callable’s return type.instantiatethen gives the instance or a function that returns it, see Callable type. A function given by import path must have a return annotation, or a return type in a stub file (see Stubs resolver), that is the callable’s return type or a subclass of it. Argument types are not validated.types.ModuleTypeaccepts the dot import path of a module, and oninstantiateis replaced by the imported module object.types.UnionTypeandtypes.GenericAlias, commonly found in third party libraries in unions such astype | UnionType | dict, accept a string with a type expression, e.g."int | str"or"list[int]". The expression is resolved without evaluating code, so its names must be builtins,typingnames or dot import paths.TypeAliasTypeis supported. Values are parsed as the aliased type and the help shows the alias as the argument type. This includes aliases defined with the PEP 695type X = ...statement (Python 3.12+) and aliases created withtyping_extensions.TypeAliasType.
Union types
A value for an argument with a Union type is validated against each subtype,
one at a time, and the first subtype that accepts it decides the parsed value.
So the order of the subtypes matters. For example, for Union[str, int] the
command line value 2 is parsed as the str "2", since any command
line value is a valid str, whereas for Union[int, str] it is parsed as
the int 2.
Subtypes are mostly attempted in the order in which they are written. The exception are the ones that accept anything, which are moved to the end when the argument is added, so that the subtypes that do validate get a chance. From first to last attempted, the groups are:
All types not mentioned below, in the order in which they are written.
None, which only acceptsnull. It is placed second to last so thatOptional[<type>]reads in the help as it does in the source code.Any,objectand the types that can’t be validated, see Unvalidated types. These accept any value, so a subtype after them would never be attempted.
The sorting is stable, so subtypes in the same group keep their relative order.
Unions nested inside other types are sorted as well, e.g. the Union in
list[Union[int, Any]].
Be aware that typing considers two unions equal no matter the order of the
subtypes, and caches the types that it creates. So for a union nested in a
typing type, e.g. typing.List[Union[int, str]], the order can end up
being the one of an equal union created earlier somewhere else. PEP 585 types are not cached, so
list[Union[int, str]] always keeps the order as written.
The sorting happens when the argument is added, so the type shown in --help
is the sorted one. That is, the help always tells in which order the subtypes
are attempted. For example, an argument added as:
parser.add_argument("--val", type=Union[Any, int, None])
is shown in the help as (type: Union[int, null, Any], default: null) and
parses values as:
>>> parser.parse_args(["--val=2"])
Namespace(val=2)
>>> parser.parse_args(["--val=null"])
Namespace(val=None)
>>> parser.parse_args(["--val=abc"])
Namespace(val='abc')
In one case the order changes while parsing instead of when the argument is
added: when appending to a list, see List append, the subtypes that are a
list are moved to the front. This can only be decided when parsing, since it
depends on whether the value is appended to a previous list or replaces it. For
an argument of type Union[int, list[int]], --val=1 gives 1, while
--val+=1 gives [1].
Unvalidated types
A signature parameter or a TypedDict key
can have a type that jsonargparse can’t validate. The argument is still added,
with only the parts of the type that can’t be validated replaced by a type that
accepts any value. The help shows these parts as Unvalidated<...>, keeping
the name used in the source code. For example, a class with a parameter
items: list[SomeType] = [] for which SomeType can’t be validated is
shown in the help as:
--myclass.items ITEMS (type: list[Unvalidated<SomeType>], default: [])
Only these parts accept any value: in the example the value must still be a
list, and in a Union the other subtypes are still validated. A type or a
part of it can’t be validated when:
It failed to resolve, e.g. a missing import or a typo in a postponed annotation.
It is not a type that jsonargparse supports, e.g. a
TypeVarthat stands for nothing, see Generic types.
The debug log gives the reason for each part, see Troubleshooting and logging. A parameter
without a type annotation is shown as Untyped and behaves the same, see
Classes, methods and functions.
Since there is no type to serialize with, dump
and --print_config derive a type from the value itself. A value of a type
that jsonargparse doesn’t support, e.g. an arbitrary object, is serialized like
the instances given for a subclass type: as an import path
when it can be imported back, and otherwise as a message saying that it was not
serializable, together with a warning.
Parsing a dump back has no type to validate with either, so only the values that
the config formats represent round-trip, e.g. a set is dumped and parsed
back as a list, and an Enum member as its name. A warning is raised for each
dumped value that loses its type this way. All of the above applies equally to
Any and object.
Restricted numbers
Numbers often need a limited range. For the common cases jsonargparse.typing
has the predefined types PositiveInt, NonNegativeInt,
PositiveFloat, NonNegativeFloat,
ClosedUnitInterval and OpenUnitInterval, and the
restricted_number_type() function to define new ones:
from jsonargparse.typing import PositiveInt, PositiveFloat, restricted_number_type
# float larger than zero
parser.add_argument("--op1", type=PositiveFloat)
# between 0 and 10
from_0_to_10 = restricted_number_type("from_0_to_10", int, [(">=", 0), ("<=", 10)])
parser.add_argument("--op2", type=from_0_to_10)
Restricted strings
Likewise, restricted_string_type() creates string types restricted to
match a regular expression. The predefined ones are Email, which
follows the normal email pattern, and NotEmptyStr. For example, an
argument that must be exactly four uppercase letters:
from jsonargparse.typing import Email, restricted_string_type
CodeType = restricted_string_type("CodeType", "^[A-Z]{4}$")
parser.add_argument("--code", type=CodeType)
parser.add_argument("--email", type=Email)
Parsing paths
Parsing a file path often means checking that it exists and has the required
access permissions, without opening the file. Also, a path in a config file can
be relative to the location of that config file, and after parsing it should be
easy to use without having to think about where the config file was. For this
jsonargparse has the path_type() type generator and some predefined
types, e.g. Path_fr.
For example, suppose there is a directory with a config file app/config.yaml
and some data app/data/info.db. The YAML file contains:
# File: config.yaml
databases:
info: data/info.db
To check that databases.info is a file that exists and is readable:
from jsonargparse import ArgumentParser
from jsonargparse.typing import Path_fr
parser = ArgumentParser()
parser.add_argument("--databases.info", type=Path_fr)
cfg = parser.parse_path("app/config.yaml")
The fr in the type name are flags standing for file and readable. After
parsing, databases.info is a Path_fr instance, which gives both
the original relative path from the YAML file and the absolute path:
>>> cfg.databases.info.relative
'data/info.db'
>>> cfg.databases.info.absolute
'/.../app/data/info.db'
Directories work the same, e.g. Path_dw requires a directory that
exists and is writable. New path types are created with path_type(), e.g.
Path_frw = path_type('frw') for files that must exist and be both readable
and writable. If app/config.yaml is not writable, then
Path_frw('app/config.yaml') raises a PathError (a subclass of
TypeError) saying that the file is not writable. All supported mode flags
are documented in the Path class.
Types created with path_type() have Path as base class. This
class implements the os.PathLike protocol, using the absolute path, so for
the previous example:
>>> os.fspath(cfg.databases.info)
'/.../app/data/info.db'
The content of the file is read with the Path.read_text() method, e.g.
info_db = cfg.databases.info.read_text().
An argument with a path type can be given nargs='+' to accept multiple
paths, i.e. --files file1 file2. To instead read a list of paths from a
plain text file or from stdin, add the argument with type list[<path_type>]
and sub_configs=True. The special string '-' means stdin:
from jsonargparse.typing import Path_fr
parser.add_argument("--list", type=list[Path_fr], sub_configs=True)
cfg = parser.parse_args(["--list", "paths.lst"]) # File with list of paths
cfg = parser.parse_args(["--list", "-"]) # List of paths from stdin
Without nargs, the argument expects a single value. So giving several paths
directly on the command line requires the YAML/JSON array syntax, i.e. --list
"[file1,file2]", or the simpler append syntax of List append, i.e.
--list+ file1 --list+ file2. Not as short as nargs='+', but with tab
completion the effort is minimal.
The same list[<path_type>] behavior applies to arguments created
automatically from type hints in signatures, i.e. with auto_cli(),
add_function_arguments,
add_method_arguments,
add_class_arguments and
add_subclass_arguments.
Note
Setting both nargs='+' and sub_configs=True for an argument of type
list[<path_type>] makes each given value produce a list of paths, which
might not be what you expect.
Note
Not all features of the Path class are supported on Windows.
Parsing URLs
path_type() also supports URLs, with the 'u' flag, and fsspec file systems, with the 's' flag.
These need the requests and fsspec packages, which are installed with the
urls and fsspec extras, see Installation.
For example, an argument that accepts either a readable file or a URL uses the
type Path_fur = path_type('fur'). If the value looks like a URL, a HEAD
request checks that it is accessible. The Path.read_text() method then
gets the content, doing a GET request for a URL, so the code does not need to
care whether the value is a local file or a URL.
set_parsing_settings(config_read_mode_urls_enabled=True) and
set_parsing_settings(config_read_mode_fsspec_enabled=True) extend this to
config files, that is to parse_path,
get_defaults (default_config_files
argument), action="config", FromConfigMixin.from_config(),
ActionJsonSchema, ActionJsonnet and ActionParser.
So a tool that takes a config file can also get it from a URL:
my_tool.py --config http://example.com/config.yaml
Note
Relative paths inside a remote path are parsed as remote. For example, for a
relative path model/state_dict.pt found inside
s3://bucket/config.yaml, its parsed absolute path becomes
s3://bucket/model/state_dict.pt.
Booleans
Boolean arguments are very common, but argparse only supports them through
store_true and store_false. Users new to argparse often write
type=bool, which in argparse does not do what they expect.
In jsonargparse type=bool does the expected thing: the values true and
yes parse as True, and false and no as False. For example:
>>> parser.add_argument("--op1", type=bool, default=False)
>>> parser.add_argument("--op2", type=bool, default=True)
>>> parser.parse_args(["--op1", "yes", "--op2", "false"])
Namespace(op1=True, op2=False)
Two paired options, one to set True and the other to set False, are
added with ActionYesNo:
from jsonargparse import ActionYesNo
# --op1 for true and --no_op1 for false.
parser.add_argument("--op1", action=ActionYesNo)
# --with-op2 for true and --without-op2 for false.
parser.add_argument("--with-op2", action=ActionYesNo(yes_prefix="with-", no_prefix="without-"))
With nargs='?' these options also accept a value of true, yes,
false or no.
Enum arguments
String choices are another case of restricted values. Besides the usual
choices list, an Enum class can be given as type, which has the benefit
of mapping each string to a desired value:
>>> import enum
>>> class MyEnum(enum.Enum):
... choice1 = -1
... choice2 = 0
... choice3 = 1
...
>>> parser.add_argument("--op", type=MyEnum)
>>> parser.parse_args(["--op=choice1"])
Namespace(op=<MyEnum.choice1: -1>)
List append
By default a new value replaces the previous one, also for lists. So
parser.parse_args(['--list=[1]', '--list=[2, 3]']) gives [2, 3]. To
append instead of replace, add + as suffix to the argument name:
>>> parser.add_argument("--list", type=list[int])
>>> parser.parse_args(["--list=[1]", "--list+=[2, 3]"])
Namespace(list=[1, 2, 3])
>>> parser.parse_args(["--list=[4]", "--list+=5"])
Namespace(list=[4, 5])
Config files support this too. The following two files first assign a list and then append to it:
# config1.yaml
list:
- 1
# config2.yaml
list+:
- 2
- 3
Appending works for any element type. When the type is a union that has a list
among its subtypes, appending changes the order in which the subtypes are
attempted, see Union types. Lists of class types (see Class type and subclasses)
also work: first append the class with the + suffix, then give its
init_args as if the type were not a list, since they apply to the last class
in the list. For example, for an argument added as:
parser.add_argument("--list_of_instances", type=list[MyBaseClass])
Thanks to the short notation, class_path and init_args can be omitted,
so several classes are appended and configured as:
python tool.py \
--list_of_instances+={CLASS_1_PATH} \
--list_of_instances.{CLASS_1_ARG_1}=... \
--list_of_instances.{CLASS_1_ARG_2}=... \
--list_of_instances+={CLASS_2_PATH} \
--list_of_instances.{CLASS_2_ARG_1}=... \
...
--list_of_instances+={CLASS_N_PATH} \
--list_of_instances.{CLASS_N_ARG_1}=... \
...
Once a new class is appended, the arguments of a previous class can no longer be changed. This limitation is intentional: it forces classes and their arguments to be given in order, which makes the command line easier to write and to read.
Dict items
An argument of type dict accepts a value in JSON format:
>>> parser.add_argument("--dict", type=dict)
>>> parser.parse_args(['--dict={"key1": "val1", "key2": "val2"}'])
Namespace(dict={'key1': 'val1', 'key2': 'val2'})
As with lists, a second JSON dict replaces the previous value completely. Single items are set without replacing as:
>>> parser.parse_args(["--dict.key1=val1", "--dict.key2=val2"])
Namespace(dict={'key1': 'val1', 'key2': 'val2'})
Generic types
Classes that inherit from typing.Generic, i.e. user-defined generic types,
are supported. For example, a point in 2D:
from typing import Generic, TypeVar
Number = TypeVar("Number", float, complex)
@dataclass
class Point2d(Generic[Number]):
x: Number = 0.0
y: Number = 0.0
Parsing complex-valued points:
>>> parser.add_argument("--point", type=Point2d[complex])
>>> parser.parse_args(["--point.x=(1+2j)"]).point
Namespace(x=(1+2j), y=0.0)
A TypeVar can’t be used to validate, so when it is used as a type, e.g.
options: Optional[OptionsT] = None, it is replaced by what it stands for:
its PEP 696 default, its constraints or its bound, in that order. Any of
these given as a forward reference, e.g. TypeVar("OptionsT",
default="Options[int]"), is resolved with the names of the module in which the
TypeVar is defined. When the TypeVar has none of these, or the forward
reference fails to resolve, the value is accepted without validation and the
help shows it as Unvalidated<...>.
Callable type
A Callable type accepts several kinds of value. The first is the import path
of a callable object:
parser.add_argument("--callable", type=Callable)
parser.parse_args(["--callable=time.sleep"])
The second is a class whose instances are callable:
class OffsetSum:
def __init__(self, offset: int):
self.offset = offset
def __call__(self, value: int):
return self.offset + value
>>> value = {
... "class_path": "__main__.OffsetSum",
... "init_args": {
... "offset": 3,
... },
... }
>>> cfg = parser.parse_args(["--callable", str(value)])
>>> cfg.callable
Namespace(class_path='__main__.OffsetSum', init_args=Namespace(offset=3))
>>> init = parser.instantiate(cfg)
>>> init.callable(5)
8
The third only applies when the callable returns class instances. It is a form of Dependency injection, explained in Instance factories.
Registering types
register_type() adds new types for use in parsers. If the class can be
created from a string representation, and str of an instance gives that
representation back, only the class is needed. This is how
jsonargparse.typing registers complex numbers, register_type(complex),
which is the same as register_type(complex, serializer=str,
deserializer=complex). Other classes need a serializer and/or a deserializer,
for example datetime:
from datetime import datetime
from jsonargparse import ArgumentParser
from jsonargparse.typing import register_type
def serializer(v):
return v.isoformat()
def deserializer(v):
return datetime.strptime(v, "%Y-%m-%dT%H:%M:%S")
register_type(datetime, serializer, deserializer)
parser = ArgumentParser()
parser.add_argument("--datetime", type=datetime)
parser.parse_args(["--datetime=2008-09-03T20:56:35"])
Registering an already registered type replaces the previous one, jsonargparse’s
own registrations included. A debug log names the module of each, useful when
two packages register the same type. Give fail_already_registered=True to
fail instead. A generic class is registered unsubscripted, and the registration
also applies to its subscripted forms, e.g. os.PathLike[str]. The type
arguments are not validated, since the deserializer gets the complete value.
Note
Registering is only intended for simple types. By default, any class used as
a type hint is treated as a subclass type (see Class type and subclasses), which
suits many use cases. Registering a class with register_type()
removes that option.
Creating custom types
New types can be created and used for parsing. Even when a type is meant for a CLI, it is better to design it so that it also makes sense outside of parsing, i.e. as a type hint in functions and classes that improves the code in general. An alternative is to use pydantic types.
The simplest way is to implement a class. Take a basic type such as int as
reference. Basic types have these properties:
Casting a string creates an instance of the type, if the value is valid, e.g.
int("1").Casting a string raises a
ValueError, if the value is not valid, e.g.int("a").Casting an instance of the type to string gives back the string representation of the value, e.g.
str(1) == "1".Types are idempotent, i.e. casting an instance of the type to the type gives back the same value, e.g.
int(1) == int(int(1)).
A new type is registered with register_type(). If it follows the
properties above, register_type(MyType) is enough. extend_base_type()
creates and registers a type in a single call, for example for even integers:
from jsonargparse.typing import extend_base_type
def is_even(class_type, value):
if int(value) % 2 != 0:
raise ValueError(f"{value} is not even")
EvenInt = extend_base_type("EvenInt", int, is_even)
Then in a parser:
>>> parser = ArgumentParser()
>>> parser.add_argument("--even_int", type=EvenInt)
>>> parser.parse_args(["--even_int=2"])
Namespace(even_int=2)
When a custom type is used as a type hint, the default must be cast to it so that static type checkers don’t complain:
def fn(value: EvenInt = EvenInt(2)):
...
Nested namespaces
Unlike in argparse, dot notation in the argument names defines a hierarchy of nested namespaces:
>>> parser = ArgumentParser(prog="app")
>>> parser.add_argument("--lev1.opt1", default="from default 1")
>>> parser.add_argument("--lev1.opt2", default="from default 2")
>>> cfg = parser.get_defaults()
>>> cfg.lev1.opt1
'from default 1'
>>> cfg.lev1.opt2
'from default 2'
A dataclass creates a group of nested options, with the advantage that the same options can be reused in several places of a project. The analogous example is:
from dataclasses import dataclass
@dataclass
class Level1Options:
"""Level 1 options
Args:
opt1: Option 1
opt2: Option 2
"""
opt1: str = "from default 1"
opt2: str = "from default 2"
parser = ArgumentParser()
parser.add_argument("--lev1", type=Level1Options, default=Level1Options())
The Namespace class extends the argparse one. Keys can be accessed
like in a dictionary, either one level at a time, e.g. cfg['lev1']['opt1'],
or all at once, e.g. cfg['lev1.opt1']. The Namespace.as_dict()
method gives the nested namespace as a nested dictionary.
Configuration files
jsonargparse can parse configuration files (config files). The dot notation
hierarchy of the arguments (see Nested namespaces) defines the structure
expected in these files. The default format is YAML. To change it, use the
parser_mode parameter of the parser, e.g.
ArgumentParser(parser_mode="toml").
The ArgumentParser.default_config_files property holds patterns of
config files to search for, e.g.
ArgumentParser(default_config_files=['~/.myapp.yaml', '/etc/myapp.yaml']).
All matching files are parsed in the given order and override the defaults from
the source code. They are always parsed first, so any command line argument
overrides their values.
An argument can also be added to give a config file path explicitly. This does
not disable default_config_files. The config argument is parsed at its
position among the command line arguments, so arguments after it override the
values from that config file. It can be given several times, each one overriding
the previous. Using the example parser from Nested namespaces, a config
file in YAML format could be:
# File: example.yaml
lev1:
opt1: from yaml 1
opt2: from yaml 2
Adding a config file argument and parsing some arguments then gives:
>>> from jsonargparse import ArgumentParser
>>> parser = ArgumentParser()
>>> parser.add_argument("--lev1.opt1", default="from default 1")
>>> parser.add_argument("--lev1.opt2", default="from default 2")
>>> parser.add_argument("--config", action="config")
>>> cfg = parser.parse_args(["--lev1.opt1", "from arg 1", "--config", "example.yaml", "--lev1.opt2", "from arg 2"])
>>> cfg.lev1.opt1
'from yaml 1'
>>> cfg.lev1.opt2
'from arg 2'
The value can also be a string with the config content, instead of a path:
>>> cfg = parser.parse_args(["--config", '{"lev1":{"opt1":"from string 1"}}'])
>>> cfg.lev1.opt1
'from string 1'
The config file can also come from an environment variable, see Environment variables. This variable is parsed first, so any other argument given through an environment variable overrides it.
To parse a config file or a config string without parsing command line
arguments, use parse_path or
parse_string.
Serialization
Parsers that have an action="config" argument also get a --print_config
option. It is useful for tools with many options, to create an initial config
file with all default values. The option accepts one or more flags separated by
comma, e.g. --print_config=comments,skip_default:
comments: add the help descriptions as YAML comments. Requires the ruamel.yaml package. The comments are the descriptions of the groups and arguments of the parser and, for values that correspond to a class, e.g. theinit_argsof a subclass or the fields of a dataclass, the descriptions from that class.skip_default: skip entries whose value is the same as the default.skip_unset: skip entries that were not given a value, see Unset values.
From Python, a config object is serialized with the dump and save methods. The
supported formats are yaml, toml, json/json_compact,
json_indented and parser_mode, the default, which uses the format of the
parser. More formats are added with set_dumper(), for example to dump
with PyYAML’s default_flow_style:
import yaml
from jsonargparse import set_dumper
def custom_yaml_dump(data):
return yaml.safe_dump(data, default_flow_style=True)
set_dumper("yaml_custom", custom_yaml_dump)
Custom loaders
The yaml parser mode (see ArgumentParser.__init__()) loads with a
subclass of yaml.SafeLoader that has three
differences:
Float scientific notation is supported, e.g.
'1e-3'gives0.001, while default PyYAML gives the string'1e-3'.Dates are kept as strings, e.g.
'2020-01-01', while default PyYAML gives adatetime.date.Text that looks like a mapping only because of the syntax is kept as a string, e.g.
'{text}'and'name:', while default PyYAML gives{'text': None}and{'name': None}.
The set_loader() function replaces the yaml loader or adds a loader
as a new parser mode. For example, a custom PyYAML loader is registered and used
as:
import yaml
from jsonargparse import ArgumentParser, set_loader
class CustomLoader(yaml.SafeLoader):
...
def custom_yaml_load(stream):
return yaml.load(stream, Loader=CustomLoader)
set_loader("yaml_custom", custom_yaml_load)
parser = ArgumentParser(parser_mode="yaml_custom")
When the loader is based on a library other than PyYAML, give the exceptions
that it raises on failure to set_loader().
Classes, methods and functions
Well written Python code gives type hints to its parameters and describes them
in the docstrings. Making such code configurable should not duplicate the types
and the descriptions. To avoid this, jsonargparse adds annotated parameters as
arguments automatically, see add_function_arguments, add_method_arguments, add_class_arguments and add_subclass_arguments.
Take for example a class with an init and a method with docstrings:
class MyClass(MyBaseClass):
def __init__(self, foo: dict[str, int | list[int]], **kwargs):
"""Initializer for MyClass.
Args:
foo: Description for foo.
"""
super().__init__(**kwargs)
...
def mymethod(self, bar: float, baz: bool = False):
"""Description for mymethod.
Args:
bar: Description for bar.
baz: Description for baz.
"""
...
Both MyClass and mymethod are made configurable, the class instantiated
and the method run, as follows:
from jsonargparse import ArgumentParser
parser = ArgumentParser()
parser.add_class_arguments(MyClass, "myclass.init")
parser.add_method_arguments(MyClass, "mymethod", "myclass.method")
cfg = parser.parse_args()
myclass = MyClass(**cfg.myclass.init.as_dict())
myclass.mymethod(**cfg.myclass.method.as_dict())
The add_class_arguments call adds
myclass.init.foo, with the description from the docstring, and makes it
required since it has no default. When parsed, it is validated against its type
hint, i.e. a dict whose values are ints or lists of ints. Since the init has
**kwargs, the keyword arguments of MyBaseClass are added too. Likewise,
the add_method_arguments call
adds myclass.method.bar as a required float and myclass.method.baz as an
optional boolean with default false.
Several classes added with add_class_arguments are instantiated at once with
instantiate. In the example above, cfg =
parser.instantiate(cfg) makes cfg.myclass.init an instance of MyClass,
built from the parsed arguments.
All values can be given in a single config file (see Configuration files). For convenience, the values of each argument group created by an add signature method can also come from its own file. For the example above, a general config file could be:
myclass:
init: myclass.yaml
method: mymethod.yaml
Then myclass.yaml and mymethod.yaml hold the settings for the class
instantiation and for the method call.
A wide range of type hints is supported for signature parameters, see Type hints. Notes about the add signature methods:
A parameter without a type annotation, or with a type that can only be validated in part, is added with a type that accepts any value, see Unvalidated types. Without an annotation but with a default, the type is
Union[<type of the default>, Untyped], i.e. a value is converted to the default’s type when it accepts it.fail_untypeddecides which parameters without a type annotation raise an exception instead: the required ones with the defaultTrue, all of them with"all", and none withFalse. Positional-only parameters are always required. Use"all"only for code you own, since one untyped parameter of a dependency would make its signature impossible to add.Parameters whose name starts with
_are considered internal and skipped, unless they are required.The
skipparameter excludes arguments, e.g.parser.add_method_arguments(MyClass, 'mymethod', skip={'baz'}).
Note
The signatures support is intended to be non-intrusive. By design there is no need to inherit from a class, add decorators, or use special type hints and default values. Among other advantages, this makes it possible to use classes from third party libraries, which developers can’t modify.
From config mixin
FromConfigMixin adds a from_config class method, so that a class
can be instantiated directly from configuration values. It is useful for small
utilities that load constructor values from a dictionary or a config file in a
single call.
>>> from jsonargparse import FromConfigMixin
>>> class Client(FromConfigMixin):
... def __init__(self, host: str = "localhost", port: int = 80):
... self.host = host
... self.port = port
>>> client = Client.from_config({"host": "api.local", "port": 8080})
>>> (client.host, client.port)
('api.local', 8080)
See FromConfigMixin in the API reference for the complete behavior.
Docstring parsing
Parameter descriptions in the help require the docstring-parser package, which is included in
the signatures extra, see Installation.
Two options can be configured, both related to parsing speed. By default the
style is docstring_parser.DocstringStyle.AUTO, which tries all supported
styles. If the codebase uses a single style, setting it is faster:
from docstring_parser import DocstringStyle
from jsonargparse import set_parsing_settings
set_parsing_settings(docstring_parse_style=DocstringStyle.REST)
The second option is support for attribute docstrings, i.e. literal strings in the line after an attribute is defined. It is disabled by default, because enabling it makes parsing slower even for classes that have none:
from dataclasses import dataclass
from jsonargparse import set_parsing_settings
set_parsing_settings(docstring_parse_attribute_docstrings=True)
@dataclass
class Options:
"""Options for a competition winner."""
name: str
"""Name of winner."""
prize: int = 100
"""Amount won."""
Docstrings are searched in the entire class inheritance chain. So inherited
parameters and attributes are documented in the help by the base class that
declares them, and the description of a group comes from the nearest class in
the method resolution order that has a docstring. Base classes that only provide
machinery, i.e. object, abc.ABC, typing.Generic, enum.Enum,
pydantic.BaseModel and the like, are skipped, since their docstrings
describe themselves instead of the class being added to the parser.
Customization of arguments
Arguments added automatically from signatures give the developer limited control
over their behavior. To customize them, subclass the parser and override the
add_argument method. For example,
bool arguments need a true|false value on the command line. To use
ActionYesNo instead, in a CLI based on auto_cli():
from jsonargparse import ActionYesNo, ArgumentParser, auto_cli
class CustomArgumentParser(ArgumentParser):
def add_argument(self, *args, **kwargs):
if "type" in kwargs and kwargs["type"] == bool:
kwargs.pop("type")
kwargs["action"] = ActionYesNo
return super().add_argument(*args, **kwargs)
def main_function(flag: bool = False):
...
if __name__ == "__main__":
auto_cli(main_function, parser_class=CustomArgumentParser)
Classes from functions
Some functions return an instance of a class. class_from_function() turns
such a function into a class that can be added to a parser, so that
instantiate calls the function:
from jsonargparse import ArgumentParser
from jsonargparse.typing import class_from_function
parser = ArgumentParser()
dynamic_class = class_from_function(instantiate_myclass)
parser.add_class_arguments(dynamic_class, "myclass.init")
Note
class_from_function() requires the function to have a return type
annotation, which must be the class that it returns.
Classes created with class_from_function() can be selected using
class_path for Class type and subclasses. For example, if
class_from_function() is run in a module my_module as:
class_from_function(instantiate_myclass, name="MyClass")
Then the class_path of the created class is my_module.MyClass.
Parameter resolvers
There are three techniques for resolving signature parameters. The AST resolver,
which uses Python’s Abstract Syntax Trees (AST) library, is tried first. The
assumptions resolver, based on assumptions about class inheritance, is the
fallback for when AST fails. The stubs resolver, which uses *.pyi stub
files, is applied on top of both.
Unresolved parameters
The resolvers make a best effort to find the correct names and types that the
parser should accept. Some cases are not supported yet, and some would be
impossible to support. For these there is the special dict_kwargs key, whose
entries are not validated when parsing but are used for class instantiation. The
name comes from the use cases in which **kwargs is only used as a dict, a
purpose that it also serves.
This section is about parameters whose name the resolvers can’t determine. For parameters that are resolved but have a type that can’t be validated, see Unvalidated types.
Take for example the following parsing and instantiation:
from jsonargparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument("--myclass", type=MyClass)
cfg = parser.parse_args()
cfg_init = parser.instantiate(cfg)
If MyClass.__init__ has **kwargs with some unresolved parameters, the
following could be a valid config file:
class_path: MyClass
init_args:
foo: 1
dict_kwargs:
bar: 2
The value for bar is not validated, but the class is instantiated as
MyClass(foo=1, bar=2).
Assumptions resolver
The assumptions resolver only considers classes. When __init__ has *args
and/or **kwargs, it assumes that these go directly to the parent class, i.e.
that __init__ has a line like super().__init__(*args, **kwargs), and
blindly collects the __init__ parameters of the parent classes. If the code
does not follow this pattern, the collected parameters are wrong. This is why it
is only a fallback for when the AST resolver fails.
AST resolver
The AST resolver reads the source code and works out how *args and
**kwargs are used, so as to find more accepted parameters. Since code can do
endless things, only a few specific cases are supported, illustrated below. The
code does not need to look exactly like this. What matters is how *args and
**kwargs are used, not the other parameters, the names of the variables, or
the complexity of unrelated code.
Cases for statements in functions or methods
def calls_a_function(*args, **kwargs):
a_function(*args, **kwargs)
def calls_a_method(*args, **kwargs):
an_instance = SomeClass()
an_instance.a_method(*args, **kwargs)
def calls_a_static_method(*args, **kwargs):
an_instance = SomeClass()
an_instance.a_static_method(*args, **kwargs)
def calls_a_class_method(*args, **kwargs):
SomeClass.a_class_method(*args, **kwargs)
def calls_local_import(**kwargs):
import some_module
some_module.a_callable(**kwargs)
def calls_nested_module_attr(**kwargs):
import some_module
some_module.nested.a_callable(**kwargs)
def pops_from_kwargs(**kwargs):
val = kwargs.pop("name", "default")
def gets_from_kwargs(**kwargs):
val = kwargs.get("name", "default")
def constant_conditional(**kwargs):
if global_boolean_1:
first_function(**kwargs)
elif not global_boolean_2:
second_function(**kwargs)
else:
third_function(**kwargs)
Cases for classes
class PassThrough(BaseClass):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
class CallMethod:
def __init__(self, *args, **kwargs):
self.a_method(*args, **kwargs)
class AttributeUseInMethod:
def __init__(self, **kwargs):
self._kwargs = kwargs
def a_method(self):
a_callable(**self._kwargs)
class AttributeUseInProperty:
def __init__(self, **kwargs):
self._kwargs = kwargs
@property
def a_property(self):
return a_callable(**self._kwargs)
class DictUpdateUseInMethod:
def __init__(self, **kwargs):
self._kwargs = dict(p1=1) # Can also be: self._kwargs = {'p1': 1}
self._kwargs.update(**kwargs) # Can also be: self._kwargs = dict(p1=1, **kwargs)
def a_method(self):
a_callable(**self._kwargs)
class InstanceInClassmethod:
@classmethod
def get_instance(cls, **kwargs):
return cls(**kwargs)
class NonImmediateSuper(BaseClass):
def __init__(self, *args, **kwargs):
super(BaseClass, self).__init__(*args, **kwargs)
Cases for class instance defaults
# Class instance: only keyword arguments with ``ast.Constant`` value
class_instance: SomeClass = SomeClass(param=1)
# Lambda returning class instance: only keyword arguments with ``ast.Constant`` value
class_instance: Callable[[type], BaseClass] = lambda a: ChildClass(a, param=2.3)
There can be other parameters besides *args and **kwargs, so the
signatures above could be e.g. name(p1: int, k1: str = 'a', **kws). The
internal call can also have extra parameters, for example:
def calls_a_function(*args, **kwargs):
a_function(*args, param=1, **kwargs)
param is excluded from the resolved parameters, because it is hard coded.
Multiple calls that use **kwargs are supported, but with caveats:
def conditional_calls(**kwargs):
if condition_1:
first_function(**kwargs)
elif condition_2:
second_function(**kwargs)
else:
third_function(**kwargs)
Parameters that have the same type hint and default in all calls behave
normally. When the calls disagree, the help shows the default as
Conditional<ast-resolver> {DEFAULT_1, ...}. The main difference is that
these parameters are not included in get_defaults or in the output of --print_config. This is
needed because the parser does not know which call will happen at runtime, and
including them would make instantiate fail
with unexpected keyword arguments.
Note
The resolvers log failures and unsupported cases. To see these logs, set the
environment variable JSONARGPARSE_DEBUG to true. The supported cases
are limited, so please create issues asking for new ones. Note though that a
very convoluted case can be a sign that the code needs refactoring.
Stubs resolver
The stubs resolver uses the typeshed-client package to find parameters and
their type hints in stub files *.pyi. To enable it, install jsonargparse
with the signatures extra, see Installation.
Most of the Python standard library has its types in stubs, for example:
>>> from random import uniform
>>> parser = ArgumentParser()
>>> parser.add_function_arguments(uniform, "uniform")
>>> parser.parse_args(["--uniform.a=0.7", "--uniform.b=3.4"])
Namespace(uniform=Namespace(a=0.7, b=3.4))
Without the stubs resolver, that add_function_arguments call needs fail_untyped=False, and
then a and b get Untyped instead of float, so an invalid value
such as a string would not fail.
The defaults of parameters found only through stubs are not known. The help then
shows the default as Unknown<stubs-resolver>, and these parameters are not
included in get_defaults or in the output
of --print_config.
By default only *.pyi files are searched. To also search in *.py files,
use set_parsing_settings(stubs_resolver_allow_py_files=True).
Parameter aliases
Pydantic and attrs allow giving a field a name that is different from the
attribute name, an alias: pydantic’s alias/validation_alias and attrs’
alias. The resolvers take these aliases into account, so that a parser
accepts the same names as the class itself.
When the framework accepts both names, e.g. a pydantic model with
populate_by_name, the alias is accepted as an additional option and config
key. The attribute name is the one used in the parsed namespace, in
--print_config and in dumps:
>>> from pydantic import BaseModel, ConfigDict, Field
>>> class Client(BaseModel):
... model_config = ConfigDict(populate_by_name=True)
... api_key: str = Field(default="", alias="key")
...
>>> parser = ArgumentParser()
>>> parser.add_class_arguments(Client, "client")
>>> parser.parse_args(["--client.key=abc"])
Namespace(client=Namespace(api_key='abc'))
When the framework only accepts the alias, e.g. the same model without
populate_by_name, the alias is the name used everywhere, since giving the
attribute name would not instantiate the class as expected.
Aliases don’t work for a parameter whose type is a subclasses-disabled type added as a group of arguments, since then the name is a prefix of several arguments instead of a single option string, so only the attribute name is accepted. Enabling subclasses for the type, see Enable/disable subclasses, makes it a single argument, and then its alias is accepted too.
Dependency injection
Dependency injection is a design pattern that separates how objects are created from how they are used, giving more loosely coupled programs, see the wikipedia article. Supporting it has been a design goal of jsonargparse.
In Python, dependency injection is done by:
Using as type hint a class, such that the parameter accepts an instance of this class or any subclass, e.g.
module: ModuleBaseClass.Using as type hint a callable that returns an instance of a class, such that the parameter accepts a function for instantiation. This could be either using
Callable, e.g.module: Callable[[int], ModuleBaseClass], or a protocol, e.g.module: ModuleFactoryProtocol.
Class type and subclasses
When a class is used as a type hint, the value is a dictionary with a
class_path entry, which is the dot notation expression to import the class,
and optionally init_args to instantiate it. This dictionary is called a
subclass spec. When parsing, it is checked that the class can be imported,
that it is a subclass of the type, and that the init_args values are valid
arguments to instantiate it. The parsed config keeps the class_path and
init_args entries. instantiate gives a
config object with all nested subclasses instantiated.
Besides using a class as type hint in a signature, parsers can be built with
add_class_arguments and
add_subclass_arguments. These
accept a skip argument to exclude parameters inside subclasses, given as a
relative destination key, i.e. param.init_args.subparam. A single argument
can also be added with a class as type, i.e. parser.add_argument("--module",
type=ModuleBase).
A simple example, with a top-level class whose parameter expects an injected
class instance, uses a config file config.yaml as:
myclass:
calendar:
class_path: calendar.Calendar
init_args:
firstweekday: 1
Then in Python:
>>> from calendar import Calendar
>>> class MyClass:
... def __init__(self, calendar: Calendar):
... self.calendar = calendar
...
>>> parser = ArgumentParser()
>>> parser.add_class_arguments(MyClass, "myclass")
>>> cfg = parser.parse_path("config.yaml")
>>> cfg.myclass.calendar.as_dict()
{'class_path': 'calendar.Calendar', 'init_args': {'firstweekday': 1}}
>>> cfg = parser.instantiate(cfg)
>>> isinstance(cfg.myclass, MyClass)
True
>>> isinstance(cfg.myclass.calendar, Calendar)
True
>>> cfg.myclass.calendar.getfirstweekday()
1
Here the class_path points to the same class used as the type. A subclass of
Calendar, with more init parameters, would work as well.
Using add_subclass_arguments
instead of add_class_arguments
would also accept subclasses of MyClass, and the config would be:
myclass:
class_path: my_module.MyClass
init_args:
calendar:
class_path: calendar.TextCalendar
init_args:
firstweekday: 1
Note
A parameter of type Any, object, or Untyped, accepts a dict with
class_path and init_args, and the class is parsed and instantiated.
This instantiation is deprecated. From v5.0.0 the subclass spec is kept as
is, so that the code receiving it decides whether to instantiate it. Set
instantiate_subclass_spec_in_any=False in set_parsing_settings()
to get this behavior now and silence the deprecation warning. Setting it to
True keeps the instantiation, but is discouraged, since it means that a
config can instantiate any class, which is a security risk.
A value that looks like a subclass spec, i.e. has a class_path, but
can’t be parsed as one, e.g. because the class fails to import, is by
default left unchanged and a debug message is logged. Set
validate_subclass_spec_in_any=True in set_parsing_settings() to
make parsing fail instead. Besides Any, object and
Unvalidated<...>, this also applies to dicts that don’t validate their
values, e.g. dict[str, Any]. For dicts the spec is only validated, since
the value stays a dict. This matters for unions such as Union[SomeClass,
dict[str, Any]], where a spec rejected by the class member would otherwise
be silently swallowed by the dict member.
Note
class_path also accepts a function whose return type is a class. The
accepted init_args are then the parameters of that function.
Note
Abstract classes, i.e. classes that have abstract methods, are not accepted
as class_path, since they can’t be instantiated. For the same reason
they are not among the known subclasses shown in the help.
Untrusted configs
Resolving a class_path imports the named module and instantiates the named
class with the given init_args, so a config decides what code runs. When the
configs come from a trusted source, this is not a concern. When they don’t, e.g.
a config uploaded by a user of a service, an import path denylist limits what a
config can reach.
Import paths that come from a value, i.e. a class_path, a Callable, a
type[...] or a types.ModuleType given in a config file, the command line
or an environment variable, are checked against a denylist before the import
happens. Paths that come from code, e.g. type annotations and defaults, are
never checked. jsonargparse denies a set of paths by default, mostly standard
library modules that give arbitrary code execution, e.g. os, subprocess,
pickle and importlib. Two settings adjust the list:
from jsonargparse import set_parsing_settings
set_parsing_settings(
import_path_denylist=["mypackage._internal"],
import_path_allowlist=["functools.partial"],
)
An entry denies or allows a dot import path and everything under it, so os
also denies os.system. The most specific entry decides, which is why
functools.partial above is allowed even though functools is denied by
default. An entry given in both lists is allowed, so naming a default entry in
import_path_allowlist is how to stop denying it. The one exception is
jsonargparse itself, which is denied by default and not accepted in
import_path_allowlist, since a value that names it would be able to call
set_parsing_settings() and thus change the policy that is checking it.
An object is denied by where it is defined, not only by the path used to reach
it. Modules commonly import others, e.g. import os, so without this
some.module.os.system would give the same object as the denied
os.system. This second check can only happen once the object is resolved, so
it prevents the object from being used, unlike the check on the given path,
which prevents the import from happening at all. An object that has no defining
path of its own is denied by the callable it reaches, i.e. the bound function
for a functools.partial and the defining class for an instance, e.g.
builtins.help is an instance of the _sitebuiltins._Helper class.
Entries given are added to the ones denied by default, they don’t replace them.
For configs that are entirely untrusted, prefer denying everything and allowing
only what the application expects. The * entry is only accepted in
import_path_denylist:
set_parsing_settings(
import_path_denylist=["*"],
import_path_allowlist=["mypackage.tools"],
)
The denylist is not the only thing that limits what a config can reach. Type
hints do as well, since a class_path is only accepted where the annotation
allows one, and must name a subclass of the annotated type. The exceptions are
Any and object, which accept a subclass spec of any class, see
Class type and subclasses. Setting instantiate_subclass_spec_in_any=False, which is
the default from v5.0.0, keeps these values as plain dicts, so nothing is
imported or instantiated and the code that receives the dict decides what to do
with it. The denylist still applies when validate_subclass_spec_in_any=True,
since validating a spec requires importing the class it names.
Note
A denylist is a mitigation, not a sandbox. A large enough set of installed
dependencies is likely to contain something that reaches a denied capability
without naming a denied path, e.g. a class that runs a command given to it.
Only * plus a narrow allowlist gives a bound on what a config can
import.
Note
The omegaconf parser modes, see OmegaConf variable interpolation, give a
config access to OmegaConf’s resolvers, which the import path denylist does
not check. The built-in oc.env resolver reads environment variables, so
a value of ${oc.env:AWS_SECRET_ACCESS_KEY} puts that variable’s value
into the config, and the resolvers that the application registers are
equally reachable. Avoid these parser modes for untrusted configs.
Note
Until v5.0.0 a denied import path only gives a deprecation warning and the
import proceeds, so that existing configs don’t break. Giving a value to
import_path_denylist or import_path_allowlist, an empty list
included, makes denied import paths fail instead. From v5.0.0 they always
fail.
Sub-config files
Instead of writing a subclass spec inline, a path to a config file that holds it
can be given. This splits a large config into smaller reusable files. It
requires the argument to be added with sub_configs=True, which is the
default in auto_cli() and is accepted by add_argument and the add_*_arguments methods.
This also works for the items of a list of classes and for the values of a dict of classes, useful when each component has its own config file. For example, take the following classes:
class Hook:
def __init__(self, verbose: bool = False):
self.verbose = verbose
class LogHook(Hook):
def __init__(self, log_file: str = "run.log", **kwargs):
super().__init__(**kwargs)
self.log_file = log_file
class CheckpointHook(Hook):
def __init__(self, every_n_steps: int = 100, **kwargs):
super().__init__(**kwargs)
self.every_n_steps = every_n_steps
And a config in which each hook is a separate file:
# File: hooks.yaml
hooks:
- log_hook.yaml
- checkpoint_hook.yaml
# File: log_hook.yaml
class_path: LogHook
init_args:
log_file: train.log
# File: checkpoint_hook.yaml
class_path: CheckpointHook
init_args:
every_n_steps: 500
Then in Python:
>>> parser = ArgumentParser()
>>> parser.add_argument("--hooks", type=list[Hook], sub_configs=True)
>>> cfg = parser.parse_path("hooks.yaml")
>>> cfg.hooks[0].class_path
'__main__.LogHook'
>>> cfg.hooks[0].init_args.log_file
'train.log'
>>> cfg.hooks[1].init_args.every_n_steps
500
>>> init = parser.instantiate(cfg)
>>> isinstance(init.hooks[1], CheckpointHook)
True
The same is accepted from command line, i.e. --hooks=[log_hook.yaml,
checkpoint_hook.yaml], or appending one item at a time as explained in
List append, i.e. --hooks+=log_hook.yaml
--hooks+=checkpoint_hook.yaml.
Relative paths inside a sub-config file are resolved with respect to the
directory of that file, so a group of config files can be moved around without
being modified. save with multifile=True
writes each sub-config back to its own file, keeping the original structure.
Class types with subclasses disabled types also accept a sub-config file, whose content is
the fields of the type, without class_path and init_args. This only
applies when the type is not added as an argument group, i.e. when it is part of
a larger type, e.g. Optional[SomeDataclass] or list[SomeDataclass]. When
added as a group, the group’s own config argument accepts the path, e.g.
--data=data.yaml, independent of sub_configs.
Instance factories
As mentioned in Dependency injection, callables that return instances of
classes, called instance factories, are the other way of doing dependency
injection. They are useful for classes that need parameters which are only
available after injection. In this case instantiate gives a partial function, which takes those
parameters and returns the instance. There are two options, Callable and
Protocol. For the Callable option, take the classes:
class Optimizer:
def __init__(self, params: Iterable):
self.params = params
class SGD(Optimizer):
def __init__(self, params: Iterable, lr: float):
super().__init__(params)
self.lr = lr
A parser and its behavior could be:
>>> value = {
... "class_path": "SGD",
... "init_args": {
... "lr": 0.01,
... },
... }
>>> parser.add_argument("--optimizer", type=Callable[[Iterable], Optimizer])
>>> cfg = parser.parse_args(["--optimizer", str(value)])
>>> cfg.optimizer
Namespace(class_path='__main__.SGD', init_args=Namespace(lr=0.01))
>>> init = parser.instantiate(cfg)
>>> optimizer = init.optimizer([1, 2, 3])
>>> isinstance(optimizer, SGD)
True
>>> optimizer.params, optimizer.lr
([1, 2, 3], 0.01)
Note
When the Callable returns a class, the class_path can be given as
just the class name, if the class was imported before parsing, see
Command line.
When the same type above is used in a signature, a lambda can set the default:
class Model:
def __init__(
self,
optimizer: Callable[[Iterable], Optimizer] = lambda p: SGD(p, lr=0.05),
):
self.optimizer = optimizer
A parser then gives:
>>> parser.add_class_arguments(Model, 'model')
>>> cfg = parser.get_defaults()
>>> cfg.model.optimizer
Namespace(class_path='__main__.SGD', init_args=Namespace(lr=0.05))
>>> init = parser.instantiate(cfg)
>>> optimizer = init.model.optimizer([1, 2, 3])
>>> optimizer.params, optimizer.lr
([1, 2, 3], 0.05)
See AST resolver for the limitations of lambda defaults in signatures. A
lambda default given to add_argument
does not work, since there is no AST resolving. Use a dict with class_path
and init_args as default instead.
Several arguments after injection work the same way, e.g. Callable[[Iterable,
Iterable], Type] for two Iterable arguments, and Callable[[], Type]
for none.
Callable has an important limitation: its parameters are positional and
unnamed. The second option, a callable Protocol, avoids this. For the same
example:
class OptimizerFactory(Protocol):
def __call__(self, params: Iterable) -> Optimizer: ...
A parser using it behaves as:
>>> value = {
... "class_path": "SGD",
... "init_args": {
... "lr": 0.02,
... },
... }
>>> parser.add_argument("--optimizer", type=OptimizerFactory)
>>> cfg = parser.parse_args(["--optimizer", str(value)])
>>> cfg.optimizer
Namespace(class_path='__main__.SGD', init_args=Namespace(lr=0.02))
>>> init = parser.instantiate(cfg)
>>> optimizer = init.optimizer(params=[6, 5])
>>> optimizer.params, optimizer.lr
([6, 5], 0.02)
The difference is that init.optimizer() can now be called with keyword
arguments, i.e. params=[6, 5].
Command line
The help does not show the parameters of a class, since these depend on the chosen subclass. A help option that takes an import path gives them. For a parser defined as:
from calendar import Calendar
from jsonargparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument("--calendar", type=Calendar)
the help of a subclass is printed with:
python tool.py --calendar.help calendar.TextCalendar
A subclass can be given through several command line arguments:
python tool.py \
--calendar.class_path calendar.TextCalendar \
--calendar.init_args.firstweekday 1
For convenience, .class_path and .init_args can be omitted, and the
subclass can be named instead of giving its full import path:
python tool.py --calendar TextCalendar --calendar.firstweekday 1
Naming the subclass works for subclasses in modules that were imported before
parsing. Abstract classes and private classes (module or name starting with
'_') are not considered. The general help, python tool.py --help, lists
all the subclasses that can be given by name.
When the base class is not abstract, the class_path can be omitted, by
giving directly init_args, for example:
python tool.py --calendar.firstweekday 2
would implicitly use calendar.Calendar as the class path.
Default values
A parameter that has a class as type can also have a default value. Take care with this: it can be considered bad practice and is best avoided in most cases. The problem is that classes are normally mutable, so depending on how the value is used, the default instance in the signature can end up modified. That is not what a default value should be, and leads to bugs that are hard to debug.
Since there are legitimate use cases, class instances in defaults are supported with a particular behavior. An example is:
class MyClass:
def __init__(
self,
calendar: Calendar = Calendar(firstweekday=1),
):
self.calendar = calendar
Adding this class to a parser works without issues. In limited cases the
AST resolver figures out how the original default was instantiated, and
then the parse methods give a dict with class_path and init_args instead
of the instance. instantiate creates a new
instance, which avoids the mutability problem.
When the AST resolver does not support the case, or the source code is
not available, the second approach is to instantiate the default with the
lazy_instance() function:
from jsonargparse.typing import lazy_instance
class MyClass:
def __init__(
self,
calendar: Calendar = lazy_instance(Calendar, firstweekday=1),
):
self.calendar = calendar
The parsed default is then again a dict with class_path and init_args,
avoiding the mutability risk.
lazy_instance() is somewhat discouraged. Delaying the initialization of
instances in a way that works in general is hard, and the current implementation
is known to have some problems. Consider using Instance factories
instead.
Note
For some classes and functions the import path can’t be determined from the
object alone. Using one of these as a default fails when serializing, since
what gets saved in the config file is the import path. To solve this, give
the module from which the object can be imported to
register_unresolvable_import_paths().
Class types with subclasses disabled
Sometimes a class is used as a type hint with no intention of accepting
subclasses. For the parser this means that a subclass is not allowed, and that
serializing stores the init arguments directly, without class_path and
init_args. The standard Python way to express this is the final()
decorator. For example:
from jsonargparse.typing import final
@final
class FinalClass:
def __init__(self, number: int = 0, accepted: bool = False):
...
parser = ArgumentParser()
parser.add_argument("--data", type=FinalClass)
cfg = parser.parse_args(["--data.number=8", "--data.accepted=true"])
for which a dump would give as output:
>>> print(parser.dump(cfg))
data:
number: 8
accepted: true
Sometimes subclasses are not intended but the final() decorator is not
used. For example, requiring a class_path for a simple x, y coordinates
dataclass would be needlessly cumbersome. For this reason jsonargparse early on
gave the same behavior to pure dataclasses (not mixed with normal classes),
attrs’ define, pydantic’s dataclass and pydantic’s BaseModel. These
classes do technically support subclassing, so subclass support can be enabled
as described below. It is disabled by default to avoid breaking changes.
A type with subclasses disabled is added as an argument group when it is the
entire type of an argument, so each of its init args becomes an individual
argument, e.g. --data.number. This does not happen when the type is part of
a larger type, e.g. Optional[FinalClass] or list[FinalClass], since then
a single argument must accept the whole value. Either way the accepted values
are the same. A subclass spec is accepted, but only with the class_path of
the type itself, i.e. --data={"class_path": "FinalClass", "init_args":
{"number": 8}}. The class_path of a subclass is not accepted, unless
subclass support is enabled for the type as described next.
Abstract dataclass-like types are an exception. A class that has abstract
methods or that inherits from abc.ABC is not meant to be instantiated from
its own fields, so for these types subclass support is enabled by default, i.e.
only the class_path of an implementation is accepted.
Enable/disable subclasses
The subclasses_disabled and subclasses_enabled parameters of
set_parsing_settings() control which class types support subclasses.
subclasses_disabled accepts a list of types and functions. A given type and
its descendants have subclass support disabled. A function receives a type and
returns True if subclasses should be disabled for it.
subclasses_enabled accepts a list of types and function names. A given type
and its descendants have subclass support enabled, and take precedence over
subclasses_disabled. A function name must be one previously registered in
subclasses_disabled, and the effect is to unregister it. The disabling
functions registered by default are is_pure_dataclass,
is_pydantic_model, is_attrs_class and is_final_class. These are not
applied to abstract classes, see above.
Since subclasses_enabled takes precedence, subclass support can be kept
disabled for dataclasses but enabled for a specific one:
from jsonargparse import set_parsing_settings
set_parsing_settings(subclasses_enabled=[DataClassBaseType])
To enable subclass support for all pydantic models:
set_parsing_settings(subclasses_enabled=["is_pydantic_model"])
To enable it for all dataclasses but disable it for a specific one:
set_parsing_settings(
subclasses_enabled=["is_pure_dataclass"],
subclasses_disabled=[DataClassBaseType],
)
Note
Enabling subclass support for types is experimental. The interface and behavior are expected to be stable, but fundamental issues may still require design changes, which could break things in future releases.
Argument linking
Some use cases add arguments from several classes, where a parameter gets its
value computed from other arguments. The link_arguments parser method does this.
There are two types of links, apply_on='parse' and
apply_on='instantiate'. As the names say, the first are applied by the parse
methods and the second by instantiate.
Applied on parse
For parse links, the source keys can be single arguments or nested groups, and
the target key must be a single argument. Keys can be inside the init_args
of a subclass. The compute function takes as many positional arguments as there
are sources, and returns a value of a type compatible with the target. For
example:
class Model:
def __init__(self, batch_size: int):
self.batch_size = batch_size
class Data:
def __init__(self, batch_size: int = 5):
self.batch_size = batch_size
parser = ArgumentParser()
parser.add_class_arguments(Model, "model")
parser.add_class_arguments(Data, "data")
parser.link_arguments("data.batch_size", "model.batch_size", apply_on="parse")
Only data.batch_size is given, on the command line or in a config file, and
its value is propagated to model.batch_size.
An example with the target inside a subclass:
class Logger:
def __init__(self, save_dir: str | None = None):
self.save_dir = save_dir
class Trainer:
def __init__(
self,
save_dir: str | None = None,
logger: bool | Logger | list[Logger] = False,
):
self.logger = logger
parser = ArgumentParser()
parser.add_class_arguments(Trainer, "trainer")
parser.link_arguments("trainer.save_dir", "trainer.logger.init_args.save_dir")
The link is applied to the logger parameter when it is a single subclass,
and to all elements when it is a list of subclasses. If a subclass does not have
the targeted init_args parameter, the link is ignored.
Applied on instantiate
For instantiate links, the sources can be class groups (added with
add_class_arguments) or subclass
arguments (see Class type and subclasses). The source key is the instantiated object
itself or one of its attributes. The target key must be a single argument, and
can be inside the init_args of a subclass. instantiate determines the instantiation order from the
links, so all instantiate links together must form a directed acyclic graph. For
example:
class Model:
def __init__(self, num_classes: int):
self.num_classes = num_classes
class Data:
def __init__(self):
self.num_classes = get_num_classes()
parser = ArgumentParser()
parser.add_class_arguments(Model, "model")
parser.add_class_arguments(Data, "data")
parser.link_arguments("data.num_classes", "model.num_classes", apply_on="instantiate")
This link makes instantiate build Data
first, and then use its num_classes attribute to build Model.
OmegaConf variable interpolation
One reason to add a parser mode (see Custom loaders) is to support
variable interpolation. Any library can be used for this. Without writing a
loader, an omegaconf parser mode is available out of the box when the
omegaconf package is installed.
For example, a YAML file:
server:
host: localhost
port: 80
client:
url: http://${server.host}:${server.port}/
It is parsed as:
>>> @dataclass
... class ServerOptions:
... host: str
... port: int
...
>>> @dataclass
... class ClientOptions:
... url: str
...
>>> parser = ArgumentParser(parser_mode="omegaconf")
>>> parser.add_argument("--server", type=ServerOptions)
>>> parser.add_argument("--client", type=ClientOptions)
>>> parser.add_argument("--config", action="config")
>>> cfg = parser.parse_args(["--config=example.yaml"])
>>> cfg.client.url
'http://localhost:80/'
Note
parser_mode="omegaconf" supports OmegaConf’s resolvers
within a single YAML file. Interpolation across several YAML files, or in a
single command line argument, is not possible.
Experimental omegaconf+ mode
The experimental omegaconf+ parser mode removes the limitations above.
Instead of resolving each YAML config on its own, resolving happens once at the
end of parsing. As a result, in nested subconfigs, node references must be
relative or absolute at the parser level. Alternatively,
set_parsing_settings(omegaconf_absolute_to_relative_paths=True) converts
absolute paths to relative ones while parsing, though this does not work in
every case.
Depending on community feedback, this mode may become the default omegaconf
mode eventually. That would be a breaking change, since absolute node references
would no longer work in nested subconfigs.
Environment variables
Parsers can also get values from environment variables. The name of a variable
is [PREFIX_][LEV__]*OPT: all upper case, a prefix, an underscore, and then
the argument name with each dot replaced by two underscores. The prefix is
env_prefix, or the prog without extension when env_prefix is unset,
or none when it is False. For the parser from Nested namespaces, the
shell variables are:
export APP_LEV1__OPT1='from env 1'
export APP_LEV1__OPT2='from env 2'
The parser then uses these variables, unless the command line overrides them:
>>> parser = ArgumentParser(env_prefix="APP", default_env=True)
>>> parser.add_argument("--lev1.opt1", default="from default 1")
>>> parser.add_argument("--lev1.opt2", default="from default 2")
>>> cfg = parser.parse_args(["--lev1.opt1", "from arg 1"])
>>> cfg.lev1.opt1
'from arg 1'
>>> cfg.lev1.opt2
'from env 2'
Note the default_env=True given to the parser. By default parse_args does not parse environment variables. If
default_env is left unset, they can also be enabled by setting
JSONARGPARSE_DEFAULT_ENV=true in the shell.
The parse_env method parses only environment
variables, useful when there is no command line call.
If the parser has an action="config" argument, its environment variable is
parsed before all the others.
Subcommands
Subcommands are a modular way of defining parsers, like subcommands in argparse. In jsonargparse they behave somewhat differently, see Deviations from argparse.
Add subcommands to a parser with add_subcommands, and then add an existing parser as a
subcommand with add_subcommand. In
the parsed namespace, the chosen subcommand is under the subcommand key (or
the key given by dest), and its arguments are nested under a key with the
subcommand’s name. For example:
from jsonargparse import ArgumentParser
...
parser_subcomm1 = ArgumentParser()
parser_subcomm1.add_argument("--op1")
...
parser_subcomm2 = ArgumentParser()
parser_subcomm2.add_argument("--op2")
...
parser = ArgumentParser(prog="app")
parser.add_argument("--op0")
subcommands = parser.add_subcommands()
subcommands.add_subcommand("subcomm1", parser_subcomm1)
subcommands.add_subcommand("subcomm2", parser_subcomm2)
Some parsing examples:
>>> parser.parse_args(["subcomm1", "--op1", "val1"])
Namespace(op0=None, subcommand='subcomm1', subcomm1=Namespace(op1='val1'))
>>> parser.parse_args(["--op0", "val0", "subcomm2", "--op2", "val2"])
Namespace(op0='val0', subcommand='subcomm2', subcomm2=Namespace(op2='val2'))
Config files can also be parsed, with parse_path or parse_string. The config file does not need to give a value
for subcommand. For the parser above, a valid YAML is:
# File: example.yaml
op0: val0
subcomm1:
op1: val1
Environment variables work like for ActionParser. For the parser
above, the variables of subcomm1 have the prefix APP_SUBCOMM1_ and those
of subcomm2 the prefix APP_SUBCOMM2_. The subcommand itself is chosen
with APP_SUBCOMMAND.
Several levels of subcommands are possible, with one requirement: they must be
added in order of level. That is, first call add_subcommands and add_subcommand for the first level, only then for the
second level, and so on.
JSON Schemas
The ActionJsonSchema class parses and validates values with a JSON
Schema. It requires the jsonschema
package, which is not part of the minimal install. Install jsonargparse with the
jsonschema extra, see Installation.
See the JSON Schema documentation to learn how to write a schema.
jsonargparse currently uses Draft7Validator. An example:
>>> from jsonargparse import ActionJsonSchema
>>> schema = {
... "type": "object",
... "properties": {
... "price": {"type": "number"},
... "name": {"type": "string"},
... },
... }
>>> parser = ArgumentParser()
>>> parser.add_argument("--json", action=ActionJsonSchema(schema=schema))
>>> parser.parse_args(["--json", '{"price": 1.5, "name": "cookie"}'])
Namespace(json={'price': 1.5, 'name': 'cookie'})
The value can also be a path to a JSON/YAML file, which is loaded and validated
against the schema. Default values defined in the schema initialize the config
values that are not given. In the help string, "%s" is replaced by the
schema.
Jsonnet files
Jsonnet support requires the jsonschema and jsonnet packages, which are not part of the
minimal install. Install jsonargparse with the jsonnet extra, see
Installation.
By default an ArgumentParser parses config files as YAML. With
parser_mode='jsonnet', parse_args,
parse_path and parse_string expect Jsonnet instead:
from jsonargparse import ArgumentParser
parser = ArgumentParser(parser_mode="jsonnet")
parser.add_argument("--config", action="config")
cfg = parser.parse_args(["--config", "example.jsonnet"])
Jsonnet files are often parametrized and need external variables. For these,
instead of changing the parser mode away from yaml, use the
ActionJsonnet class. It defines an argument that takes a Jsonnet
string or a path to a Jsonnet file, plus another argument as the source of the
external variables, given as a path to, or a string with, a JSON dictionary:
from jsonargparse import ArgumentParser, ActionJsonnet
parser = ArgumentParser()
parser.add_argument("--in_ext_vars", type=dict)
parser.add_argument("--in_jsonnet", action=ActionJsonnet(ext_vars="in_ext_vars"))
For example, if a Jsonnet file required some external variable param, then
the Jsonnet and the external variable could be given as:
cfg = parser.parse_args(["--in_ext_vars", '{"param": 123}', "--in_jsonnet", "example.jsonnet"])
The external variables argument must come before the Jsonnet path, so that the dictionary already exists when the Jsonnet is parsed.
ActionJsonnet also accepts a JSON Schema, and then validates the
Jsonnet against it right after parsing.
Parsers as arguments
An existing parser, needed standalone somewhere in the code, can be reused to
parse an inner node of a larger parser. The ActionParser class defines
such an argument:
from jsonargparse import ArgumentParser, ActionParser
inner_parser = ArgumentParser(prog="app1")
inner_parser.add_argument("--op1")
...
outer_parser = ArgumentParser(prog="app2")
outer_parser.add_argument("--inner.node", title="Inner node title", action=ActionParser(parser=inner_parser))
In a config file, the value of the node can be the node itself, or the path to a
file that is loaded and parsed with the inner parser. Parsing a complete config
file with action="config" naturally parses the inner nodes correctly.
Note the title given when adding inner_parser. In the help, added
parsers are shown as independent groups starting with that title. A
description can also be given.
For environment variables, the prefix of the outer parser is used for the leaf
nodes of the inner parser. In the example above, inner_parser on its own
checks APP1_OP1 to populate option op1, while outer_parser checks
APP2_INNER__NODE__OP1 to populate inner.node.op1.
An important detail is that the parsers given to ActionParser are
modified internally. So to use a parser both standalone and as an inner node,
write a function that creates it, and call that function in each place, so that
each one gets its own instance.
Completion scripts
From a parser, jsonargparse can generate artifacts that describe what the parser accepts, so that other tools can validate and complete configs and command lines. The supported completion types are:
jsonschema: a JSON Schema that describes the config files that the parser accepts. Always available.shtab-*: a completion script for a given shell, e.g.shtab-bash. Available when the shtab package is installed.
Both are generated with the ArgumentParser.get_completion_script()
method, or from the command line, see The –print_completion argument.
Completion at runtime in the shell, which jsonargparse supports through the argcomplete package, is covered further down in argcomplete. It involves no generated artifact.
The –print_completion argument
To enable generation of completion scripts via the command line, use
set_parsing_settings() with add_print_completion_argument=True. This
adds a --print_completion argument to top-level parsers (not subparsers),
which accepts the completion types listed above.
from jsonargparse import set_parsing_settings
set_parsing_settings(add_print_completion_argument=True)
Without changing Python code, the argument is also added by setting the
environment variable JSONARGPARSE_ADD_PRINT_COMPLETION_ARGUMENT=true.
jsonschema
The jsonschema completion type gives a JSON Schema (draft 2020-12) that describes the config files
accepted by the parser.
parser = ArgumentParser(prog="example")
parser.add_argument("--bool", type=bool)
schema = parser.get_completion_script("jsonschema")
# schema now contains the JSON schema
The equivalent from the command line is:
$ example.py --print_completion=jsonschema > schema.json
This schema is useful as a machine-readable interface for tools. For example:
IDE/editor assistance (autocompletion, hints, and inline validation).
Config contract checks in CI pipelines.
Generating documentation from parser structure.
To get validation and autocompletion for a config file in an editor such as
Visual Studio Code,
the config can point to the generated schema with a $schema key:
{
"$schema": "./schema.json",
"bool": true
}
The key is accepted in any config that a parser loads, Sub-config files included, and it is removed before parsing, so it never becomes part of the parsed namespace. Accordingly, every object in the schema that describes a config accepts the key.
The schema is derived from the same information that the --help output is
based on, so it includes:
The structure of nested keys, i.e. argument groups and subclasses-disabled types become objects, and which of their keys are required.
The accepted types, including unions, literals, enums, containers and the restrictions of types such as
PositiveIntandEmail. For the plain argparse actions, which have no type hint, this is what the action gives, e.g. a boolean forstore_true, an integer forcount, the possible values forstore_constand an array forappend.The defaults of the arguments. Three kinds are left out: the required ones, the ones whose default is
argparse.SUPPRESS, since not giving those leaves no key, and the unset ones, see Unset values. Withoutunset_sentinel, aNonedefault counts as unset, sonullis never described as a default. With it, an explicitdefault=Noneis described, as long as the type acceptsnull.Descriptions taken from the docstrings of the classes and functions that the arguments come from, or from the
helpgiven toadd_argument.For subclass types, one entry per known subclass, each with a
class_pathfixed to that subclass and aninit_argsobject describing the accepted init parameters of that specific class.For parsers with subcommands, one object per subcommand and a
subcommandkey. This key is optional, since a config that has a single subcommand block implies it, and when a config has several blocks the subcommand can be given as a command line argument.
Subclasses and types that are used in more than one place are added once to
$defs and referenced with $ref, which also makes recursive types work.
The schema is meant to accept what the parser accepts, but for subclass types it
is stricter. A string is accepted, since it can be a class path or a path to a
sub-config file. An object is only accepted for the known subclasses, i.e. one
with class_path, init_args (required only for the subclasses that have a
required init parameter) and dict_kwargs. Accepting any class_path would
keep tools from suggesting the known subclasses and from pointing out a class
path that has a typo or is not the accepted import path, and its init_args
would go undescribed. Any class_path is accepted only when a type has no
known subclass, and then its init_args are not described.
A union that has a subtype accepting anything, i.e. Any or an unvalidated
type, is kept as {"anyOf": [..., {}]} instead of the equivalent {}, so
that tools still have the other subschemas to describe and complete against. The
exception is when another subtype restricts the keys of an object, e.g. a
subclass, dataclass or typed dict. Then the subschemas that accept any object,
i.e. those from Any, dict and unvalidated types, are removed. This makes
the schema stricter than the parser, but in exchange mistakes in the keys are
pointed out instead of going unnoticed.
Note
The subclasses of a type that the schema includes are the ones known to Python when the schema is generated, i.e. only those whose modules happen to have been imported.
Note
The jsonschema completion type is experimental. The details of the
generated schema might change in non-major releases.
shtab
The shtab-* completion types give a shell completion script, using
shtab- followed by the shell name, e.g. shtab-bash or shtab-zsh.
For shtab there is no need to set complete/choices on the parser
actions, or to call shtab.add_argument_to. The only requirement
is to install shtab, directly or with the shtab extra, see
Installation.
parser = ArgumentParser(prog="example")
parser.add_argument("--bool", type=bool)
script = parser.get_completion_script("shtab-bash", preambles=[])
# script now contains the bash completion script
Warning
After calling get_completion_script() for an shtab-* completion
type, the parser instance is invalidated and cannot be used for parsing
arguments.
From the command line, for example in Linux to enable bash completions for all users, as root:
# example.py --print_completion=shtab-bash > /etc/bash_completion.d/example
Without installing, a script can be tested by sourcing or evaluating it:
$ eval "$(example.py --print_completion=shtab-bash)"
Completion behavior
The scripts complete when there are choices, and also print guidance for the user. Take for example the parser:
#!/usr/bin/env python3
from jsonargparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument("--bool", type=bool | None)
parser.parse_args()
The completion prints the type of the argument, how many options match, and then the matching choices. If only one option matches, the value is completed without printing guidance. For example:
$ example.py --bool <TAB><TAB>
Expected type: bool | None; 3/3 matched choices
true false null
$ example.py --bool f<TAB>
$ example.py --bool false
For subclass types, the import paths of the known subclasses are completed, both
for the option that selects the class and for the --*.help option. The
init_args of the known subclasses are completed too, with guidance saying
which subclasses accept each one. For example:
$ example.py --cls <TAB><TAB>
Expected type: BaseClass; 3/3 matched choices
some.module.BaseClass other.module.SubclassA
other.module.SubclassB
$ example.py --cls other.module.SubclassA --cls.<TAB><TAB>
--cls.param1 --cls.param2
$ example.py --cls other.module.SubclassA --cls.param2 <TAB><TAB>
Expected type: int; Accepted by subclasses: SubclassA
Analogously, for subclasses-disabled types and TypedDict, the fields or keys
are completed, as well as the values that they accept, e.g.:
$ example.py --data.<TAB><TAB>
--data.verbose --data.mode
$ example.py --data.verbose <TAB><TAB>
Expected type: bool; 2/2 matched choices
true false
argcomplete
For argcomplete there is no need to implement completer functions or to call
argcomplete.autocomplete, since
parse_args does it automatically. The only
requirement is to install argcomplete, directly or with the argcomplete
extra, see Installation.
The shell completion can be enabled globally for all argcomplete compatible tools or for each individual tool.
Using the same bool example, activate completion and use it as follows:
$ eval "$(register-python-argcomplete example.py)"
$ example.py --bool <TAB><TAB>
false null true
$ example.py --bool f<TAB>
$ example.py --bool false
Deviations from argparse
To keep a high level of compatibility with argparse, the argparse tests from the
Python standard library are run against jsonargparse. Some are skipped because
they cover intentional deviations, are not relevant for jsonargparse, or are
still under investigation and may be enabled later. Which tests to skip is
configured in the argparse_tests_generate.py file.
The following sections describe the main intentional deviations from argparse. In addition, deprecated features in argparse are not supported.
Subcommands
In argparse, a parser with subcommands merges the main parser and subparser options into a single flat namespace. Since jsonargparse supports nested namespaces, subcommand options are deliberately placed in their own subnamespace, which is clearer and more convenient.
In argparse, add_subparsers needs the dest parameter for the name of the
chosen subcommand to appear in the namespace. In jsonargparse it is there by
default, without any extra parameter.
To promote modularity, jsonargparse subparsers are created independently, just like the main parser, and then added as a subcommand. This makes it possible to write functions that return a subparser, usable both standalone and as a subcommand. In argparse, subparsers are tightly coupled to the main parser and can’t be defined independently. To avoid confusion with argparse, the method names for adding subcommands are intentionally different.
To migrate from argparse to jsonargparse, instead of:
import argparse
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
subparser1 = subparsers.add_parser("foo")
subparser1.add_argument("--key")
...
the code becomes:
import jsonargparse
subparser1 = jsonargparse.ArgumentParser()
subparser1.add_argument("--key")
...
parser = jsonargparse.ArgumentParser()
subcommands = parser.add_subcommands()
subcommands.add_subcommand("foo", subparser1)
Parse known arguments
Argparse has a parse_known_args method, which parses leniently by ignoring
unrecognized arguments. jsonargparse is designed for complex cases: several
subcommands, many arguments derived from signatures, class instantiation and
config files. Ignoring unrecognized arguments would make errors, such as a typo
in a config file, harder to notice. For this reason parse_known_args is
intentionally not supported.
User defined types
In argparse, the type parameter of an argument can be a user-defined
function or class. A function is supported in jsonargparse, with the extra
requirement that it must be idempotent, i.e. applying it twice or more does not
change the value. For example:
# either int larger than zero or 'off' string
def int_or_off(x):
return x if x == "off" else int(x)
parser.add_argument("--int_or_off", type=int_or_off)
A class as the type conflicts with the signature and type hint support that is central to jsonargparse, so it does not work the same way as in argparse. The recommended alternative is to implement a custom type, see Creating custom types.
Troubleshooting and logging
When a parse method fails, by default it prints a short message and exits with a
non-zero code. During development this is not enough information to find the
root of the problem. Setting the JSONARGPARSE_DEBUG environment variable to
true changes this, without touching the source code: an
ArgumentError is raised and the full stack trace is printed.
The parsers log some basic events, though this is disabled by default. To enable
it, set the logger argument when creating an ArgumentParser. The
intended use is to give the logger object that the whole application uses. For
convenience, logger can also be True to enable a default logger, a
string with the name of the logger, or a dictionary with the name and the level,
e.g. {"name": "myapp", "level": "ERROR"}.
Contributing
Contributions to jsonargparse are very welcome. There are many ways to help, among them:
Star ⭐ the GitHub project https://github.com/mauvilsa/jsonargparse/.
Sponsor 🩷 its maintenance and development.
Spread the word in your community about the features you like from jsonargparse.
Help others learn how to use jsonargparse by creating tutorials, such as blog posts and videos. If you do, let us know so that it can be added to Talks and articles.
Become active in existing GitHub issues and pull requests.
Create issues to report bugs and propose improvements.
Create pull requests with documentation improvements, bug fixes or new features.
Note
Creating an issue before submitting a pull request is not mandatory, but it can be helpful, since it allows for discussion and feedback before significant effort is invested. In some cases, though, code changes illustrate a proposal better, so submitting a pull request directly is more effective. In such cases please avoid opening a largely redundant issue.
Development environment
All requirements of the project are defined in pyproject.toml. The basic
runtime requirements are in dependencies. Requirements for optional
features, as well as for testing, development and documentation building
(test, dev and doc), are in [project.optional-dependencies].
The recommended way to work with the source code is to clone the repository, create a virtual environment, activate it, and install the development requirements:
git clone https://github.com/mauvilsa/jsonargparse.git
cd jsonargparse
python -m venv venv
. venv/bin/activate
pip install -e ".[dev,all]"
pre-commit
Please also install the pre-commit git hooks, so that unit tests and code checks run automatically on your machine:
pre-commit install
Note
.pre-commit-config.yaml is configured to run the hooks using Python
3.12, so make sure that this version is installed and available. Other
Python versions work for development, but 3.12 is recommended for
convenience.
The pre-push stage runs several hooks, including tests, doctests, mypy and
coverage. They inform developers of issues that must be resolved before a pull
request can be merged, and can take some time to complete. To push without
running them, use git push --no-verify. Formatting of the code is applied
automatically by pre-commit. Even when pushing with --no-verify, please make
sure that the formatting has been applied.
Documentation
To build the documentation run:
sphinx-build sphinx sphinx/_build sphinx/*.rst
Then open the file sphinx/_build/index.html in a browser.
Code conventions
Public vs. private naming
Most module filenames start with _, meaning they are private implementation
details. For objects within modules, the _ prefix indicates the object is
only used within that same module. An object without a _ prefix may be
imported by other modules, but that does not make it public — it is simply
internal to the package. The only truly public objects are those listed in
jsonargparse.__all__ and jsonargparse.typing.__all__.
Type annotations and docstrings
New source code should be fully type annotated. Docstrings should follow Google style.
Tests
The unit tests can be run with pytest or tox. Pre-commit runs some additional tests.
tox # Run tests using tox on available python versions
pytest # Run tests using pytest on the python of the environment
pre-commit run -a --hook-stage pre-push # Run pre-push git hooks (tests, doctests, mypy, coverage)
The tests can also be run in any environment without the source code. Since v4.47.0 they are provided in a separate package, whereas before they were included in the main package. Prefer installing the tests package with the same version as the main package, for example:
pip install jsonargparse_tests==4.47.0
python -m jsonargparse_tests
All contributed features and bug fixes must include tests. For bug fixes, ensure that the test fails without the code fix. Tests should almost always exercise only the public API; testing internal functions directly is rarely justified and should be avoided. For tests involving signatures, define the classes and functions at the global module scope. Jsonargparse is not intended to support dynamically defined classes and functions, so there is no value in testing such cases.
For maintainable tests:
Prefer
pytest.mark.parametrizewhen the same test logic is exercised with different inputs.Use fixtures for repeated setup and shared test resources, especially when multiple tests need the same files, parser configuration, or environment.
Avoid pushing trivial one-line setup into fixtures when it makes the test harder to read.
Keep setup separate from assertions, so that each test clearly shows the behavior being verified.
Keep the pytest output clean. If a test causes log output, the logs must be captured and minimally asserted using the
loggerfixture andcapture_logscontext manager fromconftest.py.
Coverage
Coverage is required to be 100% in jsonargparse/* files, with realistic
tests and without unwarranted # pragma: no cover. This ensures that all
existing code is actually needed.
For a nice html coverage report, run:
pytest --cov --cov-report=html
Then open the file htmlcov/index.html in a browser.
A full coverage report requires all supported Python versions to be installed, and then:
rm -fr jsonargparse_tests/.coverage jsonargparse_tests/htmlcov
tox --parallel -- --cov=../jsonargparse --cov-append
cd jsonargparse_tests
coverage html
Then open the file jsonargparse_tests/htmlcov/index.html in a browser.
Pull requests
For the changes you want to contribute, it is recommended to create a specific
branch in your fork, instead of using the main branch.
The tasks required for a pull request are listed in PULL_REQUEST_TEMPLATE.md.
One of the tasks is adding a changelog entry. This project uses semantic versioning, so the entry goes in a patch release for a bug fix, or in a minor release for a new feature. The changelog section for the next release does not have a definite date, for example:
v4.28.0 (unreleased)
--------------------
Added
^^^^^
-
If no such section exists, just add it with “(unreleased)” instead of a date. Have a look at previous releases to decide under which subsection the new entry should go. Entries must describe changes with respect to the previous release, not with respect to unreleased commits.
Please don’t open pull requests with breaking changes, unless this has been discussed and agreed upon in an issue.
Contributions using coding agents are welcome. However, any agent-generated code
must be fully understood by the submitter, must make sense, and must follow
these contributing guidelines. Always ask the agent to read and follow this
document, and also .github/PULL_REQUEST_TEMPLATE.md, so that the tasks
required before submitting are covered.
API Reference
Even though jsonargparse has several internal modules, users are expected to
only import from jsonargparse or jsonargparse.typing. This allows doing
internal refactoring without affecting dependants. Only objects explicitly
exposed in jsonargparse.__init__.__all__ and in
jsonargparse.typing.__all__ are included in this API reference and is what
can be considered public.
jsonargparse
Exceptions:
|
An error from creating or using an argument (optional or positional). |
Functions:
|
Simple creation of command line interfaces. |
|
Same as |
|
Modify global parser settings that affect parser creation and parsing behavior. |
|
Adds a custom instantiator for a class type. |
|
Returns the current loader function for a given mode. |
|
Sets the value loader function to be used when parsing with a certain mode. |
|
Sets the dumping function for a given format name. |
|
Returns the parser object used within the execution of a function. |
|
Saves import paths of module objects for which its import path is unresolvable from the object alone. |
|
Returns a dataclass inheriting all given dataclasses and properly handling __post_init__. |
Returns the current config reading mode. |
|
|
Converts a nested dictionary into a nested namespace. |
|
Returns a copy of a nested namespace converted into a nested dictionary. |
|
Sets options for docstring parsing. |
|
Enables/disables optional config read modes. |
|
Enables/disables URL support for config read mode. |
|
Removes all metadata keys from a configuration object. |
|
Prints the usage and exits with error code 2 (same behavior as argparse). |
Classes:
|
Parser for command line, configuration files and environment variables. |
Mixin class that adds from config support to classes. |
|
|
Extension of argparse._SubParsersAction to modify subcommands functionality. |
|
Action to parse option as JSON validated by a JSON Schema. |
|
Action to parse a Jsonnet, optionally validating against a JSON Schema. |
|
Action that always fails parsing with a given error. |
|
Paired options |
|
Action to parse option with a given parser optionally loading from file if string value. |
|
Extension of argparse's Namespace to support nesting and subscript access. |
|
Help message formatter that includes types, default values and env var names. |
|
An action based on an Enum that maps to-from strings and enum values. |
|
Action to add argument to provide ext_vars for jsonnet parsing. |
|
Action to restrict a value with comparison operators. |
|
Action to check and store a path. |
|
Action to check and store a list of file paths read from a plain text file or stream. |
|
Helper class for DefaultHelpFormatter deprecations. |
|
Adds a logger property, intended for internal use. |
Deprecated methods for Path. |
|
|
Helper class for ArgumentParser deprecations. |
- exception jsonargparse.ArgumentError(argument, message)
Bases:
ExceptionAn error from creating or using an argument (optional or positional).
The string value of this exception is the message, augmented with information about the argument that caused it.
Methods:
__init__(argument, message)- __init__(argument, message)
- jsonargparse.auto_cli(components=None, args=None, config_help='Path to a configuration file.', set_defaults=None, as_positional=True, return_instance=False, fail_untyped=True, parser_class=<class 'jsonargparse._core.ArgumentParser'>, **kwargs)
Simple creation of command line interfaces.
Previously called
jsonargparse.CLI, renamed to follow the standard of functions in lowercase.Creates an argument parser from one or more functions/classes, parses arguments and runs one of the functions or class methods depending on what was parsed.
Inspired by Fire, though with fundamental differences: arguments are derived from type hints and validated against them, instead of being guessed from the given values; and return values are not printed, they are given back to the caller.
- Parameters:
components (
Callable|type|list[Callable|type] |dict[str,Callable|type|dict[str, ComponentType | DictComponentsType]] |None) – One or more functions/classes to include in the command line interface.args (
list[str] |None) – List of arguments to parse orNoneto usesys.argv.config_help (
str) – Help string for config file option in help.set_defaults (
dict[str,Any] |None) – Dictionary of values to override components defaults.as_positional (
bool) – Whether to add required parameters as positional arguments.return_instance (
bool) – Whether class components should be instantiated directly and returned, i.e. without exposing class methods as subcommands.fail_untyped (
Union[bool,Literal['all']]) – Whether to raise an exception for parameters that don’t have a type: True for the required ones, “all” for all of them, False for none.parser_class (
type[ArgumentParser]) – TheArgumentParsersubclass to use.**kwargs – Used to instantiate
ArgumentParser.
- Returns:
The value returned by the executed function or class method.
- jsonargparse.auto_parser(*args, **kwargs)
Same as
auto_cli(), but returns the parser, doesn’t parse arguments or run.This is a shorthand for
capture_parser(lambda: auto_cli(*args, **kwargs)).- Return type:
- class jsonargparse.ArgumentParser(*args, env_prefix=True, formatter_class=<class 'jsonargparse._formatters.DefaultHelpFormatter'>, logger=False, version=None, print_config='--print_config', parser_mode='yaml', dump_header=None, default_config_files=None, default_env=False, **kwargs)
Bases:
ParserDeprecations,ActionsContainer,ArgumentParserParser for command line, configuration files and environment variables.
Methods:
__init__(*args[, env_prefix, ...])Initializer for ArgumentParser instance.
parse_args([args, namespace, env, defaults])Parses command line argument strings.
parse_object(obj[, namespace, env, defaults])Parses configuration given as an object.
parse_env([env, defaults])Parses environment variables.
parse_path(path[, ext_vars, env, defaults])Parses a configuration file given its path.
parse_string(content[, path, ext_vars, env, ...])Parses configuration given as a string.
add_argument(*args[, sub_configs])Adds an argument to the parser or argument group.
add_argument_group(*args[, name])Adds a group to the parser.
add_function_arguments(function[, ...])Adds arguments from a function based on its type hints and docstrings.
add_method_arguments(class_type, method_name)Adds arguments from a class based on its type hints and docstrings.
add_class_arguments(class_type[, ...])Adds arguments from a class based on its type hints and docstrings.
add_subclass_arguments(baseclass, nested_key)Adds arguments to allow specifying any subclass of the given base class.
link_arguments(source, target[, compute_fn, ...])Makes an argument value be derived from the values of other arguments.
add_subcommands([required, dest])Adds subcommand parsers to the ArgumentParser.
dump(namespace[, format, skip_unset, ...])Generates a serialized string for the given configuration object.
save(namespace, path[, format, skip_unset, ...])Writes to file(s) the given configuration object using the chosen format.
get_default(dest)Gets a single default value for the given destination key.
get_defaults([skip_validation])Returns a namespace with all default values.
set_defaults(*args, **kwargs)Sets default values from dictionary or keyword arguments.
get_completion_script(completion_type, **kwargs)Returns a shell completion script or a JSON Schema for a completion type.
error(message[, ex])Logs error message if a logger is set and exits or raises an
ArgumentError.validate(namespace[, skip_unset, ...])Checks that the content of a given configuration object conforms with the parser.
instantiate(namespace[, instantiate_groups])Instantiates all signature components in a configuration namespace.
strip_unknown(namespace)Removes all unknown keys from a configuration object.
get_config_files(namespace)Returns a list of loaded config file paths.
parse_known_args(*args, **kwargs)Raises
NotImplementedErrorsince typos in configs would go unnoticed.add_subparsers(*args, **kwargs)Raises
NotImplementedErrorsince jsonargparse usesadd_subcommands.Attributes:
Default config file locations.
Whether by default environment variables parsing is enabled.
The environment variables prefix property.
Mode for parsing config files,
yaml,json,jsonnetor ones added viaset_loader().Header to include as comment when dumping a config object.
- __init__(*args, env_prefix=True, formatter_class=<class 'jsonargparse._formatters.DefaultHelpFormatter'>, logger=False, version=None, print_config='--print_config', parser_mode='yaml', dump_header=None, default_config_files=None, default_env=False, **kwargs)
Initializer for ArgumentParser instance.
All the arguments from the initializer of argparse.ArgumentParser are supported. Additionally it accepts:
- Parameters:
env_prefix (
bool|str) – Prefix for environment variables.Trueto derive fromprog.formatter_class (
type[HelpFormatter]) – Class for printing help messages.logger (
Logger|bool|str|dict) – Logger to use or configuration for logger.version (
str|None) – Program version which will be printed by the--versionargument.print_config (
str|None) – Name for print config argument,%sis replaced by config dest, setNoneto disable.parser_mode (
str) – Mode for parsing values:yaml,json,jsonnetor added viaset_loader().dump_header (
list[str] |None) – Header to include as comment when dumping a config object.default_config_files (
list[str|PathLike] |None) – Default config file locations, e.g.['~/.config/myapp/*.yaml'].default_env (
bool) – Set the default value on whether to parse environment variables.
- parse_args(args=None, namespace=None, env=None, defaults=True, **kwargs)
Parses command line argument strings.
All the arguments from argparse.ArgumentParser.parse_args are supported. Additionally it accepts:
- Parameters:
- Return type:
- Returns:
A config object with all parsed values.
- Raises:
ArgumentError – If the parsing fails and
exit_on_error=False.
- parse_object(obj, namespace=None, env=None, defaults=True, **kwargs)
Parses configuration given as an object.
- Parameters:
- Return type:
- Returns:
A config object with all parsed values.
- Raises:
ArgumentError – If the parsing fails and
exit_on_error=False.
- parse_env(env=None, defaults=True, **kwargs)
Parses environment variables.
- Parameters:
- Return type:
- Returns:
A config object with all parsed values.
- Raises:
ArgumentError – If the parsing fails and
exit_on_error=False.
- parse_path(path, ext_vars=None, env=None, defaults=True, **kwargs)
Parses a configuration file given its path.
- Parameters:
path (
str|PathLike) – Path to the configuration file to parse.ext_vars (
dict|None) – Optional external variables used for parsing jsonnet.env (
bool|None) – Whether to merge with the parsed environment,Noneto use the parser’s default.defaults (
bool) – Whether to merge with the parser’s defaults.
- Return type:
- Returns:
A config object with all parsed values.
- Raises:
ArgumentError – If the parsing fails and
exit_on_error=False.
- parse_string(content, path='', ext_vars=None, env=None, defaults=True, **kwargs)
Parses configuration given as a string.
- Parameters:
content (
str) – The configuration content.path (
str|PathLike) – Optional path to original config path, just for error printing.ext_vars (
dict|None) – Optional external variables used for parsing jsonnet.env (
bool|None) – Whether to merge with the parsed environment,Noneto use the parser’s default.defaults (
bool) – Whether to merge with the parser’s defaults.
- Return type:
- Returns:
A config object with all parsed values.
- Raises:
ArgumentError – If the parsing fails and
exit_on_error=False.
- add_argument(*args, sub_configs=False, **kwargs)
Adds an argument to the parser or argument group.
All the arguments from argparse.ArgumentParser.add_argument are supported. Additionally it accepts:
- Parameters:
sub_configs (
bool) – Whether to try parsing a sub-config when argument is a complex type.
- add_argument_group(*args, name=None, **kwargs)
Adds a group to the parser.
All the arguments from argparse.ArgumentParser.add_argument_group are supported. Additionally it accepts:
- Parameters:
name (
str|None) – Name of the group. If set, the group object will be included in theparser.groupsdict.- Return type:
ArgumentGroup- Returns:
The group object.
- Raises:
ValueError – If a group with the same name already exists.
- add_function_arguments(function, nested_key=None, as_group=True, as_positional=False, skip=None, fail_untyped=True, sub_configs=False)
Adds arguments from a function based on its type hints and docstrings.
Note: Keyword arguments without at least one valid type are ignored.
- Parameters:
function (
Callable) – Function from which to add arguments.as_group (
bool) – Whether arguments should be added to a new argument group.as_positional (
bool) – Whether to add required parameters as positional arguments.skip (
set[str|int] |None) – Names of parameters or number of positionals that should be skipped.fail_untyped (
Union[bool,Literal['all']]) – Whether to raise an exception for parameters that don’t have a type: True for the required ones, “all” for all of them, False for none.sub_configs (
bool) – Whether subclass type hints should be loadable from inner config file.
- Return type:
- Returns:
The list of arguments added.
- Raises:
ValueError – When not given a callable.
ValueError – When there are required parameters without at least one valid type.
- add_method_arguments(class_type, method_name, nested_key=None, as_group=True, as_positional=False, skip=None, fail_untyped=True, sub_configs=False)
Adds arguments from a class based on its type hints and docstrings.
Note: Keyword arguments without at least one valid type are ignored.
- Parameters:
class_type (
type) – Class which includes the method.method_name (
str) – Name of the method for which to add arguments.as_group (
bool) – Whether arguments should be added to a new argument group.as_positional (
bool) – Whether to add required parameters as positional arguments.skip (
set[str|int] |None) – Names of parameters or number of positionals that should be skipped.fail_untyped (
Union[bool,Literal['all']]) – Whether to raise an exception for parameters that don’t have a type: True for the required ones, “all” for all of them, False for none.sub_configs (
bool) – Whether subclass type hints should be loadable from inner config file.
- Return type:
- Returns:
The list of arguments added.
- Raises:
ValueError – When not given a class or the name of a method of the class.
ValueError – When there are required parameters without at least one valid type.
- add_class_arguments(class_type, nested_key=None, as_group=True, as_positional=False, default=None, skip=None, instantiate=True, fail_untyped=True, sub_configs=False, **kwargs)
Adds arguments from a class based on its type hints and docstrings.
Note: Keyword arguments without at least one valid type are ignored.
- Parameters:
class_type (
type) – Class from which to add arguments.as_group (
bool) – Whether arguments should be added to a new argument group.as_positional (
bool) – Whether to add required parameters as positional arguments.default (
dict|Namespace|type|None) – Default value used to override parameter defaults.skip (
set[str|int] |None) – Names of parameters or number of positionals that should be skipped.instantiate (
bool) – Whether the class group should be instantiated byinstantiate.fail_untyped (
Union[bool,Literal['all']]) – Whether to raise an exception for parameters that don’t have a type: True for the required ones, “all” for all of them, False for none.sub_configs (
bool) – Whether subclass type hints should be loadable from inner config file.
- Return type:
- Returns:
The list of arguments added.
- Raises:
ValueError – When not given a class.
ValueError – When there are required parameters without at least one valid type.
- add_subclass_arguments(baseclass, nested_key, as_group=True, skip=None, instantiate=True, required=False, metavar='CONFIG | CLASS_PATH_OR_NAME | .INIT_ARG_NAME VALUE', help='One or more arguments specifying "class_path" and "init_args" for any subclass of %(baseclass_name)s.', **kwargs)
Adds arguments to allow specifying any subclass of the given base class.
This adds an argument that requires a dictionary with a
class_pathentry which must be a import dot notation expression. Optionally any init arguments for the class can be given in theinit_argsentry. Since subclasses can have different init arguments, the help does not show the details of the arguments of the base class. Instead a help argument is added that will print the details for a given class path.- Parameters:
baseclass (
type|tuple[type,...]) – Base class or classes to use to check subclasses.nested_key (
str) – Key for nested namespace.as_group (
bool) – Whether arguments should be added to a new argument group.skip (
set[str] |None) – Names of parameters that should be skipped.required (
bool) – Whether the argument group is required.metavar (
str) – Variable string to show in the argument’s help.help (
str) – Description of argument to show in the help.**kwargs – Additional parameters like in
add_class_arguments().
- Raises:
ValueError – When given an invalid base class.
- link_arguments(source, target, compute_fn=None, apply_on='parse')
Makes an argument value be derived from the values of other arguments.
Refer to Argument linking for a detailed explanation and examples.
- Parameters:
- Raises:
ValueError – If an invalid parameter is given.
- add_subcommands(required=True, dest='subcommand', **kwargs)
Adds subcommand parsers to the ArgumentParser.
The aim is the same as argparse.ArgumentParser.add_subparsers the difference being that dest by default is
subcommandand the parsed values of the subcommand are stored in a nested namespace using the subcommand’s name as base key.- Parameters:
required (
bool) – Whether the subcommand must be provided.dest (
str) – Destination key where the chosen subcommand name is stored.**kwargs –
All options that argparse.ArgumentParser.add_subparsers accepts.
- Return type:
- dump(namespace, format='parser_mode', skip_unset=True, skip_default=False, skip_validation=False, with_comments=False, skip_link_targets=True, **kwargs)
Generates a serialized string for the given configuration object.
- Parameters:
namespace (
Namespace) – The configuration object to dump.format (
str) – The output format:yaml,json,json_indented,toml,parser_modeor ones added viaset_dumper().skip_unset (
bool) – Whether to exclude entries whose value is the configured None/Unset value.skip_default (
bool) – Whether to exclude entries whose value is the same as the default.skip_validation (
bool) – Whether to skip parser checking.with_comments (
bool) – Whether to add help content as comments. Currently only supported forformat="yaml".skip_link_targets (
bool) – Whether to exclude link targets.
- Return type:
- Returns:
The configuration in the chosen format.
- Raises:
TypeError – If any of the values of namespace is invalid according to the parser.
- save(namespace, path, format='parser_mode', skip_unset=True, skip_validation=False, overwrite=False, multifile=True, branch=None, **kwargs)
Writes to file(s) the given configuration object using the chosen format.
- Parameters:
namespace (
Namespace) – The configuration object to save.path (
str|PathLike) – Path to the location where to save config.format (
str) – The output format:yaml,json,json_indented,parser_modeor ones added viaset_dumper().skip_unset (
bool) – Whether to exclude entries whose value is the configured None/Unset value.skip_validation (
bool) – Whether to skip parser checking.overwrite (
bool) – Whether to overwrite existing files.multifile (
bool) – Whether to save multiple config files by using the__path__metas.
- Raises:
TypeError – If any of the values of namespace is invalid according to the parser.
- Return type:
- get_default(dest)
Gets a single default value for the given destination key.
- get_defaults(skip_validation=False, **kwargs)
Returns a namespace with all default values.
- set_defaults(*args, **kwargs)
Sets default values from dictionary or keyword arguments.
- get_completion_script(completion_type, **kwargs)
Returns a shell completion script or a JSON Schema for a completion type.
- Return type:
- error(message, ex=None)
Logs error message if a logger is set and exits or raises an
ArgumentError.- Return type:
- validate(namespace, skip_unset=True, skip_required=False, branch=None, **kwargs)
Checks that the content of a given configuration object conforms with the parser.
- Parameters:
- Raises:
- Return type:
- instantiate(namespace, instantiate_groups=True)
Instantiates all signature components in a configuration namespace.
Processes the configuration recursively, converting each signature component registered with the parser into its corresponding Python object:
Class/subclass type arguments (
add_argumentwith a class type oradd_class_arguments/add_subclass_arguments): An object withclass_pathand optionallyinit_argsis replaced by an instance of the referenced class, created by callingclass_type(**init_args). For the case of classes with disabled subclasses, the namespace can have directly the init args without theclass_path+init_argswrapper.Callable type arguments: A dot-import string pointing to a function or method is resolved to the callable object. When
class_path/init_argsis given instead and the class instantiates into a callable (or is a subclass of the callable’s return type), the result is either a class instance or — when not all call arguments are provided yet — afunctools.partial()bound to the giveninit_args.Instantiation order: Components are processed in the order determined by argument links applied on instantiation.
- Parameters:
- Return type:
- Returns:
A new configuration object where every registered signature component has been replaced by its corresponding Python object.
- strip_unknown(namespace)
Removes all unknown keys from a configuration object.
- get_config_files(namespace)
Returns a list of loaded config file paths.
- property default_config_files: list[str]
Default config file locations.
- Getter:
Returns the current default config file locations.
- Setter:
Sets new default config file locations, e.g.
['~/.config/myapp/*.yaml'].- Raises:
ValueError – If an invalid value is given.
- property default_env: bool
Whether by default environment variables parsing is enabled.
If the
JSONARGPARSE_DEFAULT_ENVenvironment variable is set to true or false, that value will take precedence.- Getter:
Returns the current default environment variables parsing setting.
- Setter:
Sets the default environment variables parsing setting.
- Raises:
ValueError – If an invalid value is given.
- property env_prefix: bool | str
The environment variables prefix property.
- Getter:
Returns the current environment variables prefix.
- Setter:
Sets the environment variables prefix.
- Raises:
ValueError – If an invalid value is given.
- property parser_mode: str
Mode for parsing config files,
yaml,json,jsonnetor ones added viaset_loader().- Getter:
Returns the current parser mode.
- Setter:
Sets the parser mode.
- Raises:
ValueError – If an invalid value is given.
- property dump_header: list[str] | None
Header to include as comment when dumping a config object.
- Getter:
Returns the current dump header.
- Setter:
Sets the dump header.
- Raises:
ValueError – If an invalid value is given.
- parse_known_args(*args, **kwargs)
Raises
NotImplementedErrorsince typos in configs would go unnoticed.- Return type:
- class jsonargparse.FromConfigMixin
Bases:
objectMixin class that adds from config support to classes.
This mixin does two things:
Adds support for overriding
__init__defaults by defining a__from_config_init_defaults__class attribute pointing to a config file path. The overriding of defaults happens on subclass creation time. Inspecting the signature will give the overridden defaults.Adds a
from_config@classmethod, that instantiates the class based on a config file or dict. Ifconfig_read_mode_fsspec_enabled=Trueis set, then config paths can be URLs.
- __from_config_init_defaults__
Optional path to a config file for overriding
__init__defaults.
- __from_config_parser_kwargs__
Additional kwargs to pass to the ArgumentParser used for parsing configs.
Methods:
from_config(config)Instantiate current class based on a config file or dict.
- class jsonargparse.ActionSubCommands(option_strings, prog, parser_class, dest='==SUPPRESS==', required=False, help=None, metavar=None)
Bases:
_SubParsersActionExtension of argparse._SubParsersAction to modify subcommands functionality.
Methods:
add_parser(*args, **kwargs)Raises a
NotImplementedErrorsince jsonargparse usesadd_subcommand.add_subcommand(name, parser, **kwargs)Adds a parser as a subcommand parser.
__call__(parser, namespace, values[, ...])Adds subcommand dest and parses subcommand arguments.
- add_parser(*args, **kwargs)
Raises a
NotImplementedErrorsince jsonargparse usesadd_subcommand.- Return type:
- add_subcommand(name, parser, **kwargs)
Adds a parser as a subcommand parser.
In contrast to argparse.ArgumentParser.add_subparsers add_parser requires to be given a parser as argument.
- Parameters:
name (
str) – The name for the subcommand.parser (
ArgumentParser) – The parser to use for the subcommand.
- Return type:
ArgumentParser
- __call__(parser, namespace, values, option_string=None)
Adds subcommand dest and parses subcommand arguments.
- class jsonargparse.ActionJsonSchema(schema=None, sub_config=True, with_meta=True, **kwargs)
Bases:
ActionAction to parse option as JSON validated by a JSON Schema.
Methods:
__init__([schema, sub_config, with_meta])Initializer for ActionJsonSchema instance.
__call__(*args, **kwargs)Parses an argument validating against the corresponding JSON Schema.
completer(prefix, **kwargs)Used by argcomplete, validates value and shows expected type.
- __init__(schema=None, sub_config=True, with_meta=True, **kwargs)
Initializer for ActionJsonSchema instance.
- __call__(*args, **kwargs)
Parses an argument validating against the corresponding JSON Schema.
- Raises:
TypeError – If the argument is not valid.
- completer(prefix, **kwargs)
Used by argcomplete, validates value and shows expected type.
- class jsonargparse.ActionJsonnet(ext_vars=None, schema=None, **kwargs)
Bases:
ActionAction to parse a Jsonnet, optionally validating against a JSON Schema.
Methods:
__init__([ext_vars, schema])Initializer for ActionJsonnet instance.
__call__(*args, **kwargs)Parses an argument as Jsonnet using
ext_varsif defined.split_ext_vars(ext_vars)Splits an
ext_varsdict into theext_codesandext_varsrequired by Jsonnet.parse(jsonnet[, ext_vars, with_meta])Method that can be used to parse Jsonnet independent from an
ArgumentParser.- __init__(ext_vars=None, schema=None, **kwargs)
Initializer for ActionJsonnet instance.
- __call__(*args, **kwargs)
Parses an argument as Jsonnet using
ext_varsif defined.- Raises:
TypeError – If the argument is not valid.
- static split_ext_vars(ext_vars)
Splits an
ext_varsdict into theext_codesandext_varsrequired by Jsonnet.
- parse(jsonnet, ext_vars=None, with_meta=False)
Method that can be used to parse Jsonnet independent from an
ArgumentParser.- Parameters:
- Return type:
- Returns:
The parsed Jsonnet object.
- Raises:
TypeError – If the input is neither a path to an existent file nor a Jsonnet.
- class jsonargparse.ActionFail(message='option unavailable', **kwargs)
Bases:
ActionAction that always fails parsing with a given error.
Methods:
__init__([message])Initializer for ActionFail instance.
__call__(*args, **kwargs)Always fails with given message.
- __init__(message='option unavailable', **kwargs)
Initializer for ActionFail instance.
- Parameters:
message (
str) – Text for the error to show. Use%(option)s/%(value)sto include the option and/or value.
- __call__(*args, **kwargs)
Always fails with given message.
- class jsonargparse.ActionYesNo(yes_prefix='', no_prefix='no_', **kwargs)
Bases:
ActionPaired options
--[yes_prefix]opt,--[no_prefix]optto setTrueorFalserespectively.Methods:
__init__([yes_prefix, no_prefix])Initializer for ActionYesNo instance.
__call__(*args, **kwargs)Sets the corresponding key to True or False depending on the option string used.
completer(**kwargs)Used by argcomplete to support tab completion of arguments.
- __init__(yes_prefix='', no_prefix='no_', **kwargs)
Initializer for ActionYesNo instance.
- Parameters:
- Raises:
ValueError – If a parameter is invalid.
- __call__(*args, **kwargs)
Sets the corresponding key to True or False depending on the option string used.
- completer(**kwargs)
Used by argcomplete to support tab completion of arguments.
- class jsonargparse.ActionParser(parser)
Bases:
objectAction to parse option with a given parser optionally loading from file if string value.
Methods:
__init__(parser)Initializer for ActionParser instance.
- __init__(parser)
Initializer for ActionParser instance.
- Parameters:
parser (
ArgumentParser) – A parser to parse the option with.- Raises:
ValueError – If the parser parameter is invalid.
- class jsonargparse.Namespace(*args, **kwargs)
Bases:
NamespaceExtension of argparse’s Namespace to support nesting and subscript access.
Methods:
__init__(*args, **kwargs)Initializer for Namespace instance.
as_dict()Converts the nested namespaces into nested dictionaries.
as_flat()Converts the nested namespaces into a single argparse flat namespace.
items([branches, nested])Returns a generator of all leaf (key, value) items, optionally including branches.
keys([branches, nested])Returns a generator of all leaf keys, optionally including branches.
values([branches])Returns a generator of all leaf values, optionally including branches.
clone([with_meta])Creates an new copy of the nested namespace.
update(value[, key, only_unset])Sets or replaces all items from the given nested namespace.
get(key[, default])Returns the value for the given key if it exists, otherwise the default.
pop(key[, default])Removes the given key and returns its value if it exists, otherwise the default.
get_sorted_keys([branches, key_filter])Deprecated method
get_value_and_parent(key)Deprecated method
- __init__(*args, **kwargs)
Initializer for Namespace instance.
Instantiating a Namespace with initial values most commonly is done by providing keyword arguments, e.g.
Namespace(name1=value1, name2=value2). Alternatively a single positionalNamespaceordictobject can be given.
- as_flat()
Converts the nested namespaces into a single argparse flat namespace.
- Return type:
- items(branches=False, nested=True)
Returns a generator of all leaf (key, value) items, optionally including branches.
- keys(branches=False, nested=True)
Returns a generator of all leaf keys, optionally including branches.
- values(branches=False)
Returns a generator of all leaf values, optionally including branches.
- clone(with_meta=True)
Creates an new copy of the nested namespace.
- update(value, key=None, only_unset=False)
Sets or replaces all items from the given nested namespace.
- Parameters:
- Return type:
- get(key, default=None)
Returns the value for the given key if it exists, otherwise the default.
- Return type:
- pop(key, default=None)
Removes the given key and returns its value if it exists, otherwise the default.
- Return type:
- get_sorted_keys(branches=True, key_filter=<function is_meta_key>)
Deprecated method
Warning
get_sorted_keys method was deprecated in v4.49.0 and will be removed in v5.0.0. There is no replacement since this is for internal use and developers can call .keys() and then sort.
- class jsonargparse.DefaultHelpFormatter(*args, **kwargs)
Bases:
HelpFormatterDeprecations,HelpFormatterHelp message formatter that includes types, default values and env var names.
This class is an extension of argparse.HelpFormatter. Default values are always included. Furthermore, if the parser is configured with
default_env=Truecommand line options are preceded byARG:and the respective environment variable name is included preceded byENV:.
- jsonargparse.set_parsing_settings(*, validate_defaults=None, validate_subclass_spec_in_any=None, instantiate_subclass_spec_in_any=None, config_read_mode_urls_enabled=None, config_read_mode_fsspec_enabled=None, docstring_parse_style=None, docstring_parse_attribute_docstrings=None, parse_optionals_as_positionals=None, add_print_completion_argument=None, stubs_resolver_allow_py_files=None, omegaconf_absolute_to_relative_paths=None, unset_sentinel=None, subclasses_disabled=None, subclasses_enabled=None, import_path_denylist=None, import_path_allowlist=None)
Modify global parser settings that affect parser creation and parsing behavior.
- Parameters:
validate_defaults (
bool|None) – Whether default values must be valid according to the argument type. The default isFalse, meaning no default validation, like in argparse.validate_subclass_spec_in_any (
bool|None) – IfTrue, when a value for a type that accepts any value, i.e.Any,object,Unvalidated<...>or a dict that doesn’t validate its values, looks like a subclass spec (i.e. a dict with aclass_pathkey), it is required to be a valid one, otherwise the parsing fails. For dicts the spec is only validated, since the value is kept as a dict. By default, this isFalse, meaning that an invalid subclass spec is ignored (a debug log is emitted) and the original value is kept.instantiate_subclass_spec_in_any (
bool|None) – Whetherinstantiatebuilds the class when a value for a type that accepts any value, i.e.Any,objectorUnvalidated<...>, is a valid subclass spec. IfFalse, the value is kept as a subclass spec, which the code that receives it can instantiate itself if desired. Currently the default isTrueand a deprecation warning is emitted, since from v5.0.0 the default will beFalse. Enabling it is discouraged because it means that any class can be instantiated, so only do it for trusted configs.config_read_mode_urls_enabled (
bool|None) – Whether to read config files from URLs using requests package. Default isFalse.config_read_mode_fsspec_enabled (
bool|None) – Whether to read config files from fsspec supported file systems. Default isFalse.docstring_parse_style (
DocstringStyle|None) – The docstring style to expect. Default isDocstringStyle.AUTO.docstring_parse_attribute_docstrings (
bool|None) – Whether to parse attribute docstrings (slower). Default isFalse.parse_optionals_as_positionals (
bool|None) – IfTrue, the parser will take extra positional command line arguments as values for optional arguments. This means that optional arguments can be given by name--key=valueas usual, but also as positional. The extra positionals are applied to optionals in the order that they were added to the parser. By default, this isFalse.add_print_completion_argument (
bool|None) – IfTrue, top-level parsers automatically include a--print_completionargument. Its accepted values arejsonschemaand, whenshtabis installed, oneshtab-*value per supported shell.stubs_resolver_allow_py_files (
bool|None) – Whether the stubs resolver should search in.pyfiles in addition to.pyifiles.omegaconf_absolute_to_relative_paths (
bool|None) – IfTrue, when loading configs withomegaconf+parser mode, absolute interpolation paths are converted to relative. This is only intended for backward compatibility withomegaconfparser mode.unset_sentinel (
bool|None) – IfTrue, parsers will use theUnsetsentinel for arguments that have not been given a value (instead ofNone). This allows distinguishing betweenNoneas an explicitly given value and an argument that was not provided at all. IfFalse, usesNone(the default, argparse-compatible behavior) unless overridden byargument_default.subclasses_disabled (
list[type|Callable[[type],bool]] |None) – List of types or functions, so that when parsing only the exact type hints (not their subclasses) are accepted. Descendants of the configured types are also disabled. Functions should returnTruefor types to disable.subclasses_enabled (
list[type|str] |None) – List of types or disable function names, so that subclasses are accepted. Types given here have precedence over those insubclasses_disabled. Giving a function name removes the corresponding function fromsubclasses_disabled. By default, the following disable functions are registered:is_pure_dataclass,is_pydantic_model,is_attrs_classandis_final_class.import_path_denylist (
list[str] |None) – Import paths that a value is not allowed to name, added to the ones denied by default. An entry denies a dot import path and everything under it, e.g.osalso deniesos.system. The entry*denies everything, so that only what the allowlist permits is importable.import_path_allowlist (
list[str] |None) – Import paths that a value is allowed to name, taking precedence over the denylist for the same entry. The most specific entry decides, sofunctools.partialhere allows only that path out of a deniedfunctools. Paths underjsonargparseare not accepted, since a value that names them would be able to change these settings.
- Return type:
- jsonargparse.add_instantiator(instantiator, class_type, subclasses=True, prepend=False)
Adds a custom instantiator for a class type. Used by
ArgumentParser.instantiate.Instantiator functions are expected to have as signature
(class_type: Type[ClassType], *args, **kwargs) -> ClassType.For reference, the default instantiator is
return class_type(*args, **kwargs).In some use cases, the instantiator function might need access to values applied by instantiation links. For this, the instantiator function can have an additional keyword parameter
applied_instantiation_links: dict. This parameter will be populated with a dictionary having as keys the targets of the instantiation links and corresponding values that were applied.- Parameters:
- Return type:
- jsonargparse.get_loader(mode)
Returns the current loader function for a given mode.
- jsonargparse.set_loader(mode, loader_fn, exceptions=(), json_superset=True)
Sets the value loader function to be used when parsing with a certain mode.
The
loader_fnfunction must accept as input a single str type parameter and return any of the basic types {str, bool, int, float, list, dict, None}. If this function is not based on PyYAML for things to work correctly the exceptions types that can be raised when parsing a value fails should be provided.- Parameters:
mode (
str) – The parser mode for which to set its loader function. Example: “yaml”.loader_fn (
Callable[[str],Any]) – The loader function to set. Example:yaml.safe_load.exceptions (
tuple[type[Exception],...]) – Exceptions that the loader can raise when load fails. Example: (yaml.YAMLError,).json_superset (
bool) – Whether the loader can load JSON data.
- jsonargparse.set_dumper(format_name, dumper_fn)
Sets the dumping function for a given format name.
- jsonargparse.capture_parser(function, *args, **kwargs)
Returns the parser object used within the execution of a function.
The function execution is stopped on the start of the call to
parse_args. No parsing is done or execution of instructions after theparse_args.- Parameters:
function (
Callable) – A callable that internally creates a parser and callsparse_args.*args – Positional arguments used to run the function.
**kwargs – Keyword arguments used to run the function.
- Raises:
CaptureParserException – If the function does not call
parse_args.- Return type:
ArgumentParser
- jsonargparse.register_unresolvable_import_paths(*modules)
Saves import paths of module objects for which its import path is unresolvable from the object alone.
Objects with unresolvable import paths have the
__module__attribute set toNone.
- class jsonargparse.ActionEnum(**kwargs)
Bases:
objectAn action based on an Enum that maps to-from strings and enum values.
Warning
ActionEnum was deprecated in v3.9.0 and will be removed in v5.0.0. Enums now should be given directly as a type as explained in Enum arguments.
Methods:
__init__(**kwargs)__call__(*args, **kwargs)Call self as a function.
- __init__(**kwargs)
- __call__(*args, **kwargs)
Call self as a function.
- class jsonargparse.ActionJsonnetExtVars(*args, **kwargs)
Bases:
objectAction to add argument to provide ext_vars for jsonnet parsing.
Warning
ActionJsonnetExtVars was deprecated in v4.24.0 and will be removed in v5.0.0. Instead use
type=dict.Methods:
__call__(*args, **kwargs)Call self as a function.
__init__(*args, **kwargs)- __call__(*args, **kwargs)
Call self as a function.
- __init__(*args, **kwargs)
- class jsonargparse.ActionOperators(**kwargs)
Bases:
objectAction to restrict a value with comparison operators.
Warning
ActionOperators was deprecated in v3.0.0 and will be removed in v5.0.0. Now types should be used as explained in Restricted numbers.
Methods:
__init__(**kwargs)__call__(*args, **kwargs)Call self as a function.
- __init__(**kwargs)
- __call__(*args, **kwargs)
Call self as a function.
- class jsonargparse.ActionPath(mode, skip_check=False)
Bases:
objectAction to check and store a path.
Warning
ActionPath was deprecated in v3.11.0 and will be removed in v5.0.0. Paths now should be given directly as a type as explained in Parsing paths.
Methods:
__init__(mode[, skip_check])__call__(*args, **kwargs)Call self as a function.
- __init__(mode, skip_check=False)
- __call__(*args, **kwargs)
Call self as a function.
- class jsonargparse.ActionPathList(mode=None, rel='cwd', **kwargs)
Bases:
ActionAction to check and store a list of file paths read from a plain text file or stream.
Warning
ActionPathList was deprecated in v4.20.0 and will be removed in v5.0.0. Instead use as type
List[<path_type>]withsub_configs=True.Methods:
__init__([mode, rel])Initializer for ActionPathList instance.
__call__(*args, **kwargs)Parses an argument as a PathList and if valid sets the parsed value to the corresponding key.
- __init__(mode=None, rel='cwd', **kwargs)
Initializer for ActionPathList instance.
- Parameters:
- Raises:
ValueError – If any of the parameters (mode or rel) are invalid.
- class jsonargparse.HelpFormatterDeprecations(*args, **kwargs)
Bases:
objectHelper class for DefaultHelpFormatter deprecations. Will be removed in v5.0.0.
Methods:
__init__(*args, **kwargs)add_yaml_comments(cfg)Adds help text as yaml comments.
set_yaml_start_comment(text, cfg)Sets the start comment to a ruamel.yaml object.
set_yaml_group_comment(text, cfg, key, depth)Sets the comment for a group to a ruamel.yaml object.
set_yaml_argument_comment(text, cfg, key, depth)Sets the comment for an argument to a ruamel.yaml object.
- __init__(*args, **kwargs)
- add_yaml_comments(cfg)
Adds help text as yaml comments.
Warning
The add_yaml_comments method is deprecated and will be removed in v5.0.0.
- Return type:
- set_yaml_start_comment(text, cfg)
Sets the start comment to a ruamel.yaml object.
- Args:
text: The content to use for the comment. cfg: The ruamel.yaml object.
Warning
The set_yaml_start_comment method is deprecated and will be removed in v5.0.0.
- set_yaml_group_comment(text, cfg, key, depth)
Sets the comment for a group to a ruamel.yaml object.
- Args:
text: The content to use for the comment. cfg: The parent ruamel.yaml object. key: The key of the group. depth: The nested level of the group.
Warning
The set_yaml_group_comment method is deprecated and will be removed in v5.0.0.
- set_yaml_argument_comment(text, cfg, key, depth)
Sets the comment for an argument to a ruamel.yaml object.
- Args:
text: The content to use for the comment. cfg: The parent ruamel.yaml object. key: The key of the argument. depth: The nested level of the argument.
Warning
The set_yaml_argument_comment method is deprecated and will be removed in v5.0.0.
- class jsonargparse.LoggerProperty(*args, logger=False, **kwargs)
Bases:
LoggerPropertyAdds a logger property, intended for internal use.
Warning
LoggerProperty was deprecated in v4.40.0 and will be removed from the public API in v5.0.0. There is no replacement since jsonargparse is not a logging library. A similar class can be found in reconplogger package.
Methods:
__init__(*args[, logger])- __init__(*args, logger=False, **kwargs)
- class jsonargparse.PathDeprecations
Bases:
objectDeprecated methods for Path.
Methods:
__call__([absolute])
- class jsonargparse.ParserDeprecations(*args, error_handler=False, default_meta=None, **kwargs)
Bases:
objectHelper class for ArgumentParser deprecations. Will be removed in v5.0.0.
Methods:
__init__(*args[, error_handler, default_meta])instantiate_classes(cfg, **kwargs)add_dataclass_arguments(*args, **kwargs)check_config(*args, **kwargs)add_instantiator(instantiator, class_type[, ...])merge_config(cfg_from, cfg_to)Attributes:
Property for the error_handler function that is called when there are parsing errors.
Whether by default metadata is included in config objects.
- __init__(*args, error_handler=False, default_meta=None, **kwargs)
- property error_handler: Callable[[ArgumentParser, str], None] | None
Property for the error_handler function that is called when there are parsing errors.
- getter:
Returns the current error_handler function.
- setter:
Sets a new error_handler function (Callable[self, message:str] or None).
- Raises:
ValueError: If an invalid value is given.
Warning
error_handler property is deprecated and will be removed in v5.0.0.
- property default_meta: bool
Whether by default metadata is included in config objects.
- getter:
Returns the current default metadata setting.
- setter:
Sets the default metadata setting.
- Raises:
ValueError: If an invalid value is given.
Warning
default_metaproperty was deprecated in v4.44.0 and will be removed in v5.0.0. After removal, config objects will always include metadata. To remove metadata from a config object, do.clone(with_meta=False).
- instantiate_classes(cfg, **kwargs)
-
Warning
instantiate_classeswas deprecated in v4.49.0 and will be removed in v5.0.0. Instead useinstantiate.
- instantiate_subclasses(cfg)
- Return type:
Warning
instantiate_subclasses was deprecated in v4.0.0 and will be removed in v5.0.0. Instead use instantiate.
- add_dataclass_arguments(*args, **kwargs)
Warning
add_dataclass_arguments was deprecated in v4.35.0 and will be removed in v5.0.0. Instead use add_class_arguments.
- check_config(*args, **kwargs)
Warning
ArgumentParser.check_config was deprecated in v4.35.0 and will be removed in v5.0.0. Instead use validate.
- add_instantiator(instantiator, class_type, subclasses=True, prepend=False)
- Return type:
Warning
ArgumentParser.add_instantiatorwas deprecated in v4.49.0 and will be removed in v5.0.0. Use the global functionjsonargparse.add_instantiatorinstead.
- jsonargparse.ParserError
alias of
ArgumentError
- jsonargparse.compose_dataclasses(*args)
Returns a dataclass inheriting all given dataclasses and properly handling __post_init__.
Warning
compose_dataclasses is deprecated and will be removed in v5.0.0. There is no direct replacement, whoever is interested can copy the code from an old release.
- jsonargparse.get_config_read_mode()
Returns the current config reading mode.
Warning
get_config_read_mode was deprecated in v4.39.0 and will be removed in v5.0.0. The config read mode is internal and thus shouldn’t be used.
- Return type:
- jsonargparse.dict_to_namespace(cfg_dict)
Converts a nested dictionary into a nested namespace.
Warning
dict_to_namespace was deprecated in v4.43.0 and will be removed in v5.0.0. No replacement is provided because blindly converting a dictionary to a namespace may not yield the same results as using a parser, which could lead to confusion.
- Return type:
- jsonargparse.namespace_to_dict(namespace)
Returns a copy of a nested namespace converted into a nested dictionary.
Warning
namespace_to_dict was deprecated in v4.40.0 and will be removed in v5.0.0. Instead you can use
.clone().as_dict()or.as_dict().
- jsonargparse.set_docstring_parse_options(style=None, attribute_docstrings=None)
Sets options for docstring parsing.
Warning
set_docstring_parse_options was deprecated in v4.39.0 and will be removed in v5.0.0. Docstring parse options should now be set using function set_parsing_settings.
- jsonargparse.set_config_read_mode(urls_enabled=False, fsspec_enabled=False)
Enables/disables optional config read modes.
Warning
set_config_read_mode was deprecated in v4.39.0 and will be removed in v5.0.0. Optional config read modes should now be set using function set_parsing_settings.
- jsonargparse.set_url_support(enabled)
Enables/disables URL support for config read mode.
Warning
set_url_support was deprecated in v3.12.0 and will be removed in v5.0.0. Optional config read modes should now be set using function set_parsing_settings.
- jsonargparse.strip_meta(cfg)
Removes all metadata keys from a configuration object.
- Overloads:
cfg (Namespace) → Namespace
cfg (Dict[str, Any]) → Dict[str, Any]
Warning
strip_meta was deprecated in v4.43.0 and will be removed in v5.0.0. Instead use
.clone(with_meta=False).
- jsonargparse.usage_and_exit_error_handler(parser, message)
Prints the usage and exits with error code 2 (same behavior as argparse).
- Args:
parser: The parser object. message: The message describing the error being handled.
Warning
usage_and_exit_error_handler was deprecated in v4.20.0 and will be removed in v5.0.0. With the removal of error_handler, there is no longer a need for this function.
- Return type:
- jsonargparse.Unset = Unset
Sentinel class for unset argument values.
jsonargparse.typing
Collection of types and type generators.
Functions:
|
Decorator to make a class |
|
Checks whether a class is final, i.e. decorated with |
|
Registers a new type for use in jsonargparse parsers. |
|
Creates and registers an extension of base type. |
|
Creates or returns an already registered restricted number type class. |
|
Creates or returns an already registered restricted string type class. |
|
Creates or returns an already registered path type class. |
|
Creates a dynamic class which if instantiated is equivalent to calling func. |
|
Instantiates a lazy instance of the given type. |
Classes:
|
int restricted to be >0 |
int restricted to be ≥0 |
|
float restricted to be >0 |
|
float restricted to be ≥0 |
|
float restricted to be ≥0 and ≤1 |
|
float restricted to be >0 and <1 |
|
|
Holds a secret string that serializes to |
|
str restricted to not-empty pattern |
|
str restricted to the email pattern |
|
Base class for Path types. |
|
path to a file that exists and is readable |
|
path to a file that can be created if it does not exist |
|
path to a directory that exists and is writable |
|
path to a directory that can be created if it does not exist |
|
path to a directory that exists and is readable and writable |
- jsonargparse.typing.final(cls)
Decorator to make a class
final, i.e., it shouldn’t be subclassed.It is the same as
typing.finalor an equivalent implementation depending on the python version and whether typing-extensions is installed.
- jsonargparse.typing.is_final_class(cls)
Checks whether a class is final, i.e. decorated with
typing.final.- Return type:
- jsonargparse.typing.register_type(class_type, serializer=<class 'str'>, deserializer=None, deserializer_exceptions=(<class 'ValueError'>, <class 'TypeError'>, <class 'AttributeError'>), type_check=<function <lambda>>, fail_already_registered=False, uniqueness_key=None)
Registers a new type for use in jsonargparse parsers.
- Parameters:
class_type (
type|TypeAliasType) – The class to be registered. A generic class is registered unsubscripted and its registration also applies to its subscripted forms. Python 3.12+ also supportsTypeAliasTypealiases.serializer (
Callable) – Function that converts an instance of the class to a basic type.deserializer (
Callable|None) – Function that converts a basic type to an instance of the class. Default instantiatesclass_type.deserializer_exceptions (
type[Exception] |tuple[type[Exception],...]) – Exceptions that deserializer raises when it fails.type_check (
Callable) – Function to check if a value is ofclass_type. Gets as arguments the value andclass_type.fail_already_registered (
bool) – Whether to fail instead of replacing a previous registration of the type.uniqueness_key (
tuple|None) – Key to determine uniqueness of type.
- Return type:
- jsonargparse.typing.extend_base_type(name, base_type, validation_fn, docstring=None, extra_attrs=None, register_key=None)
Creates and registers an extension of base type.
- Parameters:
name (
str) – How the new type will be called.base_type (
type) – The type from which the created type is extended.validation_fn (
Callable) – Function that validates the value on instantiation/casting. Gets two arguments:class_typeandvalue.docstring (
str|None) – The__doc__attribute value for the created type.extra_attrs (
dict|None) – Attributes set to the type class that thevalidation_fncan access.register_key (
tuple|None) – Used to determine the uniqueness of registered types.
- Raises:
ValueError – If the type has already been registered with a different name.
- Return type:
TypeAlias
- jsonargparse.typing.restricted_number_type(name, base_type, restrictions, join='and', docstring=None)
Creates or returns an already registered restricted number type class.
- Parameters:
- Return type:
TypeAlias- Returns:
The created or retrieved type class.
- jsonargparse.typing.restricted_string_type(name, regex, docstring=None)
Creates or returns an already registered restricted string type class.
- jsonargparse.typing.path_type(mode, docstring=None, **kwargs)
Creates or returns an already registered path type class.
- jsonargparse.typing.class_from_function(func, func_return=None, name=None)
Creates a dynamic class which if instantiated is equivalent to calling func.
- Parameters:
func (
Callable[...,TypeVar(ClassType)]) – A function that returns an instance of a class.func_return (
type[TypeVar(ClassType)] |None) – The return type of the function. Required if func does not have a return type annotation.name (
str|None) – The name of the class. Defaults to function name suffixed with_class.
- Return type:
- jsonargparse.typing.lazy_instance(class_type, **kwargs)
Instantiates a lazy instance of the given type.
By lazy it is meant that the
__init__is delayed until the first time that a method of the instance is called. It also provides a lazy_get_init_data method useful for serializing.
- class jsonargparse.typing.ClosedUnitInterval(v)
Bases:
TypeCore,floatfloat restricted to be ≥0 and ≤1
- class jsonargparse.typing.OpenUnitInterval(v)
Bases:
TypeCore,floatfloat restricted to be >0 and <1
- class jsonargparse.typing.SecretStr(value)
Bases:
objectHolds a secret string that serializes to
**********.Methods:
__init__(value)Returns the actual secret value.
- __init__(value)
- class jsonargparse.typing.NotEmptyStr(v)
Bases:
TypeCore,strstr restricted to not-empty pattern
^.*[^ ].*$
- class jsonargparse.typing.Email(v)
Bases:
TypeCore,strstr restricted to the email pattern
^[^@ ]+@[^@ ]+\.[^@ ]+$
- class jsonargparse.typing.Path(path, mode='fr', cwd=None, **kwargs)
Bases:
PathDeprecationsBase class for Path types. Stores a (possibly relative) path and the corresponding absolute path.
From the object the absolute path can be obtained without having to remember the working directory (or parent remote path) from when the object was created.
When a Path instance is created, it is checked that: the path exists, whether it is a file or directory and whether it has the required access permissions (f=file, d=directory, r=readable, w=writable, x=executable, c=creatable, u=url, s=fsspec or in uppercase meaning not, i.e., F=not-file, D=not-directory, R=not-readable, W=not-writable and X=not-executable).
The creatable flag “c” can be given one or two times. If given once, the parent directory must exist and be writable. If given twice, the parent directory does not have to exist, but should be allowed to create.
An instance of Path class can also refer to the standard input or output. To do that, path must be set with the value “-”; it is a common practice. Then, getting the content or opening it will automatically be done on standard input or output.
Methods:
__init__(path[, mode, cwd])Initializer for Path instance.
Returns the text contents of the file or the remote path.
open([mode])Return an opened file object for the path.
Context manager to use this path's parent (directory or URL) for relative paths defined within.
Attributes:
Returns the relative representation of the path (how the path was given on instance creation).
Returns the absolute representation of the path.
- __init__(path, mode='fr', cwd=None, **kwargs)
Initializer for Path instance.
- Parameters:
- Raises:
ValueError – If the provided mode is invalid.
PathError – If the path does not exist or does not agree with the mode.
- class jsonargparse.typing.Path_fr(v, **k)
Bases:
PathTypepath to a file that exists and is readable
- class jsonargparse.typing.Path_fc(v, **k)
Bases:
PathTypepath to a file that can be created if it does not exist
- class jsonargparse.typing.Path_dw(v, **k)
Bases:
PathTypepath to a directory that exists and is writable
- class jsonargparse.typing.Path_dc(v, **k)
Bases:
PathTypepath to a directory that can be created if it does not exist
- class jsonargparse.typing.Path_drw(v, **k)
Bases:
PathTypepath to a directory that exists and is readable and writable