Skip to content

Commit

Permalink
Merge pull request #50 from HansBug/dev/template
Browse files Browse the repository at this point in the history
dev(hansbug): add default value to env template
  • Loading branch information
HansBug authored May 24, 2022
2 parents 9d0be26 + f915b6c commit 000656e
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 4 deletions.
29 changes: 25 additions & 4 deletions hbutils/string/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,19 @@
Useful utilities for template a string.
"""
from string import Template
from typing import Optional, Mapping
from typing import Optional, Mapping, Any

__all__ = ['env_template']
from ..design import SingletonMark

__all__ = [
'env_template'
]

def env_template(template: str, environ: Optional[Mapping[str, str]] = None, safe: bool = False) -> str:
_NO_DEFAULT_VALUE = SingletonMark('_NO_DEFAULT_VALUE')


def env_template(template: str, environ: Optional[Mapping[str, Any]] = None,
safe: bool = False, default: Any = _NO_DEFAULT_VALUE) -> str:
"""
Overview:
Mapping all the environment values (not system environment variables) into a template string.
Expand All @@ -18,6 +25,8 @@ def env_template(template: str, environ: Optional[Mapping[str, str]] = None, saf
- environ (:obj:`Optional[Mapping[str, str]]`): Environment values, should be a mapping.
- safe (:obj:`bool`): Safe substitute, default is ``False`` which means \
all the value used in template should be able to found in the given ``environ``.
- default (:obj:`Any`): Default value when no variable provided. Default is ``_NO_DEFAULT_VALUE``, which \
means ``KeyError`` will be raised.
Returns:
- result (:obj:`str`): Substituted string.
Expand All @@ -30,7 +39,19 @@ def env_template(template: str, environ: Optional[Mapping[str, str]] = None, saf
KeyError: 'B'
>>> env_template('${A} + 1 = ${B}', {'A': '1'}, safe=True)
'1 + 1 = ${B}'
>>> env_template('${A} + 1 = ${B}', {'A': '1'}, default='') # like environment variable
'1 + 1 = '
"""

class _DefaultDict(dict):
def __getitem__(self, item):
return dict.get(self, item, default)

_template = Template(template)
env = environ or {}
if default is not _NO_DEFAULT_VALUE:
env = _DefaultDict(env)

_func = _template.safe_substitute if safe else _template.substitute
return _func(**(environ or {}))
# noinspection PyArgumentList
return _func(env)
4 changes: 4 additions & 0 deletions test/string/test_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ def test_env_template(self):
assert env_template('this is the ${number} day.', dict(number='1st')) == 'this is the 1st day.'
with pytest.raises(KeyError):
env_template('this is the ${number} day')

def test_env_template_with_default(self):
assert env_template('${A} + 1 == ${B}', {'A': 1}, default='') == '1 + 1 == '
assert env_template('${A} + 1 == ${B}', {'A': 1}, default='', safe=True) == '1 + 1 == '

0 comments on commit 000656e

Please sign in to comment.