Example #1
0
def determine_style(configuration: Configuration,
                    style_name: Optional[str] = None) -> Style:
    available_styles = configuration.available_styles()

    if style_name is None:
        if len(available_styles) == 1:
            style_name = available_styles[0]
        else:
            message = "Cannot pick a default style from file containing " \
                      "{0} styles"
            raise StylistException(message.format(len(available_styles)))

    if style_name not in available_styles:
        message = f"style '{style_name}' not found in configuration"
        raise StylistException(message)

    # Todo: It would be nice to remove abstracts from this list but I haven't
    #       worked out how yet.
    #
    potential_rules: Dict[str, Type[stylist.rule.Rule]] \
        = {cls.__name__: cls for cls in _all_subclasses(stylist.rule.Rule)}

    rules: List[stylist.rule.Rule] = []
    rule_list = configuration.get_style(style_name)
    if not isinstance(rule_list, list):
        raise TypeError('Style rules should be a list of names')
    for rule_description in rule_list:
        rule_name, _, rule_arguments_string = rule_description.partition('(')
        rule_name = rule_name.strip()
        rule_arguments_string, _, _ = rule_arguments_string.partition(')')
        rule_arguments: List[str] = []
        if rule_arguments_string.strip():
            rule_arguments = [thing.strip()
                              for thing in rule_arguments_string.split(',')]
        if rule_name not in potential_rules:
            raise StylistException(f"Unrecognised rule: {rule_name}")
        if rule_arguments:
            processed_args: List[str] = []
            processed_kwargs: Dict[str, str] = {}
            for arg in rule_arguments:
                match = _ARGUMENT_PATTERN.match(arg)
                if match is None:
                    message = "Failed to comprehend rule argument list"
                    raise StylistException(message)
                if match.group(1) is not None:
                    processed_kwargs[match.group(1)] = eval(match.group(2))
                else:
                    processed_args.append(eval(match.group(2)))
            # TODO: Currently the use of *args and **kwargs here confuses mypy.
            #
            new_rule = potential_rules[rule_name](  # type: ignore
                *processed_args, **processed_kwargs)
            rules.append(new_rule)
        else:
            rules.append(potential_rules[rule_name]())
    return Style(rules)
Example #2
0
 def test_configuration(self, style_file) -> None:
     test_unit = Configuration(style_file)
     expected = [key[6:] for key in style_file.keys()
                 if key.startswith('style.')]
     assert test_unit.available_styles() == expected
     for key in style_file.keys():
         if key.startswith('style.'):
             expected = _RULE_PATTERN.findall(style_file[key]['rules'])
             expected = [item.strip() for item in expected]
             assert test_unit.get_style(key[6:]) == expected
Example #3
0
 def test_style_with_empty_rules(self) -> None:
     test_unit = Configuration({'style.empty-rules': {'rules': ''}})
     assert test_unit.available_styles() == ['empty-rules']
     with raises(StylistException):
         _ = test_unit.get_style('empty-rules')
Example #4
0
 def test_style_without_rules(self) -> None:
     test_unit = Configuration({'style.no-rules': {'only': 'thing'}})
     assert test_unit.available_styles() == ['no-rules']
     with raises(KeyError):
         _ = test_unit.get_style('no-rules')
Example #5
0
 def test_empty_style(self) -> None:
     test_unit = Configuration({'style.empty': {}})
     assert test_unit.available_styles() == ['empty']
     with raises(KeyError):
         _ = test_unit.get_style('empty')
Example #6
0
 def test_no_styles(self) -> None:
     test_unit = Configuration({'no-style': {}})
     assert test_unit.available_styles() == []
Example #7
0
 def test_empty_file(self) -> None:
     test_unit = Configuration({})
     assert test_unit.available_styles() == []
Example #8
0
 def test_raw_rule_arguments(self) -> None:
     initialiser = {'style.raw-args': {'rules': 'rule(r\'.*\')'}}
     test_unit = Configuration(initialiser)
     assert test_unit.available_styles() == ['raw-args']
     assert test_unit.get_style('raw-args') == ['rule(r\'.*\')']