Parsing of command line options, yaml/jsonnet config files and/or environment variables based on argparse.
Project description
jsonargparse (former yamlargparse)
https://omni-us.github.io/jsonargparse/
This package is an extension to python’s argparse which simplifies parsing of configuration options from command line arguments, json configuration files (yaml or jsonnet supersets), environment variables and hard-coded defaults.
The aim is similar to other projects such as configargparse, yconf and confuse. The obvious question is, why yet another package similar to many already existing ones? The answer is simply that none of the existing projects had the exact features we wanted and after analyzing the alternatives it seemed simpler to start a new project.
Features
Parsers are configured just like with python’s argparse, thus it has a gentle learning curve.
Not exclusively intended for parsing command line arguments. The main focus is parsing configuration files and not necessarily from a command line tool.
Support for two popular supersets of json: yaml and jsonnet.
Support for nested namespaces which makes it possible to parse config files with non-flat hierarchies.
Easy adding of arguments from classes, methods and functions that include type hints and docstrings.
Parsing of relative paths within config files and path lists.
Several convenient action classes to ease common parsing use cases (paths, comparison operators, json schemas, enums …).
Two mechanisms to define parsers in a modular way: parsers as arguments and sub-commands.
Support for command line tab argument completion using argcomplete.
Configuration values are overridden based on the following precedence.
Parsing command line: command line arguments (might include config file) > environment variables > default config file > defaults.
Parsing files: config file > environment variables > default config file > defaults.
Parsing environment: environment variables > default config file > defaults.
Installation
You can install using pip as:
pip install jsonargparse
By default the only dependency that jsonargparse installs is PyYAML. However, jsonargparse has several
optional features that can be enabled by specifying any of the following extras
requires: signatures
, jsonschema
, jsonnet
, urls
,
argcomplete
and reconplogger
. There is also the all
extras require that can be used to enable all optional features. Installing
jsonargparse with extras require is as follows:
pip install "jsonargparse[signatures]" # Enable only signatures feature
pip install "jsonargparse[all]" # Enable all optional features
Basic usage
A parser is created just like it is done with argparse. You import the module, create a parser object and then add arguments to it. A simple example would be:
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.')
After creating the parser, you can use it to parse command line arguments with the .ArgumentParser.parse_args function, after which you get an object with the parsed values or defaults available as attributes. For illustrative purposes giving to parse_args a list of arguments (instead of automatically getting them from the command line arguments), with the parser from above you would observe:
>>> 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 the parsing fails the standard behavior is that the usage is printed and the
program is terminated. Alternatively you can initialize the parser with
error_handler=None
in which case a .ParserError is raised.
Nested namespaces
A difference with respect to the basic argparse is that it by using dot notation in the argument names, you can define a hierarchy of nested namespaces. So for example you could do the following:
>>> 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 2'
>>> cfg.lev1.opt2
'from default 2'
Environment variables
The jsonargparse parsers can also get values from environment variables. The
parser checks existing environment variables whose name is of the form
[PREFIX_][LEV__]*OPT
, that is all in upper case, first a prefix (set by
env_prefix
, or if unset the prog
without extension) followed by
underscore and then the argument name replacing dots with two underscores. Using
the parser from the nested-namespaces section above, in your shell you
would set the environment variables as:
export APP_LEV1__OPT1='from env 1'
export APP_LEV1__OPT2='from env 2'
Then in python the parser would use these variables, unless overridden by the command line arguments, that is:
>>> 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 that when creating the parser, default_env=True
was given as
argument. By default .ArgumentParser.parse_args does not check
environment variables, so it has to be enabled explicitly.
There is also the .ArgumentParser.parse_env function to only parse environment variables, which might be useful for some use cases in which there is no command line call involved.
If a parser includes an .ActionConfigFile argument, then the environment variable for this config file will be checked before all the other environment variables.
Configuration files
An important feature of jsonargparse is the parsing of yaml/json files. The dot notation hierarchy of the arguments (see nested-namespaces) are used for the expected structure in the config files.
The .ArgumentParser class accepts a default_config_files
argument that can be given to specify patterns to search for configuration
files. Only the first matched config file is parsed.
When parsing command line arguments, it is possible to add a configuration file path argument. The config file would be read and parsed in the specific position among the command line arguments, so the arguments after would override the values from the configuration file. The config argument can be given multiple times, each overriding the values of the previous. Again using the parser from the nested-namespaces section above, for example we could have the following config file in yaml format:
# File: example.yaml
lev1:
opt1: from yaml 1
opt2: from yaml 2
Then in python adding a yaml file argument and parsing some example arguments, the following would be observed:
>>> from jsonargparse import ArgumentParser, ActionConfigFile
>>> parser = ArgumentParser()
>>> parser.add_argument('--lev1.opt1', default='from default 1')
>>> parser.add_argument('--lev1.opt2', default='from default 2')
>>> parser.add_argument('--cfg', action=ActionConfigFile)
>>> cfg = parser.parse_args(['--lev1.opt1', 'from arg 1',
'--cfg', 'example.yaml',
'--lev1.opt2', 'from arg 2'])
>>> cfg.lev1.opt1
'from yaml 1'
>>> cfg.lev1.opt2
'from arg 2'
Instead of providing a path to a configuration file, a string with the configuration content can also be provided.
>>> cfg = parser.parse_args(['--cfg', '{"lev1":{"opt1":"from string 1"}}'])
>>> cfg.lev1.opt1
'from string 1'
All parsers include a --print-config
option. This is useful particularly
for command line tools with a large set of options to create an initial config
file including all default values.
The config file can also be provided as an environment variable as explained in section environment-variables. The configuration file environment variable is the first one to be parsed. So any other argument provided through environment variables would override the config file one.
A configuration file or string can also be parsed without parsing command line arguments. The functions for this are .ArgumentParser.parse_path and .ArgumentParser.parse_string to parse a config file or a config contained in a string respectively.
Classes, methods and functions
It is good practice to write python code in which arguments have type hints and are described in the docstrings. To make this well written code configurable, it wouldn’t make sense to duplicate information of types and argument descriptions. To avoid this duplication, jsonargparse includes methods to automatically add their arguments: .SignatureArguments.add_class_arguments, .SignatureArguments.add_method_arguments and .SignatureArguments.add_function_arguments.
Take for example a class with its init and a method with docstrings as follows:
from typing import Dict, Union, List
class MyClass(MyBaseClass):
def __init__(self, items: Dict[str, Union[int, List[int]]], **kwargs):
"""Initializer for MyClass.
Args:
items: Description for items.
"""
pass
def mymethod(self, value: float, flag: bool = False):
"""Description for mymethod.
Args:
value: Description for value.
flag: Description for flag.
"""
pass
Both MyClass
and mymethod
can easily be made configurable, the
class initialized and the method executed as follows:
from jsonargparse import ArgumentParser, namespace_to_dict
parser = ArgumentParser()
parser.add_class_arguments(MyClass, 'myclass.init')
parser.add_method_arguments(MyClass, 'mymethod', 'myclass.method')
cfg = parser.parse_args()
myclass = MyClass(**namespace_to_dict(cfg.myclass.init))
myclass.mymethod(**namespace_to_dict(cfg.myclass.method))
The add_class_arguments call adds to the myclass.init key the
items
argument with description as in the docstring, it is set as
required since it does not have a default value, and when parsed it is validated
according to its type hint, i.e., a dict with values ints or list of ints. Also
since the init has the **kwargs
argument, the keyword arguments from
MyBaseClass
are also added to the parser. Similarly the
add_method_arguments call adds to the myclass.method key the arguments
value
as a required float and flag
as an optional boolean with
default value false.
Some notes about the support for automatic adding of arguments are:
Nested types are supported as long as at least one child type is supported.
The supported types are:
str
,bool
,int
,float
,list
,Any
,Union
andOptional
.dict
withstr
keys is supported for any level of nesting.int
keys are also supported but only up to the first level of nesting.Enum
is supported but only up to the first level of nesting.There is partial support for
tuple
andset
even though they can’t be represented in json distinguishable from a list. They are only supported without nesting and in the case of tuple for a fixed number of elements. Each element position can have its own type and will be validated as such. In command line arguments, config files and environment variables tuples and sets are represented as a list.All positional arguments must have a type, otherwise the add arguments functions raise an exception.
Keyword arguments are ignored if they don’t have at least one type that is supported.
Recursive adding of arguments from base classes only considers the presence of
*args
and**kwargs
. It does not check the code to identify ifsuper().__init__
is called or with which arguments.
Since keyword arguments with unsupported types are ignored, during development
it might be desired to know which arguments are ignored and the specific reason.
This can be done by initializing .ArgumentParser with
logger={'level': 'DEBUG'}
. For more details about logging go to section
logging.
For all features described above to work, two optional packages are required:
jsonschema to support validation of
complex type hints and docstring-parser to get the argument descriptions
from the docstrings. Both these packages are included when jsonargparse is
installed using the signatures
extras require as explained in section
installation.
Json schemas
The .ActionJsonSchema class is provided to allow parsing and validation
of values using a json schema. This class requires the jsonschema python package. Though note that
jsonschema is not a requirement of the minimal jsonargparse install. To enable
this functionality install with the jsonschema
extras require as
explained in section installation.
Check out the jsonschema documentation to learn how to write a schema. The current version of jsonargparse uses Draft7Validator. Parsing an argument using a json schema is done like in the following example:
>>> schema = {
... "type" : "object",
... "properties" : {
... "price" : {"type" : "number"},
... "name" : {"type" : "string"},
... },
... }
>>> from jsonargparse import ActionJsonSchema
>>> parser.add_argument('--op', action=ActionJsonSchema(schema=schema))
>>> parser.parse_args(['--op', '{"price": 1.5, "name": "cookie"}'])
Namespace(op=Namespace(name='cookie', price=1.5))
Instead of giving a json string as argument value, it is also possible to
provide a path to a json/yaml file, which would be loaded and validated against
the schema. If the schema defines default values, these will be used by the
parser to initialize the config values that are not specified. When adding an
argument with the .ActionJsonSchema action, you can use “%s” in the
help
string so that in that position the schema will be printed.
Jsonnet files
The Jsonnet support requires jsonschema and jsonnet python packages which are not included
with minimal jsonargparse install. To enable this functionality install
jsonargparse with the jsonnet
extras require as explained in section
installation.
By default an .ArgumentParser parses configuration files as yaml.
However, if instantiated giving as argument parser_mode='jsonnet'
, then
parse_args, parse_path and parse_string will expect
config files to be in jsonnet format instead. Example:
>>> from jsonargparse import ArgumentParser, ActionConfigFile
>>> parser = ArgumentParser(parser_mode='jsonnet')
>>> parser.add_argument('--cfg', action=ActionConfigFile)
>>> cfg = parser.parse_args(['--cfg', 'example.jsonnet'])
Jsonnet files are commonly parametrized, thus requiring external variables for parsing. For these cases, instead of changing the parser mode away from yaml, the .ActionJsonnet class can be used. This action allows to define an argument which would be a jsonnet string or a path to a jsonnet file. Moreover, another argument can be specified as the source for any external variables required, which would be either a path to or a string containing a json dictionary of variables. Its use would be as follows:
from jsonargparse import ArgumentParser, ActionJsonnet, ActionJsonnetExtVars
parser = ArgumentParser()
parser.add_argument('--in_ext_vars',
action=ActionJsonnetExtVars())
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', 'path_to_jsonnet'])
Note that the external variables argument must be provided before the jsonnet path so that this dictionary already exists when parsing the jsonnet.
The .ActionJsonnet class also accepts as argument a json schema, in which case the jsonnet would be validated against this schema right after parsing.
Parsing paths
For some use cases it is necessary to parse file paths, checking its existence and access permissions, but not necessarily opening the file. Moreover, a file path could be included in a config file as relative with respect to the config file’s location. After parsing it should be easy to access the parsed file path without having to consider the location of the config file. To help in these situations jsonargparse includes a type generator .path_type, some predefined types (e.g. .Path_fr) and the .ActionPath and .ActionPathList classes.
For example suppose you have a directory with a configuration file
app/config.yaml
and some data app/data/info.db
. The contents of
the yaml file is the following:
# File: config.yaml
databases:
info: data/info.db
To create a parser that checks that the value of databases.info
is a
file that exists and is readable, the following could be done:
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 are flags stand for file and readable. After parsing
the value of databases.info
will be an instance of the .Path
class that allows to get both the original relative path as included in the yaml
file, or the corresponding absolute path:
>>> str(cfg.databases.info)
'data/info.db'
>>> cfg.databases.info()
'/YOUR_CWD/app/data/info.db'
Likewise directories can be parsed for example using as type the
.Path_dw type, would require a directory to exist and be writeable. New
path types can be created using the .path_type function. For example to
create a type for files that must exist and be both readable and writeable, the
command would be Path_frw = path_type('frw')
. If the file
app/config.yaml
is not writeable, then usig the type to cast
Path_frw('app/config.yaml')
would raise a TypeError: File is not
writeable exception. For more information of all the mode flags supported,
refer to the documentation of the .Path class.
The content of a file that a .Path instance references can be read by
using the .Path.get_content method. For the previous example would be
info_db = cfg.databases.info.get_content()
.
Adding arguments with path types is equivalent to adding using for example
action=ActionPath(mode='fr')
instead of a type=Path_fr
. However,
the type option is preferred.
An argument with a path type can be given nargs='+'
to parse multiple
paths. But it might also be wanted to parse a list of paths found in a plain
text file or from stdin. For this the .ActionPathList is used and as
argument either the path to a file listing the paths is given or the special
'-'
string for reading the list from stdin. For for example:
from jsonargparse import ActionPathList
parser.add_argument('--list', action=ActionPathList(mode='fr'))
cfg = parser.parse_args(['--list', 'paths.lst') # Text file with paths
cfg = parser.parse_args(['--list', '-') # List from stdin
If nargs='+'
is given to add_argument
then a single list is
generated including all paths in all lists is provided.
Note: the .Path class is currently not fully supported in windows.
Parsing URLs
The .path_type function also supports URLs which after parsing the
.Path.get_content method can be used to perform a GET request to the
corresponding URL and retrieve its content. For this to work the validators
and requests python packages are required which will be installed along with
jsonargparse if installed with the urls
extras require as explained in
section installation.
The 'u'
flag is used to parse URLs. For example if it is desired that an
argument can be either a readable file or URL, the type would be created as
Path_fur = path_type('fur')
. If the value appears to be a URL according
to validators.url.url then a HEAD request would be triggered to check if
it is accessible, and if so, the parsing succeeds. To get the content of the
parsed path, without needing to care if it is a local file or a URL, the
.Path.get_content can be used.
If after importing jsonargparse you run
jsonargparse.set_url_support(True)
, the following functions and classes
will also support loading from URLs: .ArgumentParser.parse_path,
.ArgumentParser.get_defaults (default_config_files
argument),
.ActionConfigFile, .ActionJsonSchema, .ActionJsonnet
and .ActionParser. This means for example that a tool that can receive
a configuration file via .ActionConfigFile is able to get the config
file from a URL, that is something like the following would work:
$ my_tool.py --cfg http://example.com/config.yaml
Restricted numbers
It is quite common that when parsing a number, its range should be limited. To
ease these cases the module jsonargparse.typing
includes some predefined
types and a function .restricted_number_type to define new types. The
predefined types are: .PositiveInt, .NonNegativeInt,
.PositiveFloat, .NonNegativeFloat,
.ClosedUnitInterval and .OpenUnitInterval. Examples of usage
are:
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)
# either int larger than zero or 'off' string
def int_or_off(x): return x if x == 'off' else PositiveInt(x)
parser.add_argument('--op3', type=int_or_off))
Restricted strings
Similar to the restricted numbers, there is a function to create string types that are restricted to match a given regular expression: .restricted_string_type. A predefined type is .Email which is restricted so that it follows the normal email pattern. For example to add an argument required to 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)
Type hints
As explained in section classes-methods-functions type hints are required
to automatically add arguments from signatures to a parser. Additional to this
feature, a type hint can also be used independently when adding a single
argument to the parser. For example, an argument that can be None
or a
float in the range (0, 1)
or a positive int could be added using type
hints as follows:
from typing import Optional, Union
from jsonargparse.typing import PositiveInt, OpenUnitInterval
parser.add_argument('--op', type=Optional[Union[PositiveInt, OpenUnitInterval]])
Enum arguments
Another case of restricted values is string choices. In addition to the common
choices
given as a list of strings, it is also possible to provide as
type an Enum
class. This has the added benefit that strings are mapped
to some desired values. For example:
>>> 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>)
Boolean arguments
Parsing boolean arguments is very common, however, the original argparse only
has a limited support for them, via store_true
and store_false
.
Futhermore unexperienced users might mistakenly use type=bool
which
would not provide the intended behavior.
With jsonargparse adding an argument with type=bool
the intended action
is implemented. If given as values {'yes', 'true'}
or {'no',
'false'}
the corresponding parsed values would be True
or
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)
To use type=bool
jsonargparse needs to be installed with the
jsonschema
extras require as explained in section installation.
Sometimes it is also useful to define two paired options, one to set
True
and the other to set False
. The .ActionYesNo class
makes this straightforward. A couple of examples would be:
from jsonargparse import ActionYesNo
# --opt1 for true and --no_opt1 for false.
parser.add_argument('--op1', action=ActionYesNo)
# --with-opt2 for true and --without-opt2 for false.
parser.add_argument('--with-op2', action=ActionYesNo(yes_prefix='with-', no_prefix='without-'))
If the .ActionYesNo class is used in conjunction with
nargs='?'
the options can also be set by giving as value any of
{'true', 'yes', 'false', 'no'}
.
Parsers as arguments
As parsers get more complex, being able to define them in a modular way becomes important. Two mechanisms are available to define parsers in a modular way, both explained in this and the next section respectively.
Sometimes it is useful to take an already existing parser that is required standalone in some part of the code, and reuse it to parse an inner node of another more complex parser. For these cases an argument can be defined using the .ActionParser class. An example of how to use this class is the following:
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',
action=ActionParser(parser=inner_parser))
When using the .ActionParser class, the value of the node in a config file can be either the complex node itself, or the path to a file which will be loaded and parsed with the corresponding inner parser. Naturally using .ActionConfigFile to parse a complete config file will parse the inner nodes correctly.
From the command line the help of the inner parsers can be shown by calling the
tool with a prefixed help command, that is, for the example above it would be
--inner.node.help
.
Regarding environment variables, the prefix of the outer parser will be used to
populate the leaf nodes of the inner parser. In the example above, if
inner_parser
is used to parse environment variables, then as normal
APP1_OP1
would be checked to populate option op1
. But if
outer_parser
is used, then APP2_INNER__NODE__OP1
would be
checked to populate inner.node.op1
.
An important detail to note is that the parsers that are given to .ActionParser are internally modified. So they should be instantiated exclusively for the .ActionParser and not used standalone.
Sub-commands
A second way to define parsers in a modular way is what in argparse is known as
sub-commands.
However, to promote modularity, in jsonargparse sub-commands work a bit
different than in argparse. To add sub-commands to a parser, the
.ArgumentParser.add_subcommands method is used. Then an existing
parser is added as a sub-command using .add_subcommand. In a parsed
config object the sub-command will be stored in the subcommand
entry (or
whatever dest
was set to), and the values of the sub-command will be in
an entry with the same name as the respective sub-command. An example of
defining a parser with sub-commands is the following:
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)
Then some examples of parsing are the following:
>>> parser.parse_args(['subcomm1', '--op1', 'val1'])
Namespace(op0=None, subcomm1=Namespace(op1='val1'), subcommand='subcomm1')
>>> parser.parse_args(['--op0', 'val0', 'subcomm2', '--op2', 'val2'])
Namespace(op0='val0', subcomm2=Namespace(op2='val2'), subcommand='subcomm2')
Parsing config files with .ArgumentParser.parse_path or
.ArgumentParser.parse_string is also possible. Though there can only
be values for one of the sub-commands. The config file is not required to
specify a value for subcommand
. For the example parser above a valid
yaml would be:
# File: example.yaml
op0: val0
subcomm1:
op1: val1
Parsing of environment variables works similar to .ActionParser. For
the example parser above, all environment variables for subcomm1
would
have as prefix APP_SUBCOMM1_
and likewise for subcomm2
as prefix
APP_SUBCOMM2_
. The sub-command to use could be chosen by setting
environment variable APP_SUBCOMMAND
.
Logging
The parsers from jsonargparse log some basic events, though by default this is
disabled. To enable it the logger
argument should be set when creating
an .ArgumentParser object. The intended use is to give as value an
already existing logger object which is used for the whole application. Though
for convenience to enable a default logger the logger
argument can also
receive True
or a string which sets the name of the logger or a
dictionary that can include the name and the level, e.g. {"name":
"myapp", "level": "ERROR"}
. If reconplogger is installed, setting logger
to True
or a dictionary without specifying a name, then the reconplogger
is used.
Contributing
Contributions to the jsonargparse package are very welcome, be it just to create issues for reporting bugs and proposing enhancements, or more directly by creating pull requests.
If you intend to work with the source code, note that this project does not
include any requirements.txt
file. This is by intention. To make it very
clear what are the requirements for different use cases, all the requirements of
the project are stored in the file setup.cfg
. The basic runtime
requirements are defined in section [options]
in the
install_requires
entry. All extras requires for optional features listed
in installation are stored in section [options.extras_require]
.
Also there are test
, test_no_urls
, dev
and doc
entries in the same [options.extras_require]
section which lists
requirements for testing, development and documentation building.
The recommended way to work with the source code is the following. First clone the repository, then create a virtual environment, activate it and finally install the development requirements. More precisely the steps are:
git clone https://github.com/omni-us/jsonargparse.git
cd jsonargparse
virtualenv -p python3 venv
. venv/bin/activate
The crucial step is installing the requirements which would be done by running:
pip install -e ".[dev,all]"
Running the unit tests can be done either using using tox or the setup.py
script. The
unit tests are also installed with the package, thus can be used to in a
production system.
tox # Run tests using tox
./setup.py test_coverage # Run tests and generate coverage report
python3 -m jsonargparse_tests # Run tests for installed package
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for jsonargparse-3.0.0rc1-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | cd0b1f85b36aa85718aa34526fdcd962e286860f57ca1c338c20852bbd2b6828 |
|
MD5 | eae4265b0fe5522c3e3a9d413391f6f5 |
|
BLAKE2b-256 | 5d0213117b7e769088899b2bacb69b23ab1f674663762df1bb10a777c5bc742f |