yaml.safe_load returns string instead of object

Viewed 2129

I have this piece of code:

    config_object = yaml.safe_load(config_string)
    print("passed config: {}".format(config_object)) 
    ^^ prints expected yaml structure

    print("deserialized config object type: {}".format(type(config_object)))
    ^^ prints deserialized config object type: <class 'str'>

    value = config_object["field1"]["field2"]["field3"]
    ^^  Error: string indices must be integers

My yaml config:

   ---
   field1:
     field2:
       field3: value
     field4: value
   ...

I do not understand why string is returned. And I do not see any string return type here: https://pyyaml.org/wiki/PyYAMLDocumentation

3 Answers

The trick is to wrap your function argument with open() as follows:

config_object = yaml.safe_load(open(config_string))

I had the same problem with different data:

train:images/train

I solved the issue by adding a space after the colon:

train: images/train

Turns out, that trying to load ... most any invalid YAML data, returns a str (with both yaml.load and yaml.safe_load). I would say, that is very bad, but... that's how it is. I accidentally tried to load TOML files with yaml.load, and it also just returns the TOML file content as a string, without any error.

General Solution

Parse your YAML data with something else, be it an other YAML library (possibly in an other language then Python) or in an IDE with YAML parsing support, figure out the problem, fix it, and then go back to using yaml.load with the now valid YAML data.

Related