def test_nargs_questionmark(self):
     parser = ArgumentParser(error_handler=None)
     parser.add_argument('p1')
     parser.add_argument('p2', nargs='?', type=OpenUnitInterval)
     self.assertIsNone(parser.parse_args(['a']).p2)
     self.assertEqual(0.5, parser.parse_args(['a', '0.5']).p2)
     self.assertRaises(ParserError, lambda: parser.parse_args(['a', 'b']))
 def test_list_path(self):
     parser = ArgumentParser()
     parser.add_argument('--paths', type=List[Path_fc])
     cfg = parser.parse_args(['--paths=["file1", "file2"]'])
     self.assertEqual(['file1', 'file2'], cfg.paths)
     self.assertIsInstance(cfg.paths[0], Path)
     self.assertIsInstance(cfg.paths[1], Path)
    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_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_typehint_non_parameterized_types(self, type):
     parser = ArgumentParser(error_handler=None)
     ActionTypeHint.is_supported_typehint(type, full=True)
     parser.add_argument('--type', type=type)
     cfg = parser.parse_args(['--type=uuid.UUID'])
     self.assertEqual(cfg.type, uuid.UUID)
     self.assertEqual(parser.dump(cfg), 'type: uuid.UUID\n')
    def test_dict_union(self):
        class MyEnum(Enum):
            ab = 1

        parser = ArgumentParser(error_handler=None)
        parser.add_argument('--dict1',
                            type=Dict[int, Optional[Union[float, MyEnum]]])
        parser.add_argument('--dict2', type=Dict[str, Union[bool, Path_fc]])
        cfg = parser.parse_args(
            ['--dict1={"2":4.5, "6":"ab"}', '--dict2={"a":true, "b":"f"}'])
        self.assertEqual({2: 4.5, 6: MyEnum.ab}, cfg['dict1'])
        self.assertEqual({'a': True, 'b': 'f'}, cfg['dict2'])
        self.assertIsInstance(cfg['dict2']['b'], Path)
        self.assertEqual({5: None},
                         parser.parse_args(['--dict1={"5":null}'])['dict1'])
        self.assertRaises(ParserError,
                          lambda: parser.parse_args(['--dict1=["a", "b"]']))
        cfg = yaml.safe_load(parser.dump(cfg))
        self.assertEqual(
            {
                'dict1': {
                    '2': 4.5,
                    '6': 'ab'
                },
                'dict2': {
                    'a': True,
                    'b': 'f'
                }
            }, cfg)
    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_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_ActionParser_required(self):
     p1 = ArgumentParser()
     p1.add_argument('--op1', required=True)
     p2 = ArgumentParser(error_handler=None)
     p2.add_argument('--op2', action=ActionParser(parser=p1))
     p2.parse_args(['--op2.op1=1'])
     self.assertRaises(ParserError, lambda: p2.parse_args([]))
 def test_list(self):
     for list_type in [Iterable, List, Sequence]:
         with self.subTest(str(list_type)):
             parser = ArgumentParser()
             parser.add_argument('--list', type=list_type[int])
             cfg = parser.parse_args(['--list=[1, 2]'])
             self.assertEqual([1, 2], cfg.list)
    def test_subcommand_with_subclass_default_override_lightning_issue_10859(
            self):
        class Arch:
            def __init__(self, a: int = 1):
                pass

        class ArchB(Arch):
            def __init__(self, a: int = 2, b: int = 3):
                pass

        class ArchC(Arch):
            def __init__(self, a: int = 4, c: int = 5):
                pass

        parser = ArgumentParser(error_handler=None)
        parser_subcommands = parser.add_subcommands()
        subparser = ArgumentParser()
        subparser.add_argument('--arch', type=Arch)

        with mock_module(Arch, ArchB, ArchC) as module:
            default = {'class_path': f'{module}.ArchB'}
            value = {
                'class_path': f'{module}.ArchC',
                'init_args': {
                    'a': 10,
                    'c': 11
                }
            }

            subparser.set_defaults(arch=default)
            parser_subcommands.add_subcommand('fit', subparser)

            cfg = parser.parse_args(['fit', f'--arch={json.dumps(value)}'])
            self.assertEqual(cfg.fit.arch.as_dict(), value)
示例#12
0
    def test_ActionJsonnet(self):
        parser = ArgumentParser(default_meta=False, error_handler=None)
        parser.add_argument('--input.ext_vars', action=ActionJsonnetExtVars())
        parser.add_argument('--input.jsonnet',
                            action=ActionJsonnet(
                                ext_vars='input.ext_vars',
                                schema=json.dumps(example_schema)))

        cfg2 = parser.parse_args([
            '--input.ext_vars', '{"param": 123}', '--input.jsonnet',
            example_2_jsonnet
        ])
        self.assertEqual(123, cfg2.input.jsonnet['param'])
        self.assertEqual(9, len(cfg2.input.jsonnet['records']))
        self.assertEqual('#8', cfg2.input.jsonnet['records'][-2]['ref'])
        self.assertEqual(15.5, cfg2.input.jsonnet['records'][-2]['val'])

        cfg1 = parser.parse_args(['--input.jsonnet', example_1_jsonnet])
        self.assertEqual(cfg1.input.jsonnet['records'],
                         cfg2.input.jsonnet['records'])

        self.assertRaises(
            ParserError, lambda: parser.parse_args([
                '--input.ext_vars', '{"param": "a"}', '--input.jsonnet',
                example_2_jsonnet
            ]))
        self.assertRaises(
            ParserError,
            lambda: parser.parse_args(['--input.jsonnet', example_2_jsonnet]))

        self.assertRaises(ValueError, lambda: ActionJsonnet(ext_vars=2))
        self.assertRaises(
            ValueError,
            lambda: ActionJsonnet(schema='.' + json.dumps(example_schema)))
 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
    def test_ActionYesNo_parse_env(self):
        parser = example_parser()
        self.assertEqual(
            True,
            parser.parse_env({
                'APP_BOOLS__DEF_FALSE': 'true'
            }).bools.def_false)
        self.assertEqual(
            True,
            parser.parse_env({
                'APP_BOOLS__DEF_FALSE': 'yes'
            }).bools.def_false)
        self.assertEqual(
            False,
            parser.parse_env({
                'APP_BOOLS__DEF_TRUE': 'false'
            }).bools.def_true)
        self.assertEqual(
            False,
            parser.parse_env({
                'APP_BOOLS__DEF_TRUE': 'no'
            }).bools.def_true)

        parser = ArgumentParser(default_env=True, env_prefix='APP')
        parser.add_argument('--op', action=ActionYesNo, default=False)
        self.assertEqual(True, parser.parse_env({'APP_OP': 'true'}).op)
    def test_class_type_subclass_nested_help(self):
        class Class:
            def __init__(self, cal: Calendar, p1: int = 0):
                self.cal = cal

        parser = ArgumentParser()
        parser.add_argument('--op', type=Class)

        for pattern in [r'[\s=]', r'\s']:
            with self.subTest('" "' if '=' in pattern else '"="'), mock_module(
                    Class) as module:
                out = StringIO()
                args = re.split(
                    pattern,
                    f'--op.help={module}.Class --op.init_args.cal.help=TextCalendar'
                )
                with redirect_stdout(out), self.assertRaises(SystemExit):
                    parser.parse_args(args)
                self.assertIn('--op.init_args.cal.init_args.firstweekday',
                              out.getvalue())

        with self.subTest('invalid'), mock_module(Class) as module:
            err = StringIO()
            with redirect_stderr(err), self.assertRaises(SystemExit):
                parser.parse_args(
                    [f'--op.help={module}.Class', '--op.init_args.p1=1'])
            self.assertIn('Expected a nested --*.help option', err.getvalue())
    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']
示例#17
0
def get_parser():
    """Returns the argument parser object for the command line tool."""
    ## validate parser ##
    parser_validate = ModuleArchitecture.get_config_parser()
    parser_validate.description = 'Command for checking the validity of neural network module architecture files.'
    parser_validate.set_defaults(propagators='default')
    parser_validate.add_argument(
        'jsonnet_paths',
        action=ActionPath(mode='fr'),
        nargs='+',
        help=
        'Path(s) to neural network module architecture file(s) in jsonnet narchi format.'
    )

    ## render parser ##
    parser_render = ModuleArchitectureRenderer.get_config_parser()
    parser_render.description = 'Command for rendering a neural network module architecture file.'
    parser_render.set_defaults(propagators='default')
    parser_render.add_argument(
        'jsonnet_path',
        action=ActionPath(mode='fr'),
        help=
        'Path to a neural network module architecture file in jsonnet narchi format.'
    )
    parser_render.add_argument(
        'out_file',
        nargs='?',
        action=ActionPath(mode='fc'),
        help=
        'Path where to write the architecture diagram (with a valid extension for pygraphviz draw). If '
        'unset a pdf is saved to the output directory.')

    ## schema parser ##
    parser_schema = ArgumentParser(
        description='Prints a schema as a pretty json.')
    parser_schema.add_argument(
        'schema',
        nargs='?',
        default='narchi',
        choices=[x for x in schemas.keys() if x is not None],
        help='Which of the available schemas to print.')

    ## global parser ##
    parser = ArgumentParser(description=__doc__, version=__version__)
    parser.add_argument(
        '--stack_trace',
        type=bool,
        default=False,
        help='Whether to print stack trace when there are errors.')
    parser.parser_validate = parser_validate
    parser.parser_render = parser_render
    parser.parser_schema = parser_schema

    subcommands = parser.add_subcommands()
    subcommands.add_subcommand('validate', parser_validate)
    subcommands.add_subcommand('render', parser_render)
    subcommands.add_subcommand('schema', parser_schema)

    return parser
示例#18
0
    def get_config_parser():

        parser = ArgumentParser()
        parser.add_argument("--factor",
                            type=int,
                            default=2,
                            help="Factor to multiply")
        return parser
 def test_nested_mapping_without_args(self):
     parser = ArgumentParser()
     parser.add_argument('--map', type=Mapping[str, Union[int, Mapping]])
     self.assertEqual(parser.parse_args(['--map={"a": 1}']).map, {"a": 1})
     self.assertEqual(
         parser.parse_args(['--map={"b": {"c": 2}}']).map, {"b": {
             "c": 2
         }})
 def test_ActionParser_conflict(self):
     parser_lv2 = ArgumentParser()
     parser_lv2.add_argument('--op')
     parser = ArgumentParser(error_handler=None)
     parser.add_argument('--inner.op')
     self.assertRaises(
         ValueError,
         lambda: parser.add_argument('--inner',
                                     action=ActionParser(parser_lv2)))
    def test_list_enum(self):
        class MyEnum(Enum):
            ab = 0
            xy = 1

        parser = ArgumentParser(error_handler=None)
        parser.add_argument('--list', type=List[MyEnum])
        self.assertEqual([MyEnum.xy, MyEnum.ab],
                         parser.parse_args(['--list=["xy", "ab"]']).list)
 def test_nested_tuples(self):
     parser = ArgumentParser(error_handler=None)
     parser.add_argument('--tuple',
                         type=Tuple[Tuple[str, str],
                                    Tuple[Tuple[int, float], Tuple[int,
                                                                   float]]])
     cfg = parser.parse_args(
         ['--tuple=[["foo", "bar"], [[1, 2.02], [3, 3.09]]]'])
     self.assertEqual((('foo', 'bar'), ((1, 2.02), (3, 3.09))), cfg.tuple)
 def test_no_str_strip(self):
     parser = ArgumentParser(error_handler=None)
     parser.add_argument('--op', type=Optional[str])
     parser.add_argument('--cfg', action=ActionConfigFile)
     self.assertEqual('  ', parser.parse_args(['--op', '  ']).op)
     self.assertEqual('', parser.parse_args(['--op', '']).op)
     self.assertEqual(' abc ', parser.parse_args(['--op= abc ']).op)
     self.assertEqual(' ', parser.parse_args(['--cfg={"op":" "}']).op)
     self.assertIsNone(parser.parse_args(['--op=null']).op)
 def _test_typehint_parameterized_types(self, type):
     parser = ArgumentParser(error_handler=None)
     ActionTypeHint.is_supported_typehint(type, full=True)
     parser.add_argument('--cal', type=type[Calendar])
     cfg = parser.parse_args(['--cal=calendar.Calendar'])
     self.assertEqual(cfg.cal, Calendar)
     self.assertEqual(parser.dump(cfg), 'cal: calendar.Calendar\n')
     self.assertRaises(ParserError,
                       lambda: parser.parse_args(['--cal=uuid.UUID']))
示例#25
0
 def test_ActionPath_skip_check(self):
     parser = ArgumentParser(error_handler=None)
     parser.add_argument('--file',
                         action=ActionPath(mode='fr', skip_check=True))
     cfg = parser.parse_args(['--file=not-exist'])
     self.assertIsInstance(cfg.file, Path)
     self.assertEqual(str(cfg.file), 'not-exist')
     self.assertEqual(parser.dump(cfg), 'file: not-exist\n')
     self.assertTrue(repr(cfg.file).startswith('Path_fr_skip_check'))
def get_parser():
    parser = ArgumentParser()
    parser.add_argument('xml',
                        action=ActionPath(mode='fr'),
                        help='Page XML file to process.')
    parser.add_argument('--with_conf',
                        type=bool,
                        default=False,
                        help='Whether to include confidences.')
    return parser
示例#27
0
    def test_ActionPath_dump(self):
        parser = ArgumentParser()
        parser.add_argument('--path', action=ActionPath(mode='fc'))
        cfg = parser.parse_string('path: path')
        self.assertEqual(parser.dump(cfg), 'path: path\n')

        parser = ArgumentParser()
        parser.add_argument('--paths', nargs='+', action=ActionPath(mode='fc'))
        cfg = parser.parse_args(['--paths', 'path1', 'path2'])
        self.assertEqual(parser.dump(cfg), 'paths:\n- path1\n- path2\n')
    def get_config_parser():

        parser = ArgumentParser()
        parser.add_argument(
            "--producer",
            action=ActionParser(parser=Producer.get_config_parser()))
        parser.add_argument(
            "--transformer",
            action=ActionParser(parser=Transformer.get_config_parser()))
        return parser
 def test_optional_path(self):
     pathlib.Path('file_fr').touch()
     parser = ArgumentParser(error_handler=None)
     parser.add_argument('--path', type=Optional[Path_fr])
     self.assertIsNone(parser.parse_args(['--path=null']).path)
     cfg = parser.parse_args(['--path=file_fr'])
     self.assertEqual('file_fr', cfg.path)
     self.assertIsInstance(cfg.path, Path)
     self.assertRaises(ParserError,
                       lambda: parser.parse_args(['--path=not_exist']))
 def test_invalid_init_args_in_yaml(self):
     config = """cal:
         class_path: calendar.Calendar
         init_args:
     """
     parser = ArgumentParser(error_handler=None)
     parser.add_argument('--config', action=ActionConfigFile)
     parser.add_argument('--cal', type=Calendar)
     self.assertRaises(ParserError,
                       lambda: parser.parse_args([f'--config={config}']))