crdoconnor / strictyaml

Type-safe YAML parser and validator.
https://hitchdev.com/strictyaml/
MIT License
1.46k stars 60 forks source link

[Bug] Wrong line number on YAMLValidationError output #180

Open jrom99 opened 2 years ago

jrom99 commented 2 years ago

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)
perseoGI commented 1 month ago

Same error here! I'm receiving a line error greater than lines exist in the file.