def test_token_or_comment_or_line_generator(self): e = list(token_or_comment_or_line_generator('---\n' 'k: v # k=v\n')) self.assertEqual(len(e), 13) self.assertIsInstance(e[0], Token) self.assertIsInstance(e[0].curr, yaml.StreamStartToken) self.assertIsInstance(e[1], Token) self.assertIsInstance(e[1].curr, yaml.DocumentStartToken) self.assertIsInstance(e[2], Line) self.assertIsInstance(e[3].curr, yaml.BlockMappingStartToken) self.assertIsInstance(e[4].curr, yaml.KeyToken) self.assertIsInstance(e[6].curr, yaml.ValueToken) self.assertIsInstance(e[8], Comment) self.assertIsInstance(e[9], Line) self.assertIsInstance(e[12], Line)
def test_token_or_comment_or_line_generator(self): e = list(token_or_comment_or_line_generator('---\n' 'k: v # k=v\n')) self.assertEqual(len(e), 13) self.assertIsInstance(e[0], Token) self.assertIsInstance(e[0].curr, yaml.StreamStartToken) self.assertIsInstance(e[1], Token) self.assertIsInstance(e[1].curr, yaml.DocumentStartToken) self.assertIsInstance(e[2], Line) self.assertIsInstance(e[3].curr, yaml.BlockMappingStartToken) self.assertIsInstance(e[4].curr, yaml.KeyToken) self.assertIsInstance(e[6].curr, yaml.ValueToken) self.assertIsInstance(e[8], Comment) self.assertIsInstance(e[9], Line) self.assertIsInstance(e[12], Line)
def get_costemic_problems(buffer, conf): rules = conf.enabled_rules() # Split token rules from line rules token_rules = [r for r in rules if r.TYPE == 'token'] comment_rules = [r for r in rules if r.TYPE == 'comment'] line_rules = [r for r in rules if r.TYPE == 'line'] context = {} for rule in token_rules: context[rule.ID] = {} class DisableDirective(): def __init__(self): self.rules = set() self.all_rules = set([r.ID for r in rules]) def process_comment(self, comment): try: comment = str(comment) except UnicodeError: return # this certainly wasn't a yamllint directive comment if re.match(r'^# yamllint disable( rule:\S+)*\s*$', comment): rules = [item[5:] for item in comment[18:].split(' ')][1:] if len(rules) == 0: self.rules = self.all_rules.copy() else: for id in rules: if id in self.all_rules: self.rules.add(id) elif re.match(r'^# yamllint enable( rule:\S+)*\s*$', comment): rules = [item[5:] for item in comment[17:].split(' ')][1:] if len(rules) == 0: self.rules.clear() else: for id in rules: self.rules.discard(id) def is_disabled_by_directive(self, problem): return problem.rule in self.rules class DisableLineDirective(DisableDirective): def process_comment(self, comment): try: comment = str(comment) except UnicodeError: return # this certainly wasn't a yamllint directive comment if re.match(r'^# yamllint disable-line( rule:\S+)*\s*$', comment): rules = [item[5:] for item in comment[23:].split(' ')][1:] if len(rules) == 0: self.rules = self.all_rules.copy() else: for id in rules: if id in self.all_rules: self.rules.add(id) # Use a cache to store problems and flush it only when a end of line is # found. This allows the use of yamllint directive to disable some rules on # some lines. cache = [] disabled = DisableDirective() disabled_for_line = DisableLineDirective() disabled_for_next_line = DisableLineDirective() for elem in parser.token_or_comment_or_line_generator(buffer): if isinstance(elem, parser.Token): for rule in token_rules: rule_conf = conf.rules[rule.ID] for problem in rule.check(rule_conf, elem.curr, elem.prev, elem.next, elem.nextnext, context[rule.ID]): problem.rule = rule.ID problem.level = rule_conf['level'] cache.append(problem) elif isinstance(elem, parser.Comment): for rule in comment_rules: rule_conf = conf.rules[rule.ID] for problem in rule.check(rule_conf, elem): problem.rule = rule.ID problem.level = rule_conf['level'] cache.append(problem) disabled.process_comment(elem) if elem.is_inline(): disabled_for_line.process_comment(elem) else: disabled_for_next_line.process_comment(elem) elif isinstance(elem, parser.Line): for rule in line_rules: rule_conf = conf.rules[rule.ID] for problem in rule.check(rule_conf, elem): problem.rule = rule.ID problem.level = rule_conf['level'] cache.append(problem) # This is the last token/comment/line of this line, let's flush the # problems found (but filter them according to the directives) for problem in cache: if not (disabled_for_line.is_disabled_by_directive(problem) or disabled.is_disabled_by_directive(problem)): yield problem disabled_for_line = disabled_for_next_line disabled_for_next_line = DisableLineDirective() cache = []
def get_costemic_problems(buffer, conf): rules = conf.enabled_rules() # Split token rules from line rules token_rules = [r for r in rules if r.TYPE == 'token'] comment_rules = [r for r in rules if r.TYPE == 'comment'] line_rules = [r for r in rules if r.TYPE == 'line'] context = {} for rule in token_rules: context[rule.ID] = {} class DisableDirective(): def __init__(self): self.rules = set() self.all_rules = set([r.ID for r in rules]) def process_comment(self, comment): try: comment = str(comment) except UnicodeError: return # this certainly wasn't a yamllint directive comment if re.match(r'^# yamllint disable( rule:\S+)*\s*$', comment): rules = [item[5:] for item in comment[18:].split(' ')][1:] if len(rules) == 0: self.rules = self.all_rules.copy() else: for id in rules: if id in self.all_rules: self.rules.add(id) elif re.match(r'^# yamllint enable( rule:\S+)*\s*$', comment): rules = [item[5:] for item in comment[17:].split(' ')][1:] if len(rules) == 0: self.rules.clear() else: for id in rules: self.rules.discard(id) def is_disabled_by_directive(self, problem): return problem.rule in self.rules class DisableLineDirective(DisableDirective): def process_comment(self, comment): try: comment = str(comment) except UnicodeError: return # this certainly wasn't a yamllint directive comment if re.match(r'^# yamllint disable-line( rule:\S+)*\s*$', comment): rules = [item[5:] for item in comment[23:].split(' ')][1:] if len(rules) == 0: self.rules = self.all_rules.copy() else: for id in rules: if id in self.all_rules: self.rules.add(id) # Use a cache to store problems and flush it only when a end of line is # found. This allows the use of yamllint directive to disable some rules on # some lines. cache = [] disabled = DisableDirective() disabled_for_line = DisableLineDirective() disabled_for_next_line = DisableLineDirective() for elem in parser.token_or_comment_or_line_generator(buffer): if isinstance(elem, parser.Token): for rule in token_rules: rule_conf = conf.rules[rule.ID] for problem in rule.check(rule_conf, elem.curr, elem.prev, elem.next, elem.nextnext, context[rule.ID]): problem.rule = rule.ID problem.level = rule_conf['level'] cache.append(problem) elif isinstance(elem, parser.Comment): for rule in comment_rules: rule_conf = conf.rules[rule.ID] for problem in rule.check(rule_conf, elem): problem.rule = rule.ID problem.level = rule_conf['level'] cache.append(problem) disabled.process_comment(elem) if elem.is_inline(): disabled_for_line.process_comment(elem) else: disabled_for_next_line.process_comment(elem) elif isinstance(elem, parser.Line): for rule in line_rules: rule_conf = conf.rules[rule.ID] for problem in rule.check(rule_conf, elem): problem.rule = rule.ID problem.level = rule_conf['level'] cache.append(problem) # This is the last token/comment/line of this line, let's flush the # problems found (but filter them according to the directives) for problem in cache: if not (disabled_for_line.is_disabled_by_directive(problem) or disabled.is_disabled_by_directive(problem)): yield problem disabled_for_line = disabled_for_next_line disabled_for_next_line = DisableLineDirective() cache = []