def test_class_type_subclass_given_by_name_issue_84(self): class LocalCalendar(Calendar): pass parser = ArgumentParser() parser.add_argument('--op', type=Union[Calendar, GzipFile, None]) cfg = parser.parse_args(['--op=TextCalendar']) self.assertEqual(cfg.op.class_path, 'calendar.TextCalendar') out = StringIO() parser.print_help(out) for class_path in [ 'calendar.Calendar', 'calendar.TextCalendar', 'gzip.GzipFile' ]: self.assertIn(class_path, out.getvalue()) self.assertNotIn('LocalCalendar', out.getvalue()) class HTMLCalendar(Calendar): pass with mock_module(HTMLCalendar) as module: err = StringIO() with redirect_stderr(err), self.assertRaises(SystemExit): parser.parse_args(['--op.help=HTMLCalendar']) self.assertIn('Give the full class path to avoid ambiguity', err.getvalue()) self.assertIn(f'{module}.HTMLCalendar', err.getvalue())
def test_enum(self): class MyEnum(Enum): A = 1 B = 2 C = 3 parser = ArgumentParser(error_handler=None) parser.add_argument('--enum', type=MyEnum, 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 test_default_path_unregistered_type(self): parser = ArgumentParser() parser.add_argument('--path', type=path_type('drw', skip_check=True), default=Path('test', mode='drw', skip_check=True)) cfg = parser.parse_args([]) self.assertEqual('path: test\n', parser.dump(cfg)) out = StringIO() parser.print_help(out) self.assertIn('(type: Path_drw_skip_check, default: test)', out.getvalue())
def test_ActionJsonSchema_help(self): parser = ArgumentParser() parser.add_argument('--op1', action=ActionJsonSchema(schema=schema1), help='schema: %s') out = StringIO() parser.print_help(out) outval = out.getvalue() schema = re.sub('^.*schema:([^()]+)[^{}]*$', r'\1', outval.replace('\n', ' ')) self.assertEqual(schema1, json.loads(schema))
def test_default_help_formatter(self): parser = ArgumentParser(prog='app', default_env=True) parser.add_argument('--cfg', help='Config in yaml/json.', action=ActionConfigFile) parser.add_argument('--v1', help='Option v1.', default='v1', required=True) parser.add_argument('--v2', type=int, help='Option v2.') parser.add_argument('--g1.v3', help='Option v3.', default='v3') parser.add_argument('--v4', choices=['A', 'B'], help='Option v4.') parser2 = ArgumentParser() parser2.add_argument('--v4') parser.add_argument('--g2', action=ActionParser(parser=parser2)) parser.add_argument('--v5', action=ActionYesNo, default=True, help='Option v5.') out = StringIO() parser.print_help(out) outval = out.getvalue() self.assertIn('--print_config', outval) self.assertIn('--cfg CFG', outval) self.assertIn('APP_CFG', outval) self.assertIn('Config in yaml/json.', outval) self.assertIn('--v1 V1', outval) self.assertIn('APP_V1', outval) self.assertIn('Option v1. (required, default: v1)', outval) self.assertIn('--v2 V2', outval) self.assertIn('APP_V2', outval) self.assertIn('Option v2. (type: int, default: null)', outval) self.assertIn('--g1.v3 V3', outval) self.assertIn('APP_G1__V3', outval) self.assertIn('Option v3. (default: v3)', outval) self.assertIn('--v4 {A,B}', outval) self.assertIn('APP_V4', outval) self.assertIn('Option v4. (default: null)', outval) self.assertIn('--g2.v4 V4', outval) self.assertIn('APP_G2__V4', outval) self.assertIn('--v5, --no_v5', outval) self.assertIn('APP_V5', outval) self.assertIn('Option v5. (type: bool, default: True)', outval)
def test_default_config_files_help_with_required(self): config_path = os.path.realpath(os.path.join(self.tmpdir, 'config.yaml')) with open(config_path, 'w') as output_file: output_file.write('v1: from yaml\n') parser = ArgumentParser(default_config_files=[config_path]) parser.add_argument('req', help='req description') parser.add_argument('--v1', default='from default') out = StringIO() parser.print_help(out) outval = out.getvalue() self.assertIn('req description', outval) self.assertIn('from yaml', outval)
def test_Callable_with_function_path(self): parser = ArgumentParser(error_handler=None) parser.add_argument('--callable', type=Callable, default=lazy_instance) parser.add_argument('--list', type=List[Callable]) cfg = parser.parse_args(['--callable=jsonargparse.CLI']) self.assertEqual(CLI, cfg.callable) self.assertEqual(parser.dump(cfg), 'callable: jsonargparse.CLI\n') self.assertEqual([CLI], parser.parse_args(['--list=[jsonargparse.CLI]']).list) self.assertRaises( ParserError, lambda: parser.parse_args(['--callable=jsonargparse.not_exist'])) out = StringIO() parser.print_help(out) self.assertIn('(type: Callable, default: jsonargparse.lazy_instance)', out.getvalue())
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_restricted_number_type(self): limit_val = random.randint(100, 10000) larger_than = restricted_number_type(f'larger_than_{limit_val}', int, ('>', limit_val)) parser = ArgumentParser(error_handler=None) parser.add_argument('--val', type=larger_than, default=limit_val + 1, help='Description') self.assertEqual(limit_val + 1, parser.parse_args([f'--val={limit_val+1}']).val) self.assertRaises(ParserError, lambda: parser.parse_args([f'--val={limit_val-1}'])) help_str = StringIO() parser.print_help(help_str) self.assertIn( f'Description (type: larger_than_{limit_val}, default: {limit_val+1})', help_str.getvalue())
def test_ActionParser_action_groups(self): def get_parser_lv2(): parser_lv2 = ArgumentParser(description='parser_lv2 description') parser_lv2.add_argument('--a1', help='lv2_a1 help') group_lv2 = parser_lv2.add_argument_group( description='group_lv2 description') group_lv2.add_argument('--a2', help='lv2_a2 help') return parser_lv2 parser_lv2 = get_parser_lv2() parser = ArgumentParser() parser.add_argument('--lv2', action=ActionParser(parser_lv2)) out = StringIO() parser.print_help(out) outval = out.getvalue() self.assertIn('parser_lv2 description', outval) self.assertIn('group_lv2 description', outval) self.assertIn('--lv2.a1 A1', outval) parser_lv2 = get_parser_lv2() parser = ArgumentParser() parser.add_argument( '--lv2', title='ActionParser title', description='ActionParser description', action=ActionParser(parser_lv2), ) out = StringIO() parser.print_help(out) outval = out.getvalue() self.assertIn('ActionParser title', outval) self.assertIn('ActionParser description', outval)
def test_default_config_files_help(self): not_exist = 'does_not_exist.yaml' config_path = os.path.realpath(os.path.join(self.tmpdir, 'config.yaml')) with open(config_path, 'w') as output_file: output_file.write('v1: from yaml v1\nn1.v2: from yaml v2\n') parser = ArgumentParser(default_config_files=[not_exist, config_path]) parser.add_argument('--v1', default='from default v1') parser.add_argument('--n1.v2', default='from default v2') out = StringIO() parser.print_help(out) outval = out.getvalue() self.assertIn('default config file locations', outval) self.assertIn('from yaml v1', outval) self.assertIn('from yaml v2', outval) self.assertIn(str([not_exist, config_path]), outval) self.assertIn(config_path, outval) parser.default_config_files = [not_exist] out = StringIO() parser.print_help(out) outval = out.getvalue() self.assertIn('from default v1', outval) self.assertIn('from default v2', outval) self.assertIn(str([not_exist]), outval) self.assertIn('no existing default config file found', outval) parser.default_config_files = None out = StringIO() parser.print_help(out) outval = out.getvalue() self.assertNotIn('default config file locations', outval)