Пример #1
0
    def test_add_function_arguments(self):
        def func(a1='1', a2: float = 2.0, a3: bool = False, a4=None):
            """func short description

            Args:
                a1: a1 description
                a2: a2 description
                a4: a4 description
            """
            return a1

        parser = ArgumentParser()
        parser.add_function_arguments(func)

        self.assertRaises(ValueError,
                          lambda: parser.add_function_arguments('func'))

        self.assertIn('func', parser.groups)

        for key in ['a1', 'a2', 'a3']:
            self.assertIsNotNone(_find_action(parser, key),
                                 key + ' should be in parser but is not')
        self.assertIsNone(_find_action(parser, 'a4'),
                          'a4 should not be in parser but is')

        cfg = namespace_to_dict(parser.parse_args(['--a1=x'], with_meta=False))
        self.assertEqual(cfg, {'a1': 'x', 'a2': 2.0, 'a3': False})
        self.assertEqual('x', func(**cfg))

        if docstring_parser_support:
            self.assertEqual('func short description',
                             parser.groups['func'].title)
            for key in ['a1', 'a2']:
                self.assertEqual(key + ' description',
                                 _find_action(parser, key).help)
Пример #2
0
    def test_skip(self):
        def func(a1='1', a2: float = 2.0, a3: bool = False, a4: int = 4):
            return a1

        parser = ArgumentParser()
        parser.add_function_arguments(func, skip={'a2', 'a4'})

        for key in ['a1', 'a3']:
            self.assertIsNotNone(_find_action(parser, key),
                                 key + ' should be in parser but is not')
        for key in ['a2', 'a4']:
            self.assertIsNone(_find_action(parser, key),
                              key + ' should not be in parser but is')
Пример #3
0
    def test_add_method_arguments(self):
        class MyClass:
            def mymethod(self,
                         a1='1',
                         a2: float = 2.0,
                         a3: bool = False,
                         a4=None):
                """mymethod short description

                Args:
                    a1: a1 description
                    a2: a2 description
                    a4: a4 description
                """
                return a1

            @staticmethod
            def mystaticmethod(a1: str, a2: float = 2.0, a3=None):
                return a1

        parser = ArgumentParser()
        parser.add_method_arguments(MyClass, 'mymethod', 'm')
        parser.add_method_arguments(MyClass, 'mystaticmethod', 's')

        self.assertRaises(
            ValueError,
            lambda: parser.add_method_arguments('MyClass', 'mymethod'))
        self.assertRaises(
            ValueError,
            lambda: parser.add_method_arguments(MyClass, 'mymethod3'))

        self.assertIn('m', parser.groups)
        self.assertIn('s', parser.groups)

        for key in ['m.a1', 'm.a2', 'm.a3', 's.a1', 's.a2']:
            self.assertIsNotNone(_find_action(parser, key),
                                 key + ' should be in parser but is not')
        for key in ['m.a4', 's.a3']:
            self.assertIsNone(_find_action(parser, key),
                              key + ' should not be in parser but is')

        cfg = namespace_to_dict(
            parser.parse_args(['--m.a1=x', '--s.a1=y'], with_meta=False))
        self.assertEqual(cfg, {
            'm': {
                'a1': 'x',
                'a2': 2.0,
                'a3': False
            },
            's': {
                'a1': 'y',
                'a2': 2.0
            }
        })
        self.assertEqual('x', MyClass().mymethod(**cfg['m']))
        self.assertEqual('y', MyClass.mystaticmethod(**cfg['s']))

        if docstring_parser_support:
            self.assertEqual('mymethod short description',
                             parser.groups['m'].title)
            self.assertEqual(str(MyClass.mystaticmethod),
                             parser.groups['s'].title)
            for key in ['m.a1', 'm.a2']:
                self.assertEqual(
                    key.split('.')[1] + ' description',
                    _find_action(parser, key).help)
            for key in ['m.a3', 's.a1', 's.a2']:
                self.assertIsNone(
                    _find_action(parser, key).help,
                    'expected help for ' + key + ' to be None')
Пример #4
0
    def test_add_class_arguments(self):
        class Class0:
            def __init__(self, c0_a0: Optional[str] = '0'):
                pass

        class Class1(Class0):
            def __init__(self,
                         c1_a1: str,
                         c1_a2: Any = 2.0,
                         c1_a3=None,
                         c1_a4: int = 4,
                         c1_a5: str = '5'):
                """Class1 short description

                Args:
                    c1_a3: c1_a3 description
                """
                super().__init__()
                self.c1_a1 = c1_a1

            def __call__(self):
                return self.c1_a1

        class Class2(Class1):
            """Class2 short description

            Args:
                c1_a2: c1_a2 description
            """
            def __init__(self, c2_a0, c3_a4, *args, **kwargs):
                super().__init__(c3_a4, *args, **kwargs)

        class Class3(Class2):
            def __init__(self,
                         c3_a0: Any,
                         c3_a1='1',
                         c3_a2: float = 2.0,
                         c3_a3: bool = False,
                         c3_a4: Optional[str] = None,
                         c3_a5: Union[int, float, str, List[int],
                                      Dict[str, float]] = 5,
                         c3_a6: Optional[Class1] = None,
                         c3_a7: Tuple[str, int, float] = ('7', 7, 7.0),
                         c3_a8: Tuple[str, Class1] = None,
                         c1_a5: str = 'five',
                         **kwargs):
                """Class3 short description

                Args:
                    c3_a0: c3_a0 description
                    c3_a1: c3_a1 description
                    c3_a2: c3_a2 description
                    c3_a4: c3_a4 description
                    c3_a5: c3_a5 description
                """
                super().__init__(None, c3_a4, **kwargs)

        ## Test without nesting ##
        parser = ArgumentParser(error_handler=None)
        parser.add_class_arguments(Class3)

        self.assertRaises(ValueError,
                          lambda: parser.add_class_arguments('Class3'))

        self.assertIn('Class3', parser.groups)

        for key in [
                'c3_a0', 'c3_a1', 'c3_a2', 'c3_a3', 'c3_a4', 'c3_a5', 'c3_a6',
                'c3_a7', 'c3_a8', 'c1_a2', 'c1_a4', 'c1_a5'
        ]:
            self.assertIsNotNone(_find_action(parser, key),
                                 key + ' should be in parser but is not')
        for key in ['c2_a0', 'c1_a1', 'c1_a3', 'c0_a0']:
            self.assertIsNone(_find_action(parser, key),
                              key + ' should not be in parser but is')

        cfg = parser.parse_args(['--c3_a0=0', '--c3_a3=true', '--c3_a4=a'],
                                with_meta=False)
        self.assertEqual(
            namespace_to_dict(cfg), {
                'c1_a2': 2.0,
                'c1_a4': 4,
                'c1_a5': 'five',
                'c3_a0': 0,
                'c3_a1': '1',
                'c3_a2': 2.0,
                'c3_a3': True,
                'c3_a4': 'a',
                'c3_a5': 5,
                'c3_a6': None,
                'c3_a7': ('7', 7, 7.0),
                'c3_a8': None
            })
        self.assertEqual([1, 2],
                         parser.parse_args(['--c3_a0=0',
                                            '--c3_a5=[1,2]']).c3_a5)
        self.assertEqual({'k': 5.0},
                         namespace_to_dict(
                             parser.parse_args(
                                 ['--c3_a0=0', '--c3_a5={"k": 5.0}']).c3_a5))
        self.assertEqual(
            ('3', 3, 3.0),
            parser.parse_args(['--c3_a0=0', '--c3_a7=["3", 3, 3.0]']).c3_a7)
        self.assertEqual('a', Class3(**namespace_to_dict(cfg))())

        self.assertRaises(ParserError,
                          lambda: parser.parse_args([]))  # c3_a0 is required
        self.assertRaises(ParserError, lambda: parser.parse_args(
            ['--c3_a0=0', '--c3_a4=4.0']))  # c3_a4 is str or None
        self.assertRaises(ParserError, lambda: parser.parse_args(
            ['--c3_a0=0', '--c3_a7=["3", "3", 3.0]']))  # tuple[1] is int

        if docstring_parser_support:
            self.assertEqual('Class3 short description',
                             parser.groups['Class3'].title)
            for key in ['c3_a0', 'c3_a1', 'c3_a2', 'c3_a4', 'c3_a5', 'c1_a2']:
                self.assertEqual(key + ' description',
                                 _find_action(parser, key).help)
            for key in ['c3_a3', 'c3_a7', 'c1_a4']:
                self.assertIsNone(
                    _find_action(parser, key).help,
                    'expected help for ' + key + ' to be None')

        ## Test nested and as_group=False ##
        parser = ArgumentParser()
        parser.add_class_arguments(Class3, 'g', as_group=False)

        self.assertNotIn('g', parser.groups)

        for key in [
                'c3_a0', 'c3_a1', 'c3_a2', 'c3_a3', 'c3_a4', 'c3_a5', 'c3_a6',
                'c3_a7', 'c3_a8', 'c1_a2', 'c1_a4', 'c1_a5'
        ]:
            self.assertIsNotNone(_find_action(parser, 'g.' + key),
                                 key + ' should be in parser but is not')
        for key in ['c2_a0', 'c1_a1', 'c1_a3', 'c0_a0']:
            self.assertIsNone(_find_action(parser, 'g.' + key),
                              key + ' should not be in parser but is')

        ## Test default group title ##
        parser = ArgumentParser()
        parser.add_class_arguments(Class0)
        self.assertEqual(str(Class0), parser.groups['Class0'].title)

        ## Test positional without type ##
        self.assertRaises(ValueError,
                          lambda: parser.add_class_arguments(Class2))

        ## Test no arguments added ##
        class NoValidArgs:
            def __init__(self, a0=None):
                pass

        self.assertEqual(0, parser.add_class_arguments(NoValidArgs))

        def func(a1: Union[int, Dict[int, int]] = 1):
            pass

        parser = ArgumentParser()
        parser.add_function_arguments(func)
        parser.get_defaults()
        cfg = parser.parse_args(['--a1={"2": 7, "4": 9}'])
        self.assertEqual({
            2: 7,
            4: 9
        },
                         parser.parse_args(['--a1={"2": 7, "4": 9}']).a1)