def test_class_path_override_with_default_config_files(self): class MyCalendar(Calendar): def __init__(self, *args, param: str = '0', **kwargs): super().__init__(*args, **kwargs) with mock_module(MyCalendar) as module: config = { 'class_path': f'{module}.MyCalendar', 'init_args': { 'firstweekday': 2, 'param': '1' }, } config_path = os.path.join(self.tmpdir, 'config.yaml') with open(config_path, 'w') as f: json.dump({'cal': config}, f) parser = ArgumentParser(error_handler=None, default_config_files=[config_path]) parser.add_argument('--cal', type=Optional[Calendar]) cfg = parser.instantiate_classes(parser.get_defaults()) self.assertIsInstance(cfg['cal'], MyCalendar) cfg = parser.parse_args([ '--cal={"class_path": "calendar.Calendar", "init_args": {"firstweekday": 3}}' ]) self.assertEqual(type(parser.instantiate_classes(cfg)['cal']), Calendar)
def test_dump_skip_default(self): class MyCalendar(Calendar): def __init__(self, *args, param: str = '0', **kwargs): super().__init__(*args, **kwargs) with mock_module(MyCalendar) as module: parser = ArgumentParser() parser.add_argument('--g1.op1', default=123) parser.add_argument('--g1.op2', default='abc') parser.add_argument('--g2.op1', default=4.5) parser.add_argument('--g2.op2', type=Calendar, default=lazy_instance(Calendar, firstweekday=2)) cfg = parser.get_defaults() dump = parser.dump(cfg, skip_default=True) self.assertEqual(dump, '{}\n') cfg.g2.op2.class_path = f'{module}.MyCalendar' dump = parser.dump(cfg, skip_default=True) self.assertEqual( dump, 'g2:\n op2:\n class_path: jsonargparse_tests.MyCalendar\n init_args:\n firstweekday: 2\n' ) cfg.g2.op2.init_args.firstweekday = 0 dump = parser.dump(cfg, skip_default=True) self.assertEqual( dump, 'g2:\n op2:\n class_path: jsonargparse_tests.MyCalendar\n')
def test_class_type_with_default_config_files(self): config = { 'class_path': 'calendar.Calendar', 'init_args': { 'firstweekday': 3 }, } config_path = os.path.join(self.tmpdir, 'config.yaml') with open(config_path, 'w') as f: json.dump({'data': {'cal': config}}, f) class MyClass: def __init__(self, cal: Optional[Calendar] = None, val: int = 2): self.cal = cal parser = ArgumentParser(error_handler=None, default_config_files=[config_path]) parser.add_argument('--op', default='from default') parser.add_class_arguments(MyClass, 'data') cfg = parser.get_defaults() self.assertEqual(config_path, str(cfg['__default_config__'])) self.assertEqual(cfg.data.cal.as_dict(), config) dump = parser.dump(cfg) self.assertIn('class_path: calendar.Calendar\n', dump) self.assertIn('firstweekday: 3\n', dump) cfg = parser.parse_args([]) self.assertEqual(cfg.data.cal.as_dict(), config) cfg = parser.parse_args(['--data.cal.class_path=calendar.Calendar'], defaults=False) self.assertEqual(cfg.data.cal, Namespace(class_path='calendar.Calendar'))
def test_bool(self): parser = ArgumentParser(prog='app', default_env=True, error_handler=None) parser.add_argument('--val', type=bool) self.assertEqual(None, parser.get_defaults().val) self.assertEqual(True, parser.parse_args(['--val', 'true']).val) self.assertEqual(True, parser.parse_args(['--val', 'TRUE']).val) self.assertEqual(False, parser.parse_args(['--val', 'false']).val) self.assertEqual(False, parser.parse_args(['--val', 'FALSE']).val) self.assertRaises(ParserError, lambda: parser.parse_args(['--val', '1'])) os.environ['APP_VAL'] = 'true' self.assertEqual(True, parser.parse_args([]).val) os.environ['APP_VAL'] = 'True' self.assertEqual(True, parser.parse_args([]).val) os.environ['APP_VAL'] = 'false' self.assertEqual(False, parser.parse_args([]).val) os.environ['APP_VAL'] = 'False' self.assertEqual(False, parser.parse_args([]).val) os.environ['APP_VAL'] = '2' self.assertRaises(ParserError, lambda: parser.parse_args(['--val', 'a'])) del os.environ['APP_VAL']
def test_ActionYesNo_old_bool(self): parser = ArgumentParser(error_handler=None) parser.add_argument('--val', nargs=1, action=ActionYesNo(no_prefix=None)) self.assertEqual(False, parser.get_defaults().val) self.assertEqual(True, parser.parse_args(['--val', 'true']).val) self.assertEqual(True, parser.parse_args(['--val', 'yes']).val) self.assertEqual(False, parser.parse_args(['--val', 'false']).val) self.assertEqual(False, parser.parse_args(['--val', 'no']).val) self.assertRaises(ParserError, lambda: parser.parse_args(['--val', '1']))
def test_class_type_required_params(self): class MyCal(Calendar): def __init__(self, p1: int, p2: str): pass with mock_module(MyCal) as module: parser = ArgumentParser(error_handler=None) parser.add_argument('--op', type=MyCal, default=lazy_instance(MyCal)) cfg = parser.get_defaults() self.assertEqual(cfg.op.class_path, f'{module}.MyCal') self.assertEqual(cfg.op.init_args, Namespace(p1=None, p2=None)) self.assertRaises( ParserError, lambda: parser.parse_args([f'--op={module}.MyCal']))
def test_ActionEnum(self): class MyEnum(Enum): A = 1 B = 2 C = 3 parser = ArgumentParser(error_handler=None) action = ActionEnum(enum=MyEnum) parser.add_argument('--enum', action=action, default=MyEnum.C, help='Description') for val in ['A', 'B', 'C']: self.assertEqual(MyEnum[val], parser.parse_args(['--enum=' + val]).enum) for val in ['X', 'b', 2]: self.assertRaises( ParserError, lambda: parser.parse_args(['--enum=' + str(val)])) cfg = parser.parse_args(['--enum=C'], with_meta=False) self.assertEqual('enum: C\n', parser.dump(cfg)) help_str = StringIO() parser.print_help(help_str) self.assertIn('Description (type: MyEnum, default: C)', help_str.getvalue()) def func(a1: MyEnum = MyEnum['A']): return a1 parser = ArgumentParser() parser.add_function_arguments(func) self.assertEqual(MyEnum['A'], parser.get_defaults().a1) self.assertEqual(MyEnum['B'], parser.parse_args(['--a1=B']).a1) self.assertRaises(ValueError, lambda: ActionEnum()) self.assertRaises(ValueError, lambda: ActionEnum(enum=object)) self.assertRaises( ValueError, lambda: parser.add_argument('--bad1', type=MyEnum, action=True)) self.assertRaises( ValueError, lambda: parser.add_argument('--bad2', type=float, action=action))
def test_ActionParser(self): parser_lv3 = ArgumentParser(prog='lv3', default_env=False) parser_lv3.add_argument('--opt3', default='opt3_def') parser_lv2 = ArgumentParser(prog='lv2', default_env=False) parser_lv2.add_argument('--opt2', default='opt2_def') parser_lv2.add_argument('--inner3', action=ActionParser(parser=parser_lv3)) parser = ArgumentParser(prog='lv1', default_env=True, error_handler=None) parser.add_argument('--opt1', default='opt1_def') parser.add_argument('--inner2', action=ActionParser(parser=parser_lv2)) tmpdir = os.path.join(self.tmpdir, 'subdir') os.mkdir(tmpdir) yaml_main_file = os.path.join(tmpdir, 'main.yaml') yaml_inner2_file = os.path.join(tmpdir, 'inner2.yaml') yaml_inner3_file = os.path.join(tmpdir, 'inner3.yaml') with open(yaml_main_file, 'w') as output_file: output_file.write('opt1: opt1_yaml\ninner2: inner2.yaml\n') with open(yaml_inner2_file, 'w') as output_file: output_file.write('opt2: opt2_yaml\ninner3: inner3.yaml\n') with open(yaml_inner3_file, 'w') as output_file: output_file.write('opt3: opt3_yaml\n') ## Check defaults cfg = parser.get_defaults() self.assertEqual('opt1_def', cfg.opt1) self.assertEqual('opt2_def', cfg.inner2.opt2) self.assertEqual('opt3_def', cfg.inner2.inner3.opt3) ## Check ActionParser with parse_path expected = { 'opt1': 'opt1_yaml', 'inner2': { 'opt2': 'opt2_yaml', 'inner3': { 'opt3': 'opt3_yaml' } } } cfg = parser.parse_path(yaml_main_file, with_meta=False) self.assertEqual(expected, cfg.as_dict()) with open(yaml_main_file, 'w') as output_file: output_file.write(parser.dump(cfg)) cfg2 = parser.parse_path(yaml_main_file, with_meta=False) self.assertEqual(expected, cfg2.as_dict()) ## Check ActionParser inner environment variables self.assertEqual( 'opt2_env', parser.parse_env({ 'LV1_INNER2__OPT2': 'opt2_env' }).inner2.opt2) self.assertEqual( 'opt3_env', parser.parse_env({ 'LV1_INNER2__INNER3__OPT3': 'opt3_env' }).inner2.inner3.opt3) expected = { 'opt1': 'opt1_def', 'inner2': { 'opt2': 'opt2_def', 'inner3': { 'opt3': 'opt3_yaml' } } } cfg = parser.parse_env({'LV1_INNER2__INNER3': yaml_inner3_file}, with_meta=False) self.assertEqual(expected, cfg.as_dict()) parser.parse_env({'LV1_INNER2': yaml_inner2_file}) self.assertEqual( 'opt2_yaml', parser.parse_env({ 'LV1_INNER2': yaml_inner2_file }).inner2.opt2) ## Check ActionParser as argument path expected = { 'opt1': 'opt1_arg', 'inner2': { 'opt2': 'opt2_yaml', 'inner3': { 'opt3': 'opt3_yaml' } } } cfg = parser.parse_args( ['--opt1', 'opt1_arg', '--inner2', yaml_inner2_file], with_meta=False) self.assertEqual(expected, cfg.as_dict()) expected = { 'opt1': 'opt1_def', 'inner2': { 'opt2': 'opt2_arg', 'inner3': { 'opt3': 'opt3_yaml' } } } cfg = parser.parse_args( ['--inner2.opt2', 'opt2_arg', '--inner2.inner3', yaml_inner3_file], with_meta=False) self.assertEqual(expected, cfg.as_dict()) expected = { 'opt1': 'opt1_def', 'inner2': { 'opt2': 'opt2_def', 'inner3': { 'opt3': 'opt3_arg' } } } cfg = parser.parse_args([ '--inner2.inner3', yaml_inner3_file, '--inner2.inner3.opt3', 'opt3_arg' ], with_meta=False) self.assertEqual(expected, cfg.as_dict()) ## Check ActionParser as argument string expected = {'opt2': 'opt2_str', 'inner3': {'opt3': 'opt3_str'}} cfg = parser.parse_args(['--inner2', json.dumps(expected)], with_meta=False) self.assertEqual(expected, cfg.as_dict()['inner2']) expected = {'opt3': 'opt3_str'} cfg = parser.parse_args( ['--inner2.inner3', json.dumps(expected)], with_meta=False) self.assertEqual(expected, cfg.as_dict()['inner2']['inner3']) ## Check ActionParser with ActionConfigFile parser.add_argument('--cfg', action=ActionConfigFile) expected = { 'opt1': 'opt1_yaml', 'inner2': { 'opt2': 'opt2_yaml', 'inner3': { 'opt3': 'opt3_yaml' } } } cfg = parser.parse_args(['--cfg', yaml_main_file], with_meta=False) delattr(cfg, 'cfg') self.assertEqual(expected, cfg.as_dict()) cfg = parser.parse_args([ '--cfg', yaml_main_file, '--inner2.opt2', 'opt2_arg', '--inner2.inner3.opt3', 'opt3_arg' ]) self.assertEqual('opt2_arg', cfg.inner2.opt2) self.assertEqual('opt3_arg', cfg.inner2.inner3.opt3)
def test_dump_header_yaml(self): parser = ArgumentParser() parser.add_argument('--int', type=int, default=1) parser.dump_header = ['line 1', 'line 2'] dump = parser.dump(parser.get_defaults()) self.assertEqual(dump, '# line 1\n# line 2\nint: 1\n')
def test_dump_header_json(self): parser = ArgumentParser() parser.add_argument('--int', type=int, default=1) parser.dump_header = ['line 1', 'line 2'] dump = parser.dump(parser.get_defaults(), format='json') self.assertEqual(dump, '{"int":1}')