How to get information from PyYAML exception?

I want to gracefully notify the user where their corrupted YAML file is corrupted. Line 288 python-3.4.1/lib/python-3.4/yaml/scanner.pyis where it reports a common parsing error and processes it, throwing an exception:

raise ScannerError("while scanning a simple key", key.mark,
                   "could not found expected ':'", self.get_mark())

I am struggling to report this.

try:
    parsed_yaml = yaml.safe_load(txt)

except yaml.YAMLError as exc:
    print ("scanner error 1")
    if hasattr(exc, 'problem_mark'):
        mark = exc.problem_mark
        print("Error parsing Yaml file at line %s, column %s." %
                                            (mark.line, mark.column+1))
    else:
        print ("Something went wrong while parsing yaml file")
    return

This gives

$ yaml_parse.py
scanner error 1
Error parsing Yaml file line 1508, column 9.

But how do I get the error text and everything that is in key.mark, and the other sign?

More useful, how can I study the source of PyYaml to figure this out? The ScannerError class seems to ignore the parameters (from scanner.pyline 32):

class ScannerError(MarkedYAMLError):
     pass
+4
source share
2 answers

ScannerError ( pass no-op. , MarkedYAMLError, , . error.py:

class MarkedYAMLError(YAMLError):
    def __init__(self, context=None, context_mark=None,
                 problem=None, problem_mark=None, note=None):
        self.context = context
        self.context_mark = context_mark
        self.problem = problem
        self.problem_mark = problem_mark
        self.note = note

    def __str__(self):
        lines = []
        if self.context is not None:
            lines.append(self.context)
        if self.context_mark is not None  \
           and (self.problem is None or self.problem_mark is None
                or self.context_mark.name != self.problem_mark.name
                or self.context_mark.line != self.problem_mark.line
                or self.context_mark.column != self.problem_mark.column):
            lines.append(str(self.context_mark))
        if self.problem is not None:
            lines.append(self.problem)
        if self.problem_mark is not None:
            lines.append(str(self.problem_mark))
        if self.note is not None:
            lines.append(self.note)
        return '\n'.join(lines)

txt.yaml:

hallo: 1
bye

a test.py:

import ruamel.yaml as yaml
txt = open('txt.yaml')
data = yaml.load(txt, yaml.SafeLoader)

:

...
ruamel.yaml.scanner.ScannerError: while scanning a simple key
  in "txt.yaml", line 2, column 1
could not find expected ':'
  in "txt.yaml", line 3, column 1

, test.py:

import ruamel.yaml as yaml
txt = open('txt.yaml').read()
data = yaml.load(txt, yaml.SafeLoader)

:

...
ruamel.yaml.scanner.ScannerError: while scanning a simple key
  in "<byte string>", line 2, column 1:
    bye
    ^
could not find expected ':'
  in "<byte string>", line 3, column 1:

    ^

, get_mark() (in reader.py) , , :

def get_mark(self):
    if self.stream is None:
        return Mark(self.name, self.index, self.line, self.column,
                    self.buffer, self.pointer)
    else:
        return Mark(self.name, self.index, self.line, self.column,
                    None, None)

context_mark. , . , , YAML , .

YAML - , , , . grep def method_name(, ( ).


PyYAML ruamel.yaml, . >

+2

@Anthon :

try:
    import yaml
except:
    print ('Fatal error:  Yaml library not available')
    quit()

f = open ('y.yml')
txt = f.read()

try:
    yml = yaml.load(txt, yaml.SafeLoader)

except yaml.YAMLError as exc:
    print ("Error while parsing YAML file:")
    if hasattr(exc, 'problem_mark'):
        if exc.context != None:
            print ('  parser says\n' + str(exc.problem_mark) + '\n  ' +
                str(exc.problem) + ' ' + str(exc.context) +
                '\nPlease correct data and retry.')
        else:
            print ('  parser says\n' + str(exc.problem_mark) + '\n  ' +
                str(exc.problem) + '\nPlease correct data and retry.')
    else:
        print ("Something went wrong while parsing yaml file")
    return

# make use of `yml`

:

$ yaml_parse.py
Error while parsing YAML file:
  parser says
  in "<unicode string>", line 1525, column 9:
      - name: Curve 1
            ^
  could not found expected ':' while scanning a simple key
Please correct data and retry.

$ yaml_parse.py
Error while parsing YAML file:
  parser says
  in "<unicode string>", line 1526, column 10:
        curve: title 1
             ^
  mapping values are not allowed here
Please correct data and retry.
+3

All Articles