Welcome, guest | Sign In | My Account | Store | Cart
#!/usr/bin/env python3
# coding: utf-8

from abc import abstractmethod, ABCMeta
from argparse import Action, ArgumentParser

from yaml import load

class SetDefaultFromFile(Action, metaclass=ABCMeta):
    Populates arguments with file contents.

    This abstract class is to be inherited per type of file read.

    def __call__(self, parser, namespace, values, option_string=None):
        config = self._get_config_from_file(values)
        for key, value in config.items():
            setattr(namespace, key, value)

    def _get_config_from_file(self, filename):
        raise NotImplementedError

class SetDefaultFromYAMLFile(SetDefaultFromFile):
    Populates arguments with a YAML file contents.

    def _get_config_from_file(self, filename):
        with open(filename) as f:
            config = load(f)
        return config

_TEST_FILE = 'test.yaml'
_NAME = 'spam'
_FILE_VALUE = 'eggs'
with open(_TEST_FILE, mode='w') as f:
    f.write('{}: {}'.format(_NAME, _FILE_VALUE))
_PARSER = ArgumentParser()
_PARSER.add_argument('--config', action=SetDefaultFromYAMLFile)

def test_file_content_populates_args():
    args = _PARSER.parse_args('--config {}'.format(_TEST_FILE).split())
    assert getattr(args, _NAME) == _FILE_VALUE

def test_file_content_is_erased_if_arg_given_after():
    expected = '42'
    args = _PARSER.parse_args('--config {} --spam {}'.format(_TEST_FILE,
    assert getattr(args, _NAME) == expected

def test_arg_is_erases_if_file_is_given_after():
    value = 12
    args = _PARSER.parse_args('--spam {} --config {}'.format(value,
    assert getattr(args, _NAME) == _FILE_VALUE