Source code for argsloader.units.common

from typing import Mapping, Any

from inflection import underscore

from .base import UnitProcessProxy
from .build import CalculateUnit, BaseUnit
from ..base import PValue, ParseResult


[docs]class IsUnit(CalculateUnit): """ Overview: Unit for ``is`` calculation. """ __names__ = ('target',) __errors__ = (ValueError,)
[docs] def __init__(self, target): """ Constructor of :class:`IsUnit`. :param target: Target for calculation. """ CalculateUnit.__init__(self, target)
def _calculate(self, v: object, pres: Mapping[str, Any]) -> object: target = pres['target'] if v is target: return v else: raise ValueError(f'Value expected to be {repr(target)}({hex(id(target))}), ' f'but {repr(v)}({hex(id(v))}) found.')
[docs]def is_(v) -> IsUnit: """ Overview: Check if the given object is the same object as ``v``. :param v: Unit or value to be checked. :return: A :class:`IsUnit` object. Examples:: >>> from argsloader.units import is_ >>> u = is_(1) >>> u(1) # 1 is 1, int is immutable in python 1 >>> u(2) # 2 is 1 ValueParseError: Value expected to be 1(0x7fb7799546c0), but 2(0x7fb7799546e0) found. >>> u(None) ValueParseError: Value expected to be 1(0x7fb7799546c0), but None(0x7fb77990a110) found. """ return IsUnit(v)
[docs]def none(): """ Overview: Check if the given value is none. Examples:: >>> from argsloader.units import none >>> u = none() >>> u(None) # None is None >>> u(2) # 2 is None ValueParseError: Value expected to be None(0x7fb77990a110), but 2(0x7fb7799546e0) found. """ return is_(None)
def _string_formal(s: str): return underscore(s.strip()).lower()
[docs]class YesNoUnit(BaseUnit): """ Overview: Unit for parsing yes or no option. """
[docs] def __init__(self, yes='yes', no='no'): """ Constructor of :class:`YesNoUnit`. :param yes: Yes string. :param no: No string. """ self._syes = yes self._sno = no
def _easy_process(self, v: PValue, proxy: UnitProcessProxy) -> ParseResult: if isinstance(v.value, str): fv = _string_formal(v.value) if fv == _string_formal(self._syes): return proxy.success(v.val(True)) elif fv == _string_formal(self._sno): return proxy.success(v.val(False)) else: return proxy.error(ValueError(f'Value expected to be {repr(self._syes)} or {repr(self._sno)}, ' f'but {repr(v.value)} found.')) else: return proxy.success(v.val(bool(v.value))) def _rinfo(self): return [('yes', self._syes), ('no', self._sno)], []
[docs]def yesno(yes='yes', no='no') -> YesNoUnit: """ Overview: Parse yes-or-no option. :param yes: Yes string, default is ``yes``. :param no: No string, default is ``no``. :return: A :class:`YesNoUnit` object. Examples:: - Simple Usage >>> from argsloader.units import yesno >>> u = yesno() >>> u('yes') True >>> u('no') False >>> u(True) True >>> u(False) False >>> u(1) True >>> u(0) False >>> u('xxx') ValueParseError: Value expected to be 'yes' or 'no', but 'xxx' found. - Self-defined tags >>> from argsloader.units import yesno >>> u = yesno('Accept', 'Decline') >>> u('accept') True >>> u('decline') False >>> u(True) True >>> u(False) False >>> u(1) True >>> u(0) False >>> u('yes') ValueParseError: Value expected to be 'Accept' or 'Decline', but 'yes' found. .. note:: If you need to parse from multiple pairs of yes and no tags, you can simply chain them \ together with ``|`` operator. >>> from argsloader.units import yesno >>> u = yesno() | yesno('Accept', 'Decline') >>> u('yes') True >>> u('NO') False >>> u('accept') True >>> u('decline') False >>> u('xxx') ValueParseError: Value expected to be 'yes' or 'no', but 'xxx' found. """ return YesNoUnit(yes, no)
[docs]def onoff(): """ Overview: Parse on-or-off option. The same as ``yesno('on', 'off')``, see :func:`yesno`. """ return yesno('on', 'off')