Skip to content

Commit

Permalink
yaml config supportedĀ šŸ¤”
Browse files Browse the repository at this point in the history
  • Loading branch information
Microndgt committed Apr 9, 2018
1 parent 6ac0863 commit 2f43280
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 6 deletions.
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# pyconf

Configuration for Humans
Configuration for Humans in ***Python3***.

**pyconf** is an INI/py/yml configuration parsing package, written for humans.

Expand Down Expand Up @@ -36,6 +36,16 @@ print(c['path'])
# some_path
```

yaml config file
---

```python
import pyconf
c = pyconf.load('tests/sample.yml', config_class=pyconf.YamlConfig)
print(c['path'])
# some_path
```

Tests
=====

Expand All @@ -44,11 +54,17 @@ Run the tests with
```bash
python -m tests.test_ini_configs
python -m tests.test_py_configs
python -m tests.test_yaml_configs
```

History
===

0.1.1
---

1. support the yaml config file

0.1.0
---

Expand Down
3 changes: 2 additions & 1 deletion pyconf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@
"""

__title__ = 'pyconf'
__version__ = '0.1.0'
__version__ = '0.1.1'
__author__ = 'Kevin Du'
__license__ = 'MIT'

from .ini_config import IniConfig
from .py_config import PyConfig
from .yml_config import YamlConfig
from .base_config import BaseConfig, Section
from .api import load
5 changes: 3 additions & 2 deletions pyconf/api.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
from .ini_config import IniConfig
from .py_config import PyConfig
from .yml_config import YamlConfig


support_configs = (IniConfig, PyConfig)
support_configs = (IniConfig, PyConfig, YamlConfig)


def load(config_file, config_class=IniConfig):
"""Constructs and returns a :class:`Config <Config>` instance.
:param config_file: configuration file to be parsed
:param ext: configuration extension
:param config_class: configuration extension
Usage::
Expand Down
1 change: 0 additions & 1 deletion pyconf/ini_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ def load(self, config_file):
"""Parse an INI configuration file.
:param config_file: configuration file to be loaded.
:param silent: set to ``True`` if you want silent failure for missing files.
"""

current_section = None
Expand Down
10 changes: 10 additions & 0 deletions pyconf/yml_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import yaml
from .py_config import PyConfig


class YamlConfig(PyConfig):

def load(self, config_file):
with open(config_file) as config:
config_obj = yaml.load(config)
self._add_section_recursive(config_obj, self.sections['root'])
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
certifi==2018.1.18
PyYAML==3.12
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
try:
readme = open('README.md').read()
except:
readme = 'pyconf: Configuration for Humans. Support ini config file, python config file'
readme = 'pyconf: Configuration for Humans. Support ini config file, python config file, yaml config file'

setup(
name=pyconf.__title__,
Expand Down
20 changes: 20 additions & 0 deletions tests/sample.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
path: some_path
hosts: ["example.com", "http://bing.com", "ssh.com:23", "www.qwe.asd"]

section: {
"attr1": 7.1,
"attr2": 42,
"foo": 123
}

section2: {
"inner_section": {
"test_section": {
1: 2
},
"two": 2,
},
"attr1": 7.1,
"attr2": 42,
"foo": 123
}
47 changes: 47 additions & 0 deletions tests/test_yaml_configs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import unittest

from pyconf import api, YamlConfig, Section
from typing import Sequence


class TestPyConfig(unittest.TestCase):

def setUp(self):
self.sample_config_filename = 'tests/sample.yml'
self.missing_config_filename = 'missing.yml'

def test_load_general(self):
"""Check if a valid config file is parsed correctly"""

self.assertIsInstance(api.load(self.sample_config_filename, config_class=YamlConfig), YamlConfig)

def test_load_missing_file(self):
"""Check if the correct exception in raised when a missing config file is attempted to parse"""

with self.assertRaises(FileNotFoundError):
api.load(self.missing_config_filename)

def test_load_check_types(self):
"""Check automatic float, integer, and boolean value conversion"""
config_data = api.load(self.sample_config_filename, config_class=YamlConfig)
self.assertIsInstance(config_data['path'], str)
self.assertIsInstance(config_data['hosts'], Sequence)
self.assertIsInstance(config_data['hosts'][0], str)

self.assertIsInstance(config_data['section'], Section)
self.assertIsInstance(config_data['section']['attr1'], float)
self.assertIsInstance(config_data['section']['attr2'], int)
self.assertIsInstance(config_data['section']['foo'], int)

self.assertIsInstance(config_data['section2'], Section)
self.assertIsInstance(config_data['section2']['attr1'], float)
self.assertIsInstance(config_data['section2']['attr2'], int)
self.assertIsInstance(config_data['section2']['foo'], int)
self.assertIsInstance(config_data['section2']['inner_section'], Section)
self.assertIsInstance(config_data['section2']['inner_section']['two'], int)
self.assertIsInstance(config_data['section2']['inner_section']['test_section'], Section)
self.assertIsInstance(config_data['section2']['inner_section']['test_section'][1], int)


if __name__ == '__main__':
unittest.main()

0 comments on commit 2f43280

Please sign in to comment.