<commit_before>import collections
from build.error import ConfigError

Param = collections.namedtuple('Param', 'type default')

class ParamParser(object):
    """Parser for parameter strings.

    Parameter strings appear in command line arguments, and have the form
    'key=val:key2=val2'.
    """
    __init__ = ['_params']
    def __init__(self):
        self._params = {}
    def add_param(self, name, *, type=None, default=None):
        if name in self._params:
            raise Exception('duplicate parameter')
        self._params[name] = Param(type, default)
    def parse(self, x):
        result = {}
        for part in x.split(':') if x is not None else ():
            i = part.find('=')
            if i >= 0:
                name = part[:i]
                val = part[i+1:]
            else:
                name = part
                val = ''
            try:
                param = self._params[name]
            except KeyError:
                raise ConfigError('no such parameter: {!r}'.format(name))
            if name in result:
                raise ConfigError('duplicate parameter: {}'.format(name))
            if param.type is not None:
                try:<commit_msg>build: add 'bool' type to parameter parser<commit_after>import collections
from build.error import ConfigError

Param = collections.namedtuple('Param', 'type default')

def parse_bool(x):
    y = x.lower()
    if y in ('yes', 'true', 'on', '1'):
        return True
    if y in ('no', 'false', 'off', '0'):
        return False
    raise ValueError('invalid boolean')

TYPES = {
    'bool': parse_bool,
}

class ParamParser(object):
    """Parser for parameter strings.

    Parameter strings appear in command line arguments, and have the form
    'key=val:key2=val2'.
    """
    __init__ = ['_params']
    def __init__(self):
        self._params = {}
    def add_param(self, name, *, type=None, default=None):
        if isinstance(type, str):
            try:
                type = TYPES[type]
            except KeyError:
                raise ValueError('unknown type: {!r}'.format(type))
        if name in self._params:
            raise Exception('duplicate parameter')
        self._params[name] = Param(type, default)
    def parse(self, x):
        result = {}
        for part in x.split(':') if x is not None else ():
            i = part.find('=')
            if i >= 0:
                name = part[:i]
                val = part[i+1:]
            else:
                name = part
                val = ''
            try:
                param = self._params[name]
            except KeyError:
                raise ConfigError('no such parameter: {!r}'.format(name))
            if name in result:
                raise ConfigError('duplicate parameter: {}'.format(name))
            if param.type is not None:
                try:
{'fraction_non_alphanumeric': 0.11952330879775674, 'fraction_numerical': 0.0035050823694356818, 'mean_word_length': 1.8201581027667983, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6137440', 'n_tokens_mistral': 793, 'n_tokens_neox': 776, 'n_words': 243}