Commit 1b83a0e4 authored by Xavier Barbosa's avatar Xavier Barbosa

first commit

parents
### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
# Translations
*.mo
*.pot
# Django stuff:
*.log
# Sphinx documentation
docs/_build/
# PyBuilder
target/
Overdub
=======
Load configurations from multiple yaml files.
from .bases import MutableOverdub, Overdub
__all__ = ['MutableOverdub', 'Overdub']
from collections.abc import Mapping
from copy import deepcopy
def merge_recursively(base, data):
dest = deepcopy(base)
for key, value in data.items():
orig = base.get(key, None)
if isinstance(orig, Mapping) and isinstance(value, Mapping):
value = merge_recursively(orig, value)
dest[key] = value
return dest
class Overdub(Mapping):
"""Access mapping as a layer.
When possible, keys will be accessed as attributes.
For example:
>>> overdub = Overdub({'foo': 1, 'bar': {'baz': 'qux'}})
>>> overdub.foo
1
>>> overdub['foo']
1
"""
def __init__(self, data=None):
self._ = data or {}
def __getitem__(self, key):
try:
value = self._[key]
except KeyError as error:
raise KeyError('Key %r is not defined' % key) from error
if isinstance(value, dict):
value = self.__class__(value)
return value
def __iter__(self):
return iter(self._)
def __len__(self):
return len(self._)
def __getattr__(self, name):
"""
Fallback to current data key if attr is not setted.
"""
try:
return self.__getitem__(name)
except KeyError:
return AttributeError("%r object has no attribute %r" % (
self.__class__.__name__, name
))
class MutableOverdub(Overdub):
"""A Overdub with mutability abilities.
"""
def update(self, data):
"""Update data
Parameters:
data (dict): data to be updated
"""
return self._.update(data)
def merge(self, data):
"""Merge data
Parameters:
data (dict): data to be merged
"""
data = merge_recursively(self._, data)
return self._.update(data)
def rebase(self, data):
"""Rebase data
Parameters:
data (dict): data to be rebase
"""
data = merge_recursively(data, self._)
return self._.update(data)
def frozen(self):
"""froze data
Returns:
Overdub: the frozen data
"""
return Overdub(self._)
import os.path
import yaml
from .bases import MutableOverdub
from collections import OrderedDict
class OverdubLoader(yaml.SafeLoader):
pass
def construct_mapping(loader, node):
loader.flatten_mapping(node)
return OrderedDict(loader.construct_pairs(node))
OverdubLoader.add_constructor('tag:yaml.org,2002:map', construct_mapping)
OverdubLoader.add_constructor('tag:yaml.org,2002:omap', construct_mapping)
class OverdubDumper(yaml.SafeDumper):
pass
def represent_dict(dumper, data):
return dumper.represent_mapping('tag:yaml.org,2002:map', data.items())
OverdubDumper.add_representer(OrderedDict, represent_dict)
def load_from_file(*filenames, Loader=OverdubLoader):
"""Merge from various yaml files to obtain an overdubbed instance.
"""
assert filenames, 'filename required'
overdub = MutableOverdub()
for filename in filenames:
filename = os.path.expanduser(filename)
if os.path.exists(filename):
with open(filename) as file:
data = yaml.load(file, Loader)
overdub.merge(data)
return overdub
pytest
pytest-cover
pytest-flake8
#!/usr/bin/env python
from setuptools import setup, find_packages
setup(
name='overdub',
version='0.1',
packages=find_packages(),
install_requires=[],
extras_require={
'yaml': ['pyyaml']
}
)
import pytest
from overdub import Overdub, MutableOverdub
def test_attrs():
overdub = Overdub({'foo': True, 'bar': {'baz': 'quz'}})
assert overdub['foo'] == True
assert overdub.foo == True
assert overdub['bar']['baz'] == 'quz'
print(overdub.bar)
assert overdub.bar.baz == 'quz'
with pytest.raises(TypeError):
overdub['foo'] = True
def test_update():
a = {'foo': 1, 'bar': {'baz': 2}, 'qux': {'one': 1}}
b = {'foo': 3, 'bar': {'baz': 4}, 'qux': {'two': 2}}
overdub = MutableOverdub(a)
overdub.update(b)
assert overdub.foo == 3
assert overdub.bar.baz == 4
assert overdub.qux == {'two': 2}
def test_merge():
a = {'foo': 1, 'bar': {'baz': 2}, 'qux': {'one': 1}}
b = {'foo': 3, 'bar': {'baz': 4}, 'qux': {'two': 2}}
overdub = MutableOverdub(a)
overdub.merge(b)
assert overdub.foo == 3
assert overdub.bar.baz == 4
assert overdub.qux == {'one': 1, 'two': 2}
def test_rebase():
a = {'foo': 1, 'bar': {'baz': 2}, 'qux': {'one': 1}}
b = {'foo': 3, 'bar': {'baz': 4}, 'qux': {'two': 2}}
overdub = MutableOverdub(a)
overdub.rebase(b)
assert overdub.foo == 1
assert overdub.bar.baz == 2
assert overdub.qux == {'one': 1, 'two': 2}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment