Ejemplo n.º 1
0
def test_cant_convert_to_type():
    """
    add an argument that must catch an int value, Parse a string that
    contains only this argument with a value that is not an int test if an
    """
    parser = MainParser(help_arg=False)
    parser.add_argument('a', type=int)

    with pytest.raises(BadTypeException):
        parser.parse('-a a'.split())
Ejemplo n.º 2
0
def test_add_two_short_name():
    """
    Parse an argument with a value that doesn't respect the check function of
    this argument. Test if a BadValueException is raised

    """
    parser = MainParser(help_arg=False)
    parser.add_argument('coco', type=int, check=lambda x: x > 2)

    with pytest.raises(BadValueException):
        parser.parse('--coco 1'.split())
Ejemplo n.º 3
0
def test_parse_empty_string_default_value():
    parser = MainParser(help_arg=False)
    parser.add_argument('a', default=1)
    result = parser.parse(''.split())
    assert len(result) == 1
    assert 'a' in result
    assert result['a'] == 1
Ejemplo n.º 4
0
def test_other_type():
    """
    add an argument that must catch an int value, Parse a string that
    contains only this argument and test if the value contained in the result is
    an int

    """
    parser = MainParser(help_arg=False)
    parser.add_argument('a', type=int)
    result = parser.parse('-a 1'.split())
    assert len(result) == 1
    assert 'a' in result
    assert isinstance(result['a'], int)
Ejemplo n.º 5
0
def test_default_type():
    """
    add an argument without specifing the type it must catch. Parse a string
    that contains only this argument and test if the value contained in the
    result is a string

    """
    parser = MainParser(help_arg=False)
    parser.add_argument('a')
    result = parser.parse('-a 1'.split())
    assert len(result) == 1
    assert 'a' in result
    assert isinstance(result['a'], str)
Ejemplo n.º 6
0
class MainConfigParser(ConfigParser):
    """
    Parser abstraction for the configuration
    """
    def __init__(self):
        ConfigParser.__init__(self)
        self.subparser = {}
        self.cli_parser = MainParser()

    def add_subparser(self, name, subparser: SubConfigParser, help=''):
        """
        Add a SubParser to call when <name> is encoutered
        When name is encoutered, the subarpser such as subparser.name match conf[name].type

        """
        if name in self.subparser:
            if subparser.name in list(self.subparser[name]):
                raise AlreadyAddedSubparserException(name)
        else:
            self.subparser[name] = {}

        self.subparser[name][subparser.name] = subparser

        self.cli_parser.add_actor_subparser(name, subparser.cli_parser, help)

    def _parse_cli(self, cli_line):
        return self.cli_parser.parse(cli_line)

    @staticmethod
    def _parse_file(filename):
        config_file = open(filename, 'r')
        conf = json.load(config_file)
        return conf

    def _validate(self, conf: Dict):
        """ Check the parsed configuration"""

        # Check that all the mandatory arguments are precised
        mandatory_args = self._get_mandatory_args()
        for arg in mandatory_args:
            if arg not in conf:
                raise MissingArgumentException(arg)

        # check types
        for args, value in conf.items():
            is_an_arg = False
            if args in self.subparser:
                for _, dic_value in value.items():
                    self.subparser[args][dic_value["type"]].validate(dic_value)
                    is_an_arg = True

            for _, waited_value in self.args.items():
                if args in waited_value.names:
                    is_an_arg = True
                    # check type
                    if not isinstance(
                            value,
                            waited_value.type) and not waited_value.is_flag:
                        raise BadTypeException(args, waited_value.type)

            if not is_an_arg:
                raise UnknowArgException(args)

        for args, value in self.args.items():
            is_precised = False
            for name in value.names:
                if name in conf:
                    is_precised = True
                    break
            if not is_precised and value.default_value is not None:
                conf[args] = value.default_value

        return conf

    def parse(self, args=None):
        """
        Find the configuration method (CLI or config file)
        Call the method to produce a configuration dictionnary
        check the configuration
        """

        if args is None:
            args = sys.argv
        i = 0
        filename = None
        for s in args:
            if s == '--config-file':
                if i + 1 == len(args):
                    logging.error(
                        "CLI Error: config file path needed with argument --config-file"
                    )
                    sys.exit(-1)
                filename = args[i + 1]
            i += 1

        try:
            if filename is not None:
                conf = self._parse_file(filename)
            else:
                conf = self._parse_cli(args[1:])
            conf = self._validate(conf)

        except MissingValueException as exn:
            msg = 'CLI error: argument ' + exn.argument_name + ': expect a value'
            logging.error(msg)
            sys.exit(-1)

        except BadTypeException as exn:
            msg = "Configuration error: " + exn.msg
            logging.error(msg)
            sys.exit(-1)

        except UnknowArgException as exn:
            msg = 'Configuration error: unknow argument ' + exn.argument_name
            logging.error(msg)
            sys.exit(-1)

        except BadContextException as exn:
            msg = 'CLI error: argument ' + exn.argument_name
            msg += ' not used in the correct context\nUse it with the following arguments:'
            for main_arg_name, context_name in exn.context_list:
                msg += '\n  --' + main_arg_name + ' ' + context_name
            logging.error(msg)
            sys.exit(-1)

        except FileNotFoundError:
            logging.error("Configuration Error: configuration file not found")
            sys.exit(-1)

        except json.JSONDecodeError as exn:
            logging.error('Configuration Error: JSON Error: ' + exn.msg +
                          ' at line' + exn.lineno + ' colomn ' + exn.colno)
            sys.exit(-1)

        except MissingArgumentException as exn:
            logging.error("Configuration Error: " + exn.msg)
            sys.exit(-1)

        return conf