Source code for objconfig.reader.yaml

r"""
This is a port of zend-config to Python

NOTE: This file requires PyYaml, which is recorded in the setup.py

Some idioms of PHP are still employed, but where possible I have Pythonized it

IGNORE:
    Author: Asher Wolfstein Copyright 2017
    Blog: http://wunk.me/
    E-Mail: asherwunk@gmail.com
    Twitter: https://twitter.com/asherwolfstein Send Me Some Love!
    Package Homepage: http://wunk.me/programming-projects/objconfig-python/
    GitHub: http://github.com/asherwunk/objconfig for the source repository
    DevPost: https://devpost.com/software/objconfig
    Buy Me A Coffee: https://ko-fi.com/A18224XC
    Support Me On Patreon: https://www.patreon.com/asherwolfstein
IGNORE

Following is the header as given in zend-config::

    /**
     * Zend Framework (http://framework.zend.com/)
     *
     * @link      http://github.com/zendframework/zf2 for the
     *            canonical source repository
     * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc.
     *            (http://www.zend.com)
     * @license   http://framework.zend.com/license/new-bsd New BSD License
     */
"""

from objconfig.reader import ReaderInterface
from objconfig.exception import RuntimeException
from objconfig.util import array_merge_recursive
import yaml
import os


[docs]class Yaml(ReaderInterface): r""" Following is the class documentation as given in zend-config:: /** * YAML config reader. */ """ def __init__(self): """Initialize safe and directory members.""" r""" Utilize load_safe method? """ self.safe = True r""" Following is the header as given in zend-config:: /** * Directory of the JSON file * * @var string */ """ self.directory = ''
[docs] def fromFile(self, filename): r""" Following is the header as given in zend-config:: /** * fromFile(): defined by Reader interface. * * @see ReaderInterface::fromFile() * @param string $filename * @return array * @throws Exception\RuntimeException */ """ if not os.path.isfile(filename) and not os.access(filename, os.R_OK): raise RuntimeException("Yaml: File %s Doesn't Exist or Not Readable" % filename) self.directory = os.path.dirname(filename.rstrip(os.sep)) or '.' conf = {} try: with open(filename, "r") as file: yamlcontent = file.read() if self.safe: conf = yaml.safe_load(yamlcontent) else: conf = yaml.load(yamlcontent) except yaml.YAMLError as e: raise RuntimeException("Yaml: Error Reading YAML file \"%s\": %s" % (filename, e)) return self.process(conf)
[docs] def fromString(self, string): r""" Following is the header as given in zend-config:: /** * fromString(): defined by Reader interface. * * @param string $string * @return array|bool * @throws Exception\RuntimeException */ """ if not string: return {} self.directory = None conf = {} try: if self.safe: conf = yaml.safe_load(string) else: conf = yaml.load(string) except yaml.YAMLError as e: raise RuntimeException("Yaml: Error Reading YAML string: %s" % e) return self.process(conf)
[docs] def process(self, array): r""" Following is the header as given in zend-config:: /** * Process the array for @include * * @param array $data * @return array * @throws Exception\RuntimeException */ """ for key, value in (array.items() if 'items' in dir(array) else array): if isinstance(value, (tuple, list, dict)): array[key] = self.process(value) elif "_@include" in key: if not self.directory: raise RuntimeException("Yaml: Cannot Process @include When Reading From String") if (not os.path.isfile(os.path.join(self.directory, value)) and not os.access(os.path.join(self.directory, value), os.R_OK)): raise RuntimeException("Yaml: File %s Doesn't Exist or Not Readable (@include)" % value) conf = {} with open(os.path.join(self.directory, value), "r") as file: yamlcontent = file.read() if self.safe: conf = yaml.safe_load(yamlcontent) else: conf = yaml.load(yamlcontent) del array[key] array = array_merge_recursive(array, self.process(conf)) return array