/argsloader

Configuration Parsing and Management Based on ChainLoader

Primary LanguagePythonApache License 2.0Apache-2.0

argsloader

PyPI PyPI - Python Version Loc Comments

Docs Deploy Code Test Badge Creation Package Release codecov

GitHub stars GitHub forks GitHub commit activity GitHub issues GitHub pulls Contributors GitHub license

Configuration Parsing and Management Based on chainloader.

The argsloader library's main goal is to extract and change configuration data before implementing it using its computational mechanism:

  • Reusability of local configuration modules

  • Scalability and composition of configuration components

  • Constructing complicated configuration data validation quickly

Installation

You can simply install it with pip command line from the official PyPI site.

pip install argsloader

For more information about installation, you can refer to Installation.

Quick Start

Painless Try

A simple usage is like above

from argsloader.units import yesno, number, is_type, interval

if __name__ == '__main__':
    yn = yesno()  # yes-no option
    print(yn('yes'))  # True
    print(yn('no'))  # False
    print(yn(True))  # True
    print(yn(False))  # False

    num = number()  # any number
    print(num(1))  # 1
    print(num('1.2'))  # 1.2
    print(num('0x4f'))  # 79

    int_ = number() >> is_type(int)  # any int number
    print(num(1))  # 1
    print(num('0x4f'))  # 79
    print(num(1.2))  # TypeError

    val_ = number() >> interval.LR(0, 10)  # number within [0, 10]
    print(num(1))  # 1
    print(num(1.2))  # 1.2
    print(num(11))  # ValueError

After the unit is built, it can be used to transform and validate the given value.

Full Validation

Sometimes, there may be multiple errors in the given value, but if you directly call corresponding loader (i.e. call the pre-defined __call__ method), only the first error will be raised.

from argsloader.units import is_type, interval

if __name__ == '__main__':
    in_ = is_type(int) & interval.LR(0, 10)  # int within [0, 10]
    print(in_(1))  # OK
    print(in_(10))  # OK
    print(in_(11.2))  # not an int, not in [0, 10] neither

The output should be

1
10
Traceback (most recent call last):
  File "test_main.py", line 7, in <module>
    print(in_(11.2))  # not an int, not in [0, 10] neither
  File "/home/hansbug/projects/argsloader/argsloader/units/base.py", line 237, in __call__
    return self.call(v, 'FIRST')
  File "/home/hansbug/projects/argsloader/argsloader/units/base.py", line 249, in call
    return self._process(PValue(v, ())).act(err_mode)
  File "/home/hansbug/projects/argsloader/argsloader/base/result.py", line 264, in act
    raise self._first_error()
  File "/home/hansbug/projects/argsloader/argsloader/units/build.py", line 80, in _easy_process
    pres = self._transform(v, pvalues)
  File "/home/hansbug/projects/argsloader/argsloader/units/build.py", line 105, in _transform
    v.value, nested_map(lambda x: x.value, pres)
  File "/home/hansbug/projects/argsloader/argsloader/units/type.py", line 43, in _calculate
    raise TypeError(f'Value type not match - {_tname(type_)} expected but {_tname(type(v))} found.')
TypeParseError: Value type not match - int expected but float found.

To resolve this problem, you can use method call to show them all.

from argsloader.units import is_type, interval

if __name__ == '__main__':
    in_ = is_type(int) & interval.LR(0, 10)  # int within [0, 10]
    print(in_.call(1))  # OK
    print(in_.call(10))  # OK
    print(in_.call(11.2))  # not an int, not in [0, 10] neither

The output should be

1
10
Traceback (most recent call last):
  File "test_main.py", line 7, in <module>
    print(in_.call(11.2))
  File "/home/hansbug/projects/argsloader/argsloader/units/base.py", line 249, in call
    return self._process(PValue(v, ())).act(err_mode)
  File "/home/hansbug/projects/argsloader/argsloader/base/result.py", line 268, in act
    raise self._full_error()
argsloader.base.exception.MultipleParseError: (2 errors)
  <root>: TypeParseError: Value type not match - int expected but float found.
  <root>: ValueParseError: Value not in interval - [0, 10] expected but 11.2 found.

For further examples and best practice, see

Contributing

We appreciate all contributions to improve argsloader, both logic and system designs. Please refer to CONTRIBUTING.md for more guides.

License

argsloader released under the Apache 2.0 license.