https://readthedocs.org/projects/jsonargparse/badge/?version=stable https://github.com/mauvilsa/jsonargparse/actions/workflows/tests.yaml/badge.svg https://codecov.io/gh/mauvilsa/jsonargparse/branch/main/graph/badge.svg https://sonarcloud.io/api/project_badges/measure?project=mauvilsa_jsonargparse&metric=alert_status&token=74f3ff0af709f6caa0544dfbcf823c49fb68cb46 https://badge.fury.io/py/jsonargparse.svg

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.

Teaser examples

CLI with minimal boilerplate:

from jsonargparse import auto_cli

def main_function(...):  # your main parameters with type hints here
    ...  # your main code here

if __name__ == "__main__":
    auto_cli(main_function)  # parses arguments and runs main_function

Minimal boilerplate but manually parsing:

from jsonargparse import auto_parser

parser = auto_parser(main_function)
cfg = parser.parse_args()
...

Powerful argparse-like low level parsers:

from jsonargparse import ArgumentParser

parser = ArgumentParser()
parser.add_argument("--config", action="config")  # support config files
parser.add_argument("--opt", type=int | Literal["off"])  # complex arguments via type hints
parser.add_function_arguments(main_function, "function")  # add function parameters
parser.add_class_arguments(SomeClass, "class")  # add class parameters
...
cfg = parser.parse_args()
init = parser.instantiate(cfg)
...

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:

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:

  1. Defaults defined in the source code.

  2. Existing default config files in the order defined in default_config_files, e.g. ~/.config/myapp.yaml.

  3. Full config environment variable, e.g. APP_CONFIG.

  4. Individual key environment variables, e.g. APP_OPT1.

  5. 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 nargs or nargs=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, and add_argument received no default.

  • None – either explicitly set to null, or add_argument received default=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 of List[<type>]) and 604 (<type> | <type> instead of Union[<type>, <type>]).

  • Types that use components imported inside TYPE_CHECKING blocks 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, OrderedDict and TypedDict are supported, but only with str or int keys, see Dict items.

  • TypedDict accepts Required and NotRequired to mark single keys as required or optional, and Unpack to type **kwargs precisely, see PEP 692. A --*.help option, e.g. --data.help, shows the accepted keys. It takes no value, unless the TypedDict is 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_arguments also accepts a TypedDict, adding one argument per key and giving the corresponding dict on instantiate. As the argument of type, e.g. type[SomeTypedDict], the value is an import path to a class. Since TypedDict classes don’t support issubclass, 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 generic TypedDict works both unsubscripted and subscripted, e.g. SomeDict and SomeDict[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 a TypeVar. A key whose type can’t be validated accepts any value, see Unvalidated types.

  • tuple, set, frozenset, AbstractSet and MutableSet are supported, even though on the command line, in config files and in environment variables they are all written as an array, like a list. Each tuple position can have its own type, which is validated as such, and tuple[type, ...] is also accepted. A set or frozenset of a class type is kept as a list when parsing, since subclass specs are not hashable, and becomes a set on instantiate.

  • None is written as null, as JSON/YAML define it. For the same reason the help shows NoneType as null, e.g. a parameter with type and default Optional[str] = None is shown as type: Union[str, null], default: null.

  • Normal classes can be used as a type. The value is a dict with a class_path and optionally init_args, and instantiate instantiates all classes in a config object, see Class type and subclasses.

  • Protocol types work the same as subclasses and don’t need to be runtime_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 or Any, which accept any type. A generic protocol works both unsubscripted and subscripted, e.g. Proto and Proto[int]. Subscripting substitutes the type arguments in the protocol’s methods, so Proto[int] and Proto[str] accept different implementations. A TypeVar that 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’s dataclass and pydantic’s BaseModel are 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 Generic types are supported, see Generic types.

  • Annotated types are supported. If the metadata is a pydantic type, it is used for validation.

  • pydantic.SecretStr is supported and, as expected, the actual value is not serialized. jsonargparse.typing.SecretStr gives 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_config is not used with the mask as the secret.

  • pydantic.FilePath and pydantic.DirectoryPath run the corresponding pydantic validation when parsing. Arguments with these types also get file and directory tab completions, see Completion scripts.

  • Callable accepts either a dot import path to a callable object, or a dict with class_path and optionally init_args. The named class must either instantiate into a callable or be a subclass of the callable’s return type. instantiate then 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.ModuleType accepts the dot import path of a module, and on instantiate is replaced by the imported module object.

  • types.UnionType and types.GenericAlias, commonly found in third party libraries in unions such as type | 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, typing names or dot import paths.

  • TypeAliasType is 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 695 type X = ... statement (Python 3.12+) and aliases created with typing_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:

  1. All types not mentioned below, in the order in which they are written.

  2. None, which only accepts null. It is placed second to last so that Optional[<type>] reads in the help as it does in the source code.

  3. Any, object and 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 TypeVar that 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. the init_args of 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' gives 0.001, while default PyYAML gives the string '1e-3'.

  • Dates are kept as strings, e.g. '2020-01-01', while default PyYAML gives a datetime.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_untyped decides which parameters without a type annotation raise an exception instead: the required ones with the default True, all of them with "all", and none with False. 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 skip parameter 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 PositiveInt and Email. For the plain argparse actions, which have no type hint, this is what the action gives, e.g. a boolean for store_true, an integer for count, the possible values for store_const and an array for append.

  • 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. Without unset_sentinel, a None default counts as unset, so null is never described as a default. With it, an explicit default=None is described, as long as the type accepts null.

  • Descriptions taken from the docstrings of the classes and functions that the arguments come from, or from the help given to add_argument.

  • For subclass types, one entry per known subclass, each with a class_path fixed to that subclass and an init_args object describing the accepted init parameters of that specific class.

  • For parsers with subcommands, one object per subcommand and a subcommand key. 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.parametrize when 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 logger fixture and capture_logs context manager from conftest.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:

ArgumentError(argument, message)

An error from creating or using an argument (optional or positional).

ParserError

Functions:

auto_cli([components, args, config_help, ...])

Simple creation of command line interfaces.

auto_parser(*args, **kwargs)

Same as auto_cli(), but returns the parser, doesn't parse arguments or run.

set_parsing_settings(*[, validate_defaults, ...])

Modify global parser settings that affect parser creation and parsing behavior.

add_instantiator(instantiator, class_type[, ...])

Adds a custom instantiator for a class type.

get_loader(mode)

Returns the current loader function for a given mode.

set_loader(mode, loader_fn[, exceptions, ...])

Sets the value loader function to be used when parsing with a certain mode.

set_dumper(format_name, dumper_fn)

Sets the dumping function for a given format name.

capture_parser(function, *args, **kwargs)

Returns the parser object used within the execution of a function.

register_unresolvable_import_paths(*modules)

Saves import paths of module objects for which its import path is unresolvable from the object alone.

compose_dataclasses(*args)

Returns a dataclass inheriting all given dataclasses and properly handling __post_init__.

get_config_read_mode()

Returns the current config reading mode.

dict_to_namespace(cfg_dict)

Converts a nested dictionary into a nested namespace.

namespace_to_dict(namespace)

Returns a copy of a nested namespace converted into a nested dictionary.

set_docstring_parse_options([style, ...])

Sets options for docstring parsing.

set_config_read_mode([urls_enabled, ...])

Enables/disables optional config read modes.

set_url_support(enabled)

Enables/disables URL support for config read mode.

strip_meta(cfg)

Removes all metadata keys from a configuration object.

usage_and_exit_error_handler(parser, message)

Prints the usage and exits with error code 2 (same behavior as argparse).

Classes:

ArgumentParser(*args[, env_prefix, ...])

Parser for command line, configuration files and environment variables.

FromConfigMixin()

Mixin class that adds from config support to classes.

ActionSubCommands(option_strings, prog, ...)

Extension of argparse._SubParsersAction to modify subcommands functionality.

ActionJsonSchema([schema, sub_config, with_meta])

Action to parse option as JSON validated by a JSON Schema.

ActionJsonnet([ext_vars, schema])

Action to parse a Jsonnet, optionally validating against a JSON Schema.

ActionFail([message])

Action that always fails parsing with a given error.

ActionYesNo([yes_prefix, no_prefix])

Paired options --[yes_prefix]opt, --[no_prefix]opt to set True or False respectively.

ActionParser(parser)

Action to parse option with a given parser optionally loading from file if string value.

Namespace(*args, **kwargs)

Extension of argparse's Namespace to support nesting and subscript access.

DefaultHelpFormatter(*args, **kwargs)

Help message formatter that includes types, default values and env var names.

ActionEnum(**kwargs)

An action based on an Enum that maps to-from strings and enum values.

ActionJsonnetExtVars(*args, **kwargs)

Action to add argument to provide ext_vars for jsonnet parsing.

ActionOperators(**kwargs)

Action to restrict a value with comparison operators.

ActionPath(mode[, skip_check])

Action to check and store a path.

ActionPathList([mode, rel])

Action to check and store a list of file paths read from a plain text file or stream.

HelpFormatterDeprecations(*args, **kwargs)

Helper class for DefaultHelpFormatter deprecations.

LoggerProperty(*args[, logger])

Adds a logger property, intended for internal use.

PathDeprecations()

Deprecated methods for Path.

ParserDeprecations(*args[, error_handler, ...])

Helper class for ArgumentParser deprecations.

exception jsonargparse.ArgumentError(argument, message)

Bases: Exception

An 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 or None to use sys.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]) – The ArgumentParser subclass 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:

ArgumentParser

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, ArgumentParser

Parser 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 NotImplementedError since typos in configs would go unnoticed.

add_subparsers(*args, **kwargs)

Raises NotImplementedError since jsonargparse uses add_subcommands.

Attributes:

default_config_files

Default config file locations.

default_env

Whether by default environment variables parsing is enabled.

env_prefix

The environment variables prefix property.

parser_mode

Mode for parsing config files, yaml, json, jsonnet or ones added via set_loader().

dump_header

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. True to derive from prog.

  • 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 --version argument.

  • print_config (str | None) – Name for print config argument, %s is replaced by config dest, set None to disable.

  • parser_mode (str) – Mode for parsing values: yaml, json, jsonnet or added via set_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:
  • args (Sequence[str] | None) – List of arguments to parse or None to use sys.argv.

  • env (bool | None) – Whether to merge with the parsed environment, None to use the parser’s default.

  • defaults (bool) – Whether to merge with the parser’s defaults.

Return type:

Namespace

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:
  • obj (Namespace | dict[str, Any]) – The configuration object.

  • env (bool | None) – Whether to merge with the parsed environment, None to use the parser’s default.

  • defaults (bool) – Whether to merge with the parser’s defaults.

Return type:

Namespace

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:
  • env (dict[str, str] | None) – The environment object to use, if None then os.environ is used.

  • defaults (bool) – Whether to merge with the parser’s defaults.

Return type:

Namespace

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, None to use the parser’s default.

  • defaults (bool) – Whether to merge with the parser’s defaults.

Return type:

Namespace

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, None to use the parser’s default.

  • defaults (bool) – Whether to merge with the parser’s defaults.

Return type:

Namespace

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 the parser.groups dict.

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.

  • nested_key (str | None) – Key for nested namespace.

  • 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:

list[str]

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.

  • nested_key (str | None) – Key for nested namespace.

  • 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:

list[str]

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.

  • nested_key (str | None) – Key for nested namespace.

  • 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 by instantiate.

  • 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:

list[str]

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_path entry which must be a import dot notation expression. Optionally any init arguments for the class can be given in the init_args entry. 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.

Makes an argument value be derived from the values of other arguments.

Refer to Argument linking for a detailed explanation and examples.

Parameters:
  • source (str | tuple[str, ...]) – Key(s) from which the target value is derived.

  • target (str) – Key to where the value is set.

  • compute_fn (Callable | None) – Function to compute target value from source.

  • apply_on (str) – At what point to set target value, ‘parse’ or ‘instantiate’.

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 subcommand and the parsed values of the subcommand are stored in a nested namespace using the subcommand’s name as base key.

Parameters:
Return type:

ActionSubCommands

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_mode or ones added via set_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 for format="yaml".

  • skip_link_targets (bool) – Whether to exclude link targets.

Return type:

str

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_mode or ones added via set_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:

None

get_default(dest)

Gets a single default value for the given destination key.

Parameters:

dest (str) – Destination key from which to get the default.

Raises:

KeyError – If key or its default not defined in the parser.

Return type:

Any

get_defaults(skip_validation=False, **kwargs)

Returns a namespace with all default values.

Parameters:

skip_validation (bool) – Whether to skip validation of defaults.

Return type:

Namespace

Returns:

An object with all default values as attributes.

set_defaults(*args, **kwargs)

Sets default values from dictionary or keyword arguments.

Parameters:
  • *args (dict[str, Any]) – Dictionary defining the default values to set.

  • **kwargs (Any) – Sets default values based on keyword arguments.

Raises:

KeyError – If key not defined in the parser.

Return type:

None

get_completion_script(completion_type, **kwargs)

Returns a shell completion script or a JSON Schema for a completion type.

Return type:

str

error(message, ex=None)

Logs error message if a logger is set and exits or raises an ArgumentError.

Return type:

NoReturn

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:
  • namespace (Namespace) – The configuration object to check.

  • skip_unset (bool) – Whether to skip checking of values that are the configured None/Unset value.

  • skip_required (bool) – Whether to skip checking required arguments.

  • branch (str | None) – Base key in case cfg corresponds only to a branch.

Raises:
  • TypeError – If any of the values are not valid.

  • KeyError – If a key in cfg is not defined in the parser.

Return type:

None

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_argument with a class type or add_class_arguments/add_subclass_arguments): An object with class_path and optionally init_args is replaced by an instance of the referenced class, created by calling class_type(**init_args). For the case of classes with disabled subclasses, the namespace can have directly the init args without the class_path + init_args wrapper.

  • Callable type arguments: A dot-import string pointing to a function or method is resolved to the callable object. When class_path/init_args is 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 — a functools.partial() bound to the given init_args.

  • Instantiation order: Components are processed in the order determined by argument links applied on instantiation.

Parameters:
  • namespace (Namespace) – The configuration object to use. Must have been produced by one of the parse_* methods and not modified in a way that breaks the structure expected by the parser.

  • instantiate_groups (bool) – Whether class groups should be instantiated.

Return type:

Namespace

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.

Parameters:

namespace (Namespace) – The configuration object to strip.

Return type:

Namespace

Returns:

The stripped configuration object.

get_config_files(namespace)

Returns a list of loaded config file paths.

Parameters:

namespace (Namespace) – The configuration object.

Return type:

list[str]

Returns:

Paths to loaded config files.

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_ENV environment 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, jsonnet or ones added via set_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 NotImplementedError since typos in configs would go unnoticed.

Return type:

NoReturn

add_subparsers(*args, **kwargs)

Raises NotImplementedError since jsonargparse uses add_subcommands.

Return type:

NoReturn

class jsonargparse.FromConfigMixin

Bases: object

Mixin class that adds from config support to classes.

This mixin does two things:

  1. 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.

  2. Adds a from_config @classmethod, that instantiates the class based on a config file or dict. If config_read_mode_fsspec_enabled=True is 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.

classmethod from_config(config)

Instantiate current class based on a config file or dict.

Parameters:

config (str | PathLike | dict) – Path to a config file or a dict with config values.

Return type:

TypeVar(T)

class jsonargparse.ActionSubCommands(option_strings, prog, parser_class, dest='==SUPPRESS==', required=False, help=None, metavar=None)

Bases: _SubParsersAction

Extension of argparse._SubParsersAction to modify subcommands functionality.

Methods:

add_parser(*args, **kwargs)

Raises a NotImplementedError since jsonargparse uses add_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 NotImplementedError since jsonargparse uses add_subcommand.

Return type:

NoReturn

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: Action

Action 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.

Parameters:
  • schema (str | dict | None) – Schema to validate values against.

  • sub_config (bool) – Whether to try to load JSON from path.

  • with_meta (bool) – Whether to include metadata.

Raises:
  • ValueError – If a parameter is invalid.

  • jsonschema.exceptions.SchemaError – If the schema is invalid.

__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: Action

Action 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_vars if defined.

split_ext_vars(ext_vars)

Splits an ext_vars dict into the ext_codes and ext_vars required 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.

Parameters:
  • ext_vars (str | None) – Key where to find the external variables required to parse the Jsonnet.

  • schema (str | dict | None) – Schema to validate values against.

Raises:
  • ValueError – If a parameter is invalid.

  • jsonschema.exceptions.SchemaError – If the schema is invalid.

__call__(*args, **kwargs)

Parses an argument as Jsonnet using ext_vars if defined.

Raises:

TypeError – If the argument is not valid.

static split_ext_vars(ext_vars)

Splits an ext_vars dict into the ext_codes and ext_vars required by Jsonnet.

Parameters:

ext_vars (dict[str, Any] | None) – External variables. Values can be strings or any other basic type.

Return type:

tuple[dict[str, Any], dict[str, Any]]

parse(jsonnet, ext_vars=None, with_meta=False)

Method that can be used to parse Jsonnet independent from an ArgumentParser.

Parameters:
  • jsonnet (str | Path) – Either a path to a Jsonnet file or the Jsonnet content.

  • ext_vars (dict[str, Any] | None) – External variables. Values can be strings or any other basic type.

  • with_meta (bool) – Whether to include metadata in config object.

Return type:

dict

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: Action

Action 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)s to include the option and/or value.

__call__(*args, **kwargs)

Always fails with given message.

class jsonargparse.ActionYesNo(yes_prefix='', no_prefix='no_', **kwargs)

Bases: Action

Paired options --[yes_prefix]opt, --[no_prefix]opt to set True or False respectively.

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:
  • yes_prefix (str) – Prefix for yes option.

  • no_prefix (str) – Prefix for no option.

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: object

Action 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: Namespace

Extension 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 positional Namespace or dict object can be given.

as_dict()

Converts the nested namespaces into nested dictionaries.

Return type:

dict[str, Any]

as_flat()

Converts the nested namespaces into a single argparse flat namespace.

Return type:

Namespace

items(branches=False, nested=True)

Returns a generator of all leaf (key, value) items, optionally including branches.

Return type:

Iterator[tuple[str, Any]]

keys(branches=False, nested=True)

Returns a generator of all leaf keys, optionally including branches.

Return type:

Iterator[str]

values(branches=False)

Returns a generator of all leaf values, optionally including branches.

Return type:

Iterator[Any]

clone(with_meta=True)

Creates an new copy of the nested namespace.

Parameters:

with_meta (bool) – Whether to include metadata keys in the copy.

Return type:

Namespace

update(value, key=None, only_unset=False)

Sets or replaces all items from the given nested namespace.

Parameters:
  • value (Namespace | Any) – A namespace to update multiple values or other type to set in a single key.

  • key (str | None) – Branch key where to set the value. Required if value is not namespace.

  • only_unset (bool) – Whether to only set the value if not set in namespace.

Return type:

Namespace

get(key, default=None)

Returns the value for the given key if it exists, otherwise the default.

Return type:

Any

pop(key, default=None)

Removes the given key and returns its value if it exists, otherwise the default.

Return type:

Any

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.

Return type:

list[str]

get_value_and_parent(key)

Deprecated method

Warning

get_value_and_parent 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 get the parent and leaf separately.

Return type:

tuple[Any, Namespace, str]

class jsonargparse.DefaultHelpFormatter(*args, **kwargs)

Bases: HelpFormatterDeprecations, HelpFormatter

Help 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=True command line options are preceded by ARG: and the respective environment variable name is included preceded by ENV:.

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 is False, meaning no default validation, like in argparse.

  • validate_subclass_spec_in_any (bool | None) – If True, 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 a class_path key), 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 is False, 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) – Whether instantiate builds the class when a value for a type that accepts any value, i.e. Any, object or Unvalidated<...>, is a valid subclass spec. If False, the value is kept as a subclass spec, which the code that receives it can instantiate itself if desired. Currently the default is True and a deprecation warning is emitted, since from v5.0.0 the default will be False. 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 is False.

  • config_read_mode_fsspec_enabled (bool | None) – Whether to read config files from fsspec supported file systems. Default is False.

  • docstring_parse_style (DocstringStyle | None) – The docstring style to expect. Default is DocstringStyle.AUTO.

  • docstring_parse_attribute_docstrings (bool | None) – Whether to parse attribute docstrings (slower). Default is False.

  • parse_optionals_as_positionals (bool | None) – If True, 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=value as 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 is False.

  • add_print_completion_argument (bool | None) – If True, top-level parsers automatically include a --print_completion argument. Its accepted values are jsonschema and, when shtab is installed, one shtab-* value per supported shell.

  • stubs_resolver_allow_py_files (bool | None) – Whether the stubs resolver should search in .py files in addition to .pyi files.

  • omegaconf_absolute_to_relative_paths (bool | None) – If True, when loading configs with omegaconf+ parser mode, absolute interpolation paths are converted to relative. This is only intended for backward compatibility with omegaconf parser mode.

  • unset_sentinel (bool | None) – If True, parsers will use the Unset sentinel for arguments that have not been given a value (instead of None). This allows distinguishing between None as an explicitly given value and an argument that was not provided at all. If False, uses None (the default, argparse-compatible behavior) unless overridden by argument_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 return True for 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 in subclasses_disabled. Giving a function name removes the corresponding function from subclasses_disabled. By default, the following disable functions are registered: is_pure_dataclass, is_pydantic_model, is_attrs_class and is_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. os also denies os.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, so functools.partial here allows only that path out of a denied functools. Paths under jsonargparse are not accepted, since a value that names them would be able to change these settings.

Return type:

None

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:
  • instantiator (InstantiatorCallable) – Function that instantiates a class.

  • class_type (type[TypeVar(ClassType)]) – The class type to instantiate.

  • subclasses (bool) – Whether to instantiate subclasses of class_type.

  • prepend (bool) – Whether to prepend the instantiator to the existing instantiators.

Return type:

None

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_fn function 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.

Parameters:
  • format_name (str) – Name to use for dumping with this function. Example: yaml_custom.

  • dumper_fn (Callable[[Any], str]) – The dumper function to set. Example: yaml.safe_dump.

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 the parse_args.

Parameters:
  • function (Callable) – A callable that internally creates a parser and calls parse_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 to None.

class jsonargparse.ActionEnum(**kwargs)

Bases: object

An 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: object

Action 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: object

Action 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: object

Action 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: Action

Action 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>] with sub_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:
  • mode (Optional[str]) – The required type and access permissions among [fdrwxcuFDRWX] as a keyword argument (uppercase means not), e.g. ActionPathList(mode=’fr’).

  • rel (str) – Whether relative paths are with respect to current working directory ‘cwd’ or the list’s parent directory ‘list’.

Raises:

ValueError – If any of the parameters (mode or rel) are invalid.

__call__(*args, **kwargs)

Parses an argument as a PathList and if valid sets the parsed value to the corresponding key.

Raises:

TypeError – If the argument is not a valid PathList.

class jsonargparse.HelpFormatterDeprecations(*args, **kwargs)

Bases: object

Helper 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:

str

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: LoggerProperty

Adds 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: object

Deprecated methods for Path.

Methods:

__call__([absolute])

__call__(absolute=True)
Return type:

str

Warning

Calling Path objects is deprecated and will be removed in v5.0.0. Use the absolute or relative properties instead.

class jsonargparse.ParserDeprecations(*args, error_handler=False, default_meta=None, **kwargs)

Bases: object

Helper class for ArgumentParser deprecations. Will be removed in v5.0.0.

Methods:

__init__(*args[, error_handler, default_meta])

instantiate_classes(cfg, **kwargs)

instantiate_subclasses(cfg)

add_dataclass_arguments(*args, **kwargs)

check_config(*args, **kwargs)

add_instantiator(instantiator, class_type[, ...])

merge_config(cfg_from, cfg_to)

Attributes:

error_handler

Property for the error_handler function that is called when there are parsing errors.

default_meta

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_meta property 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)
Return type:

Union[Namespace, Dict[str, Any]]

Warning

instantiate_classes was deprecated in v4.49.0 and will be removed in v5.0.0. Instead use instantiate.

instantiate_subclasses(cfg)
Return type:

Namespace

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:

None

Warning

ArgumentParser.add_instantiator was deprecated in v4.49.0 and will be removed in v5.0.0. Use the global function jsonargparse.add_instantiator instead.

merge_config(cfg_from, cfg_to)
Return type:

Namespace

Warning

ArgumentParser.merge_config was deprecated in v4.50.0 and will be removed in v5.0.0. There is no replacement since this is for internal use.

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:

str

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:

Namespace

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

Return type:

Dict[str, Any]

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:

None

jsonargparse.Unset = Unset

Sentinel class for unset argument values.

jsonargparse.typing

Collection of types and type generators.

Functions:

final(cls)

Decorator to make a class final, i.e., it shouldn't be subclassed.

is_final_class(cls)

Checks whether a class is final, i.e. decorated with typing.final.

register_type(class_type[, serializer, ...])

Registers a new type for use in jsonargparse parsers.

extend_base_type(name, base_type, validation_fn)

Creates and registers an extension of base type.

restricted_number_type(name, base_type, ...)

Creates or returns an already registered restricted number type class.

restricted_string_type(name, regex[, docstring])

Creates or returns an already registered restricted string type class.

path_type(mode[, docstring])

Creates or returns an already registered path type class.

class_from_function(func[, func_return, name])

Creates a dynamic class which if instantiated is equivalent to calling func.

lazy_instance(class_type, **kwargs)

Instantiates a lazy instance of the given type.

Classes:

PositiveInt(v)

int restricted to be >0

NonNegativeInt(v)

int restricted to be ≥0

PositiveFloat(v)

float restricted to be >0

NonNegativeFloat(v)

float restricted to be ≥0

ClosedUnitInterval(v)

float restricted to be ≥0 and ≤1

OpenUnitInterval(v)

float restricted to be >0 and <1

SecretStr(value)

Holds a secret string that serializes to **********.

NotEmptyStr(v)

str restricted to not-empty pattern ^.*[^ ].*$

Email(v)

str restricted to the email pattern ^[^@ ]+@[^@ ]+\.[^@ ]+$

Path(path[, mode, cwd])

Base class for Path types.

Path_fr(v, **k)

path to a file that exists and is readable

Path_fc(v, **k)

path to a file that can be created if it does not exist

Path_dw(v, **k)

path to a directory that exists and is writable

Path_dc(v, **k)

path to a directory that can be created if it does not exist

Path_drw(v, **k)

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.final or 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:

bool

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 supports TypeAliasType aliases.

  • 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 instantiates class_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 of class_type. Gets as arguments the value and class_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:

None

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_type and value.

  • docstring (str | None) – The __doc__ attribute value for the created type.

  • extra_attrs (dict | None) – Attributes set to the type class that the validation_fn can 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:
  • name (str | None) – Name for the type or None for an automatic name.

  • base_type (type) – One of {int, float}.

  • restrictions (tuple | list[tuple]) – Tuples of pairs (comparison, reference), e.g. ('>', 0).

  • join (str) – How to combine multiple comparisons, one of {'or', 'and'}.

  • docstring (str | None) – Docstring for the type class.

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.

Parameters:
  • name (str) – Name for the type or None for an automatic name.

  • regex (str | Pattern) – Regular expression that the string must match.

  • docstring (str | None) – Docstring for the type class.

Return type:

TypeAlias

Returns:

The created or retrieved type class.

jsonargparse.typing.path_type(mode, docstring=None, **kwargs)

Creates or returns an already registered path type class.

Parameters:
  • mode (str) – The required type and access permissions among [fdrwxcuFDRWX].

  • docstring (str | None) – Docstring for the type class.

Return type:

TypeAlias

Returns:

The created or retrieved 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:

type[TypeVar(ClassType)]

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.

Parameters:
  • class_type (type[TypeVar(ClassType)]) – The class to instantiate.

  • **kwargs – Any keyword arguments to use for instantiation.

Return type:

TypeVar(ClassType)

class jsonargparse.typing.PositiveInt(v)

Bases: TypeCore, int

int restricted to be >0

class jsonargparse.typing.NonNegativeInt(v)

Bases: TypeCore, int

int restricted to be ≥0

class jsonargparse.typing.PositiveFloat(v)

Bases: TypeCore, float

float restricted to be >0

class jsonargparse.typing.NonNegativeFloat(v)

Bases: TypeCore, float

float restricted to be ≥0

class jsonargparse.typing.ClosedUnitInterval(v)

Bases: TypeCore, float

float restricted to be ≥0 and ≤1

class jsonargparse.typing.OpenUnitInterval(v)

Bases: TypeCore, float

float restricted to be >0 and <1

class jsonargparse.typing.SecretStr(value)

Bases: object

Holds a secret string that serializes to **********.

Methods:

__init__(value)

get_secret_value()

Returns the actual secret value.

__init__(value)
get_secret_value()

Returns the actual secret value.

Return type:

str

class jsonargparse.typing.NotEmptyStr(v)

Bases: TypeCore, str

str restricted to not-empty pattern ^.*[^ ].*$

class jsonargparse.typing.Email(v)

Bases: TypeCore, str

str restricted to the email pattern ^[^@ ]+@[^@ ]+\.[^@ ]+$

class jsonargparse.typing.Path(path, mode='fr', cwd=None, **kwargs)

Bases: PathDeprecations

Base 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.

read_text()

Returns the text contents of the file or the remote path.

open([mode])

Return an opened file object for the path.

relative_path_context()

Context manager to use this path's parent (directory or URL) for relative paths defined within.

Attributes:

relative

Returns the relative representation of the path (how the path was given on instance creation).

absolute

Returns the absolute representation of the path.

__init__(path, mode='fr', cwd=None, **kwargs)

Initializer for Path instance.

Parameters:
  • path (str | PathLike | Path) – The path to check and store.

  • mode (str) – The required type and access permissions among [fdrwxcuFDRWX].

  • cwd (str | PathLike | None) – Working directory for relative paths. If None then os.getcwd() is used.

Raises:
  • ValueError – If the provided mode is invalid.

  • PathError – If the path does not exist or does not agree with the mode.

property relative: str

Returns the relative representation of the path (how the path was given on instance creation).

property absolute: str

Returns the absolute representation of the path.

read_text()

Returns the text contents of the file or the remote path.

Return type:

str

open(mode='r')

Return an opened file object for the path.

Return type:

Iterator[IO]

relative_path_context()

Context manager to use this path’s parent (directory or URL) for relative paths defined within.

Return type:

Iterator[str]

class jsonargparse.typing.Path_fr(v, **k)

Bases: PathType

path to a file that exists and is readable

class jsonargparse.typing.Path_fc(v, **k)

Bases: PathType

path to a file that can be created if it does not exist

class jsonargparse.typing.Path_dw(v, **k)

Bases: PathType

path to a directory that exists and is writable

class jsonargparse.typing.Path_dc(v, **k)

Bases: PathType

path to a directory that can be created if it does not exist

class jsonargparse.typing.Path_drw(v, **k)

Bases: PathType

path to a directory that exists and is readable and writable

Index