pyyaml icon indicating copy to clipboard operation
pyyaml copied to clipboard

pyyaml failed to load python objects with full loader

Open HappyRay opened this issue 3 years ago • 2 comments

With python 3.8, pyyaml 5.4.1, the simple example used in the official pyyaml documentation for loading a python object https://pyyaml.docsforge.com/master/documentation/#loading-yaml failed to work.

The same example works with pyyaml 5.3.1, 5.3, 5.1.

yaml.load(s, Loader=yaml.UnsafeLoader) works with pyyaml 5.4.1

Here is the complete code adopted from the example above.

class Hero:
    def __init__(self, name, hp, sp):
        self.name = name
        self.hp = hp
        self.sp = sp

    def __repr__(self):
        return "%s(name=%r, hp=%r, sp=%r)" % (
            self.__class__.__name__, self.name, self.hp, self.sp)


def load_class():
    s = """
!!python/object:__main__.Hero
name: Welthyr Syxgon
hp: 1200
sp: 0
"""
    r = yaml.full_load(s)
    print(r)

load_class()

I got an error:

    raise ConstructorError(None, None, yaml.constructor.ConstructorError: could not determine a constructor for the tag 'tag:yaml.org,2002:python/object:__main__.Hero'   in "<unicode string>", line 2, column 1:
    !!python/object:__main__.Hero
    ^

HappyRay avatar Aug 12 '21 17:08 HappyRay

The linked docs are not the official documentation. It can be found here: https://pyyaml.org/wiki/PyYAMLDocumentation

You are supposed to use UnsafeLoader because loading python/object:... is considered unsafe.

perlpunk avatar Aug 27 '21 23:08 perlpunk

Thanks. UnsafeLoader worked for me.

I saw the same example in the official documentation at https://pyyaml.org/wiki/PyYAMLDocumentation though. Maybe the example needs to be updated?

" Even instances of Python classes can be constructed using the !!python/object tag.

class Hero: ... def init(self, name, hp, sp): ... self.name = name ... self.hp = hp ... self.sp = sp ... def repr(self): ... return "%s(name=%r, hp=%r, sp=%r)" % ( ... self.class.name, self.name, self.hp, self.sp)

yaml.load(""" ... !!python/object:main.Hero ... name: Welthyr Syxgon ... hp: 1200 ... sp: 0 ... """)

Hero(name='Welthyr Syxgon', hp=1200, sp=0) "

HappyRay avatar Aug 28 '21 00:08 HappyRay