Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions jsonargparse_tests/__main__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Run all unit tests in package."""
# pragma: no cover

import os
import sys
Expand Down
1 change: 1 addition & 0 deletions jsonargparse_tests/argparse_tests_generate.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env python3
# pragma: no cover
"""Generate argparse compatibility tests from CPython's test_argparse.py.

This script downloads the test_argparse.py file from the CPython repository,
Expand Down
4 changes: 2 additions & 2 deletions jsonargparse_tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,12 +271,12 @@ def get_parse_args_stderr(parser: ArgumentParser, args: List[str]) -> str:

class BaseClass:
def __init__(self):
pass
pass # pragma: no cover


def wrap_fn(fn):
@wraps(fn)
def wrapped_fn(*args, **kwargs):
return fn(*args, **kwargs)
return fn(*args, **kwargs) # pragma: no cover

return wrapped_fn
10 changes: 5 additions & 5 deletions jsonargparse_tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def get_cli_stderr(*args, **kwargs) -> str:


def simple_main(a1: int = 0, a2: bool = False):
pass
pass # pragma: no cover


def test_auto_parser():
Expand All @@ -54,7 +54,7 @@ def test_unexpected_components(cli_fn, components):

class ConflictingSubcommandKey:
def subcommand(self, x: int = 0):
return x
return x # pragma: no cover


def test_conflicting_subcommand_key():
Expand Down Expand Up @@ -167,14 +167,14 @@ def test_function_in_list_with_config_parameter():


def conditionalA(foo: int = 1):
return foo
return foo # pragma: no cover


def conditionalB(bar: int = 2):
return bar
return bar # pragma: no cover


def conditional_function(fn: "Literal['A', 'B']", *args, **kwargs):
def conditional_function(fn: "Literal['A', 'B']", *args, **kwargs): # pragma: no cover
if fn == "A":
return conditionalA(*args, **kwargs)
elif fn == "B":
Expand Down
2 changes: 1 addition & 1 deletion jsonargparse_tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -787,7 +787,7 @@ def rm_out_files():


class ListItem:
def __init__(self, a: int, b: str):
def __init__(self, a: int, b: str): # pragma: no cover
self.a = a
self.b = b

Expand Down
4 changes: 2 additions & 2 deletions jsonargparse_tests/test_dataclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ def __init__(self, a1: DataClassB = DataClassB()):


class RootClass:
def __init__(self, c1: SubBaseClass):
def __init__(self, c1: SubBaseClass): # pragma: no cover
"""RootClass description"""
self.c1 = c1

Expand Down Expand Up @@ -486,7 +486,7 @@ class DataWithOptionalA:


def data_with_optional(a: DataWithOptionalA):
pass
pass # pragma: no cover


def test_dataclass_with_optional_default(parser):
Expand Down
12 changes: 6 additions & 6 deletions jsonargparse_tests/test_deprecated.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def suppress_stderr():
def assert_deprecation_warn(warns, message, code):
assert message in str(warns[-1].message)
if code is None:
return
return # pragma: no cover
assert pathlib.Path(warns[-1].filename).name == pathlib.Path(__file__).name
assert code in source[warns[-1].lineno - 1]

Expand All @@ -119,7 +119,7 @@ class MyEnum(Enum):


def func(a1: MyEnum = MyEnum["A"]):
return a1
return a1 # pragma: no cover


def test_ActionEnum():
Expand Down Expand Up @@ -310,7 +310,7 @@ def test_add_instantiator_method_deprecated(parser):


def function(a1: float):
return a1
return a1 # pragma: no cover


def test_single_function_cli():
Expand All @@ -325,11 +325,11 @@ def test_single_function_cli():


def cmd1(a1: int):
return a1
return a1 # pragma: no cover


def cmd2(a2: str = "X"):
return a2
return a2 # pragma: no cover


def test_multiple_functions_cli():
Expand Down Expand Up @@ -447,7 +447,7 @@ def test_error_handler_parameter():
with catch_warnings(record=True) as w:
parser = ArgumentParser(error_handler=usage_and_exit_error_handler)
code = "ArgumentParser(error_handler=usage_"
if not is_posix:
if not is_posix: # pragma: no cover
code = None # for some reason the stack trace differs in windows
assert_deprecation_warn(
w,
Expand Down
4 changes: 2 additions & 2 deletions jsonargparse_tests/test_from_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class DefaultsOverrideRequiredNotAllowed(FromConfigMixin):
__from_config_init_defaults__ = config_path

def __init__(self, param1: int):
self.param1 = param1
self.param1 = param1 # pragma: no cover


def test_init_defaults_override_class_with_init_subclass(tmp_cwd):
Expand Down Expand Up @@ -300,7 +300,7 @@ def __init__(self, param1: str, param2: str):

def test_from_config_method_partial_config_with_required_parameter():
class FromConfigMethodPartial(FromConfigMixin):
def __init__(self, required_param: str, optional_param: str = "default_value"):
def __init__(self, required_param: str, optional_param: str = "default_value"): # pragma: no cover
self.required_param = required_param
self.optional_param = optional_param

Expand Down
2 changes: 1 addition & 1 deletion jsonargparse_tests/test_jsonnet.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def test_parser_mode_jsonnet_import_libsonnet(parser, tmp_cwd):
def test_parser_mode_jsonnet_subconfigs(parser, tmp_cwd):
class Class:
def __init__(self, name: str = "Lucky", prize: int = 100):
pass
pass # pragma: no cover

parser.parser_mode = "jsonnet"
parser.add_class_arguments(Class, "group", sub_configs=True)
Expand Down
69 changes: 30 additions & 39 deletions jsonargparse_tests/test_link_arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,23 +38,24 @@ def test_on_parse_shallow_print_config(parser):
assert json_or_yaml_load(out) == {"a": 0}


def test_on_parse_subcommand_failing_compute_fn(parser, subparser, subtests):
def to_str(value):
if not value:
raise ValueError("value is empty")
return str(value)
def _to_str_empty_error(value):
if not value:
raise ValueError("value is empty")
return str(value) # pragma: no cover


def test_on_parse_subcommand_failing_compute_fn(parser, subparser, subtests):
subparser.add_argument("--a", type=int, default=0)
subparser.add_argument("--b", type=str)
subparser.link_arguments("a", "b", to_str)
subparser.link_arguments("a", "b", _to_str_empty_error)
subparser.add_argument("--config", action="config")
subcommands = parser.add_subcommands()
subcommands.add_subcommand("sub", subparser)

with subtests.test("parse_args"):
with pytest.raises(ArgumentError) as ctx:
parser.parse_args(["sub"])
ctx.match("Call to compute_fn of link 'to_str.*failed: value is empty")
ctx.match("Call to compute_fn of link '_to_str_empty_error.*failed: value is empty")

with subtests.test("print_config"):
out = get_parse_args_stdout(parser, ["sub", "--print_config"])
Expand Down Expand Up @@ -120,15 +121,15 @@ def test_on_parse_compute_fn_subclass_spec(parser, subtests):

class ClassA:
def __init__(self, v1: int = 2, v2: int = 3):
pass
pass # pragma: no cover


class ClassB:
def __init__(self, v1: int = -1, v2: int = 4, v3: int = 2):
pass
pass # pragma: no cover


def parser_classes_links_on_parse():
def _parser_classes_links_on_parse():
def add(*args):
return sum(args)

Expand All @@ -141,7 +142,7 @@ def add(*args):


def test_on_parse_add_class_arguments(subtests):
parser = parser_classes_links_on_parse()
parser = _parser_classes_links_on_parse()

with subtests.test("without defaults"):
with pytest.raises(ArgumentError) as ctx:
Expand Down Expand Up @@ -175,12 +176,12 @@ def __init__(
v1: Union[int, str] = 1,
v2: Union[int, str] = 2,
):
pass
pass # pragma: no cover


class ClassS2:
def __init__(self, v3: int):
self.v3 = v3
self.v3 = v3 # pragma: no cover


def test_on_parse_add_subclass_arguments(parser, subtests):
Expand Down Expand Up @@ -218,7 +219,7 @@ def add(v1, v2):

class Logger:
def __init__(self, save_dir: Optional[str] = None):
pass
pass # pragma: no cover


class TrainerLoggerUnion:
Expand All @@ -227,7 +228,7 @@ def __init__(
save_dir: Optional[str] = None,
logger: Union[bool, Logger] = False,
):
pass
pass # pragma: no cover


def test_on_parse_subclass_target_in_union(parser):
Expand All @@ -246,7 +247,7 @@ def __init__(
save_dir: Optional[str] = None,
logger: List[Logger] = [],
):
pass
pass # pragma: no cover


def test_on_parse_subclass_target_in_list(parser):
Expand All @@ -269,7 +270,7 @@ def __init__(
save_dir: Optional[str] = None,
logger: Union[bool, Logger, List[Logger]] = False,
):
pass
pass # pragma: no cover


def test_on_parse_subclass_target_in_union_list(parser):
Expand All @@ -291,7 +292,7 @@ def __init__(
save_dir: Optional[str] = None,
logger: Optional[List[Logger]] = None,
):
pass
pass # pragma: no cover


def test_on_parse_subclass_target_in_optional_list(parser):
Expand Down Expand Up @@ -420,7 +421,7 @@ def test_on_parse_within_subcommand(parser, subparser):

class RequiredTargetA:
def __init__(self, a: int):
pass
pass # pragma: no cover


@dataclass
Expand All @@ -430,7 +431,7 @@ class RequiredTargetB:

class RequiredTargetC:
def __init__(self, b: RequiredTargetB):
pass
pass # pragma: no cover


def test_on_parse_save_required_target_subclass_param(parser, tmp_cwd):
Expand Down Expand Up @@ -459,7 +460,7 @@ def test_on_parse_save_required_target_entire_dataclass(parser, tmp_cwd):


class Optimizer:
def __init__(self, params: List[int], lr: float):
def __init__(self, params: List[int], lr: float): # pragma: no cover
self.params = params
self.lr = lr

Expand Down Expand Up @@ -608,23 +609,18 @@ def __init__(self, a: int = 0):

class FailingComputeFn2:
def __init__(self, b: str):
self.b = b
self.b = b # pragma: no cover


def test_on_instantiate_failing_compute_fn(parser):
def to_str(value):
if not value:
raise ValueError("value is empty")
return str(value)

parser.add_class_arguments(FailingComputeFn1, "c1")
parser.add_class_arguments(FailingComputeFn2, "c2")
parser.link_arguments("c1.a", "c2.b", compute_fn=to_str, apply_on="instantiate")
parser.link_arguments("c1.a", "c2.b", compute_fn=_to_str_empty_error, apply_on="instantiate")

with pytest.raises(ValueError) as ctx:
cfg = parser.parse_args([])
parser.instantiate(cfg)
ctx.match("Call to compute_fn of link 'to_str.*failed: value is empty")
ctx.match("Call to compute_fn of link '_to_str_empty_error.*failed: value is empty")


def test_on_instantiate_link_from_subclass_with_compute_fn():
Expand All @@ -641,7 +637,7 @@ def test_on_instantiate_link_from_subclass_with_compute_fn():

class ClassN:
def __init__(self, calendar: Calendar):
self.calendar = calendar
self.calendar = calendar # pragma: no cover


def test_on_parse_and_instantiate_link_entire_instance(parser):
Expand Down Expand Up @@ -963,11 +959,6 @@ def __init__(self, batch_size: int = 6):
self.num_classes = 7


class CustomOptimizer(Optimizer):
def __init__(self, params: List[int], num_classes: int, **kwargs):
super().__init__(params, **kwargs)


def custom_instantiator(class_type, *args, applied_instantiation_links: dict, **kwargs):
init = class_type(*args, **kwargs)
init.applied_instantiation_links = applied_instantiation_links
Expand Down Expand Up @@ -1056,28 +1047,28 @@ def test_on_parse_link_failure_previous_source_as_target(parser):


def test_on_parse_link_failure_already_linked():
parser = parser_classes_links_on_parse()
parser = _parser_classes_links_on_parse()
with pytest.raises(ValueError) as ctx:
parser.link_arguments("a.v2", "b.v1")
ctx.match('Target "b.v1" is already a target of another link')


def test_on_parse_link_failure_non_existing_source():
parser = parser_classes_links_on_parse()
parser = _parser_classes_links_on_parse()
with pytest.raises(ValueError) as ctx:
parser.link_arguments("x", "b.v3")
ctx.match('No action for key "x"')


def test_on_parse_link_failure_non_existing_target():
parser = parser_classes_links_on_parse()
parser = _parser_classes_links_on_parse()
with pytest.raises(ValueError) as ctx:
parser.link_arguments("a.v1", "x")
ctx.match('No action for key "x"')


def test_on_parse_link_failure_multi_source_missing_compute_fn():
parser = parser_classes_links_on_parse()
parser = _parser_classes_links_on_parse()
with pytest.raises(ValueError) as ctx:
parser.link_arguments(("a.v1", "a.v2"), "b.v3")
ctx.match("Multiple source keys requires a compute function")
Expand Down
Loading
Loading