コード例 #1
0
    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)
コード例 #2
0
    def test_linking_deep_targets_mapping(self):
        class D:
            pass

        class A:
            def __init__(self, d: D) -> None:
                self.d = d

        class BSuper:
            pass

        class BSub(BSuper):
            def __init__(self, a_map: Mapping[str, A]) -> None:
                self.a_map = a_map

        class C:
            def fn(self) -> D:
                return D()

        with mock_module(D, A, BSuper, BSub, C) as module:
            config = {
                "b": {
                    "class_path": f"{module}.BSub",
                    "init_args": {
                        "a_map": {
                            "name": {
                                "class_path": f"{module}.A",
                            },
                        },
                    },
                },
                "c": {},
            }
            config_path = os.path.join(self.tmpdir, 'config.yaml')
            with open(config_path, 'w') as f:
                yaml.safe_dump(config, f)

            parser = ArgumentParser()
            parser.add_argument("--config", action=ActionConfigFile)
            parser.add_subclass_arguments(BSuper,
                                          nested_key="b",
                                          required=True)
            parser.add_class_arguments(C, nested_key="c")
            parser.link_arguments("c",
                                  "b.init_args.a_map.name.init_args.d",
                                  compute_fn=C.fn,
                                  apply_on="instantiate")

            config = parser.parse_args(["--config", config_path])
            config_init = parser.instantiate_classes(config)
            self.assertIsInstance(config_init["b"].a_map["name"].d, D)

            config_init = parser.instantiate_classes(config)
            self.assertIsInstance(config_init["b"].a_map["name"].d, D)
コード例 #3
0
    def test_enable_path(self):
        data = {'a': 1, 'b': 2, 'c': [3, 4]}
        cal = {'class_path': 'calendar.Calendar'}
        with open('data.yaml', 'w') as f:
            json.dump(data, f)
        with open('cal.yaml', 'w') as f:
            json.dump(cal, f)

        parser = ArgumentParser(error_handler=None)
        parser.add_argument('--data', type=Dict[str, Any], enable_path=True)
        parser.add_argument('--cal', type=Calendar, enable_path=True)
        cfg = parser.parse_args(['--data=data.yaml'])
        self.assertEqual('data.yaml', str(cfg['data'].pop('__path__')))
        self.assertEqual(data, cfg['data'])
        cfg = parser.instantiate_classes(parser.parse_args(['--cal=cal.yaml']))
        self.assertIsInstance(cfg['cal'], Calendar)
        self.assertRaises(
            ParserError,
            lambda: parser.parse_args(['--data=does-not-exist.yaml']))
コード例 #4
0
    def test_mapping_class_typehint(self):
        class A:
            pass

        class B:
            def __init__(
                self,
                class_map: Mapping[str, A],
                int_list: List[int],
            ):
                self.class_map = class_map
                self.int_list = int_list

        with mock_module(A, B) as module:
            parser = ArgumentParser(error_handler=None)
            parser.add_class_arguments(B, 'b')

            config = {
                'b': {
                    'class_map': {
                        'one': {
                            'class_path': f'{module}.A'
                        },
                    },
                    'int_list': [1],
                },
            }

            cfg = parser.parse_object(config)
            self.assertEqual(cfg.b.class_map,
                             {'one': Namespace(class_path=f'{module}.A')})
            self.assertEqual(cfg.b.int_list, [1])

            cfg_init = parser.instantiate_classes(cfg)
            self.assertIsInstance(cfg_init.b, B)
            self.assertIsInstance(cfg_init.b.class_map, dict)
            self.assertIsInstance(cfg_init.b.class_map['one'], A)

            config['b']['int_list'] = config['b']['class_map']
            self.assertRaises(ParserError, lambda: parser.parse_object(config))
コード例 #5
0
    def test_Callable_with_class_path(self):
        class MyFunc1:
            def __init__(self, p1: int = 1):
                self.p1 = p1

            def __call__(self):
                return self.p1

        class MyFunc2(MyFunc1):
            pass

        parser = ArgumentParser(error_handler=None)
        parser.add_argument('--callable', type=Callable)

        with mock_module(MyFunc1, MyFunc2) as module:
            value = {'class_path': f'{module}.MyFunc2', 'init_args': {'p1': 1}}
            cfg = parser.parse_args([f'--callable={module}.MyFunc2'])
            self.assertEqual(cfg.callable.as_dict(), value)
            value = {'class_path': f'{module}.MyFunc1', 'init_args': {'p1': 2}}
            cfg = parser.parse_args([f'--callable={json.dumps(value)}'])
            self.assertEqual(cfg.callable.as_dict(), value)
            self.assertEqual(
                yaml.safe_load(parser.dump(cfg))['callable'], value)
            cfg_init = parser.instantiate_classes(cfg)
            self.assertIsInstance(cfg_init.callable, MyFunc1)
            self.assertEqual(cfg_init.callable(), 2)

            self.assertRaises(ParserError,
                              lambda: parser.parse_args(['--callable={}']))
            self.assertRaises(
                ParserError, lambda: parser.parse_args(
                    ['--callable=jsonargparse.SUPPRESS']))
            self.assertRaises(
                ParserError,
                lambda: parser.parse_args(['--callable=calendar.Calendar']))
            value = {'class_path': f'{module}.MyFunc1', 'key': 'val'}
            self.assertRaises(
                ParserError,
                lambda: parser.parse_args([f'--callable={json.dumps(value)}']))
コード例 #6
0
    def test_class_type(self):
        parser = ArgumentParser(error_handler=None)
        parser.add_argument('--op', type=Optional[List[Calendar]])

        class_path = '"class_path": "calendar.Calendar"'
        expected = [{
            'class_path': 'calendar.Calendar',
            'init_args': {
                'firstweekday': 0
            }
        }]
        cfg = parser.parse_args(['--op=[{' + class_path + '}]'])
        self.assertEqual(cfg.as_dict()['op'], expected)
        cfg = parser.parse_args(['--op=["calendar.Calendar"]'])
        self.assertEqual(cfg.as_dict()['op'], expected)
        cfg = parser.instantiate_classes(cfg)
        self.assertIsInstance(cfg['op'][0], Calendar)

        with self.assertRaises(ParserError):
            parser.parse_args(
                ['--op=[{"class_path": "jsonargparse.ArgumentParser"}]'])
        with self.assertRaises(ParserError):
            parser.parse_args(
                ['--op=[{"class_path": "jsonargparse.NotExist"}]'])
        with self.assertRaises(ParserError):
            parser.parse_args(
                ['--op=[{"class_path": "jsonargparse0.IncorrectModule"}]'])
        with self.assertRaises(ParserError):
            parser.parse_args(['--op=[1]'])

        init_args = '"init_args": {"bad_arg": True}'
        with self.assertRaises(ParserError):
            parser.parse_args(
                ['--op=[{' + class_path + ', ' + init_args + '}]'])

        init_args = '"init_args": {"firstweekday": 3}'
        cfg = parser.parse_args(
            ['--op=[{' + class_path + ', ' + init_args + '}]'])
        self.assertEqual(cfg['op'][0]['init_args'].as_dict(),
                         {'firstweekday': 3})
        cfg = parser.instantiate_classes(cfg)
        self.assertIsInstance(cfg['op'][0], Calendar)
        self.assertEqual(3, cfg['op'][0].firstweekday)

        parser = ArgumentParser(error_handler=None)
        parser.add_argument('--n.op', type=Optional[Calendar])
        cfg = parser.parse_args(
            ['--n.op={' + class_path + ', ' + init_args + '}'])
        cfg = parser.instantiate_classes(cfg)
        self.assertIsInstance(cfg['n']['op'], Calendar)
        self.assertEqual(3, cfg['n']['op'].firstweekday)

        parser = ArgumentParser()
        parser.add_argument('--op', type=Calendar)
        cfg = parser.parse_args(
            ['--op={' + class_path + ', ' + init_args + '}'])
        cfg = parser.instantiate_classes(cfg)
        self.assertIsInstance(cfg['op'], Calendar)
        self.assertEqual(3, cfg['op'].firstweekday)

        cfg = parser.instantiate_classes(parser.parse_args([]))
        self.assertIsNone(cfg['op'])