Mercurial > hgrepos > Python > libs > ConfigMix
view configmix/yaml.py @ 207:b3b5ed34d180
Handle most flake8 errors and warnings.
NOTE: E265 "block comment should start with '# ' ist not yet handled.
We would need to adjust our Python style.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Sun, 05 May 2019 18:29:47 +0200 |
| parents | e2e8d21b4122 |
| children | bbe8513ea649 |
line wrap: on
line source
# -*- coding: utf-8 -*- #- # :Copyright: (c) 2015-2019, 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 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 __all__ = ["safe_load", "safe_load_all", "load", "load_all"] 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
