Mercurial > hgrepos > Python > libs > ConfigMix
view configmix/yaml.py @ 284:4aaf74858d07
Some links to AWS docu into the aws moduleSome links to AWS docu into the aws moduleSome links to AWS docu into the aws moduleSome links to AWS docu into the aws moduleSome links to AWS docu into the aws moduleSome links to AWS docu into the aws moduleSome links to AWS docu into the aws moduleSome links to AWS docu into the aws module
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 07 Dec 2020 01:59:11 +0100 |
| parents | ff964825a75a |
| children | edf5cc1ffd26 |
line wrap: on
line source
# -*- coding: utf-8 -*- # :- # :Copyright: (c) 2015-2020, Franz Glasner. All rights reserved. # :License: 3-clause BSD. See LICENSE.txt for details. # :- """Simple wrapper for :mod:`yaml` to support all-unicode strings when loading configuration files. """ from __future__ import division, print_function, absolute_import __all__ = ["safe_load", "safe_load_all", "load", "load_all"] try: from collections import OrderedDict except ImportError: try: from ordereddict import OrderedDict except ImportError: OrderedDict = None import yaml import yaml.constructor from .compat import u DictImpl = OrderedDict or dict class ConfigLoader(yaml.Loader): """A YAML loader, which makes all ``!!str`` strings to Unicode. Standard PyYAML does this only in the non-ASCII case. If an `OrderedDict` implementation is available then all "map" and "omap" nodes are constructed as `OrderedDict`. This is against YAML specs but within configuration files it seems more natural. """ def construct_yaml_str(self, node): return self.construct_scalar(node) if OrderedDict: # # From https://pypi.python.org/pypi/yamlordereddictloader/0.1.1 # (MIT License) # def construct_yaml_map(self, node): data = OrderedDict() yield data value = self.construct_mapping(node) data.update(value) def construct_mapping(self, node, deep=False): if isinstance(node, yaml.MappingNode): self.flatten_mapping(node) else: raise yaml.constructor.ConstructorError( None, None, 'expected a mapping node, but found %s' % node.id, node.start_mark) mapping = OrderedDict() for key_node, value_node in node.value: key = self.construct_object(key_node, deep=deep) try: hash(key) except TypeError as err: raise yaml.constructor.ConstructorError( 'while constructing a mapping', node.start_mark, 'found unacceptable key (%s)' % (err, key_node.start_mark) ) value = self.construct_object(value_node, deep=deep) mapping[key] = value return mapping ConfigLoader.add_constructor( u("tag:yaml.org,2002:str"), ConfigLoader.construct_yaml_str) if OrderedDict: ConfigLoader.add_constructor( u("tag:yaml.org,2002:map"), ConfigLoader.construct_yaml_map) ConfigLoader.add_constructor( u("tag:yaml.org,2002:omap"), ConfigLoader.construct_yaml_map) class ConfigSafeLoader(yaml.SafeLoader): """A safe YAML loader, which makes all ``!!str`` strings to Unicode. Standard PyYAML does this only in the non-ASCII case. If an `OrderedDict` implementation is available then all "map" and "omap" nodes are constructed as `OrderedDict`. This is against YAML specs but within configuration files it seems more natural. """ def construct_yaml_str(self, node): return self.construct_scalar(node) if OrderedDict: # # From https://pypi.python.org/pypi/yamlordereddictloader/0.1.1 # (MIT License) # def construct_yaml_map(self, node): data = OrderedDict() yield data value = self.construct_mapping(node) data.update(value) def construct_mapping(self, node, deep=False): if isinstance(node, yaml.MappingNode): self.flatten_mapping(node) else: raise yaml.constructor.ConstructorError( None, None, 'expected a mapping node, but found %s' % node.id, node.start_mark) mapping = OrderedDict() for key_node, value_node in node.value: key = self.construct_object(key_node, deep=deep) try: hash(key) except TypeError as err: raise yaml.constructor.ConstructorError( 'while constructing a mapping', node.start_mark, 'found unacceptable key (%s)' % (err, key_node.start_mark) ) value = self.construct_object(value_node, deep=deep) mapping[key] = value return mapping ConfigSafeLoader.add_constructor( u("tag:yaml.org,2002:str"), ConfigSafeLoader.construct_yaml_str) if OrderedDict: ConfigSafeLoader.add_constructor( u("tag:yaml.org,2002:map"), ConfigSafeLoader.construct_yaml_map) ConfigSafeLoader.add_constructor( u("tag:yaml.org,2002:omap"), ConfigSafeLoader.construct_yaml_map) def load(stream, Loader=ConfigLoader): """Parse the given `stream` and return a Python object constructed from for the first document in the stream. """ data = yaml.load(stream, Loader) # Map an empty document to an empty dict if data is None: return DictImpl() if not isinstance(data, DictImpl): raise TypeError("YAML root object must be a mapping") return data def load_all(stream, Loader=ConfigLoader): """Parse the given `stream` and return a sequence of Python objects corresponding to the documents in the `stream`. """ data_all = yaml.load_all(stream, Loader) rdata = [] for data in data_all: if data is None: rdata.append(DictImpl()) else: if not isinstance(data, DictImpl): raise TypeError("YAML root object must be a mapping") rdata.append(data) return rdata def safe_load(stream): """Parse the given `stream` and return a Python object constructed from for the first document in the stream. Recognizes only standard YAML tags and cannot construct an arbitrary Python object. """ data = yaml.load(stream, Loader=ConfigSafeLoader) # Map an empty document to an empty dict if data is None: return DictImpl() if not isinstance(data, DictImpl): raise TypeError("YAML root object must be a mapping") return data def safe_load_all(stream): """Return the list of all decoded YAML documents in the file `stream`. Recognizes only standard YAML tags and cannot construct an arbitrary Python object. """ data_all = yaml.load_all(stream, Loader=ConfigSafeLoader) rdata = [] for data in data_all: if data is None: rdata.append(DictImpl()) else: if not isinstance(data, DictImpl): raise TypeError("YAML root object must be a mapping") rdata.append(data) return data_all
