majkrzak
majkrzak

Reputation: 1547

Load mapping with complex keys

pyyaml fails to load the mappings with complex keys like bellow, because dict is not hashable.

foo:
- {bar: test}: 123

Is it possible to force pyyaml to load mappings with complex keys?

Upvotes: 0

Views: 134

Answers (2)

majkrzak
majkrzak

Reputation: 1547

I've "solved" this with following polyfill:

from collections.abc import Hashable

from yaml import MappingNode
from yaml.constructor import BaseConstructor


def construct_mapping(self: BaseConstructor, node: MappingNode, deep=True):
    mapping = {}
    for key_node, value_node in node.value:
        key = self.construct_object(key_node, True)
        if not isinstance(key, Hashable):
            key = type('hashable', (key.__class__,), {'__hash__': lambda _: 1})(key)
        value = self.construct_object(value_node, True)
        mapping[key] = value
    return mapping


BaseConstructor.construct_mapping = construct_mapping

Upvotes: 0

ubaumann
ubaumann

Reputation: 200

In Python, dictionary keys must be unique and hashable. A default dictionary is not hashable.

You need to create a custom hashable dictionary class. You can get inspiration from the answers here. Python hashable dicts

After that, you need to tell pyyaml to use the custom dictionary. Maybe this question will lead you in the right direction. How to use custom dictionary class while loading yaml?

Upvotes: 1

Related Questions