strictyaml icon indicating copy to clipboard operation
strictyaml copied to clipboard

[Bug] Wrong line number on YAMLValidationError output

Open jrom99 opened this issue 2 years ago • 0 comments

Okay, I found a pretty weird case where YAMLValidationError output shows the wrong line numbers.

I don't know why, but the combination of Slug, values with brackets and missing keys change the behaviour of line counter.

I couldn't reliably test it to discover what actually caused it, sorry.

Each line with brackets adds one to the line counter, but only in certain conditions (replacing "nós descobrimos" with "aaaaa" corrects this, as does changing what is inside some brackets). The number is correct if I don't use Slug as a key validator.

Edit: It seems to be due to long lines, actually.

image

Example yaml file that causes this.

# pode ser o nome de um arquivo em resources/saude ou o texto diretamente
Titulo: Sample text {key1} {key2} foi aaaaa para {underline_} lot{s} value{s} nós descobrimos
Resumo: Sample text {key1} {key2} foi aaaaa para {underline_} lot{s} value{s} nós descobrimos

Formatação:
   Resumo:
      MargemTopo: 24mm
      Alinhamento Horizontal Numeros: desenho

Minimum example I could create that causes this behaviour

import re
import unicodedata

from strictyaml import (EmptyDict, EmptyNone, Enum, FixedSeq, Int, Map,
                        Optional, Regex, ScalarValidator, Str,
                        YAMLValidationError, load)
from strictyaml.yamllocation import YAMLChunk


class Slug(ScalarValidator):
    def __init__(self, is_uppercase: bool = False, space_char: str = "-") -> None:
        super().__init__()
        self.is_uppercase = is_uppercase
        self.space_char = space_char

    def slugify(self, string: str):
        """
        Slugify a unicode string.

        Example:
            >>> slugify(u"Héllø Wörld")
            u"hello-world"
        """
        simplified = re.sub(
            r'[^\w\s-]',
            '',
            unicodedata.normalize('NFKD', string).encode('ascii', 'ignore').decode('ascii')).strip()
        no_spaces = re.sub(r'[-\s]+', self.space_char, simplified)
        return no_spaces.upper() if self.is_uppercase else no_spaces.lower()

    def validate_scalar(self, chunk: YAMLChunk):
        return self.slugify(chunk.contents)


file_schema = Map({
    "titulo": Str(),
    "resumo": Str(),
    "detalhe": Str()
}, Slug())


with open("test.yaml") as handle:
    file_data = handle.read()

load(file_data, file_schema)

jrom99 avatar Apr 13 '22 14:04 jrom99