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']))
예제 #7
0
    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)
예제 #9
0
 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')
예제 #10
0
 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}')