diff --git a/dist/pyutl-2.6.tar.gz b/dist/pyutl-2.6.tar.gz new file mode 100644 index 0000000..e97a507 Binary files /dev/null and b/dist/pyutl-2.6.tar.gz differ diff --git a/pyutl.egg-info/PKG-INFO b/pyutl.egg-info/PKG-INFO index 777c804..7d87c0f 100644 --- a/pyutl.egg-info/PKG-INFO +++ b/pyutl.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pyutl -Version: 2.5 +Version: 2.6 Summary: functions and utilities to recycle code Home-page: https://git.binkfe.com/jesrat/pyutl Author: Josue Gomez diff --git a/pyutl/__init__.py b/pyutl/__init__.py index ee0d56c..045668b 100644 --- a/pyutl/__init__.py +++ b/pyutl/__init__.py @@ -11,7 +11,7 @@ shellExecute can receive a cmd as str or arr example __title__ = 'pyutl' __description__ = 'functions and utilities to recycle code' __url__ = 'https://git.binkfe.com/jesrat/pyutl' -__version__ = '2.5' +__version__ = '2.6' __author__ = 'Josue Gomez ' __email__ = "jgomez@binkfe.com" __maintainer__ = "Josue Gomez" diff --git a/pyutl/localenv.py b/pyutl/localenv.py index 6f8e517..9f829e8 100644 --- a/pyutl/localenv.py +++ b/pyutl/localenv.py @@ -15,19 +15,23 @@ DEFAULT = object() class LocalEnv: + _BOOLEANS = {'1': True, 'yes': True, 'true': True, 'on': True, + '0': False, 'no': False, 'false': False, 'off': False, '': False} + def __init__(self): self.files = [] self.data = {} + self.first_load = False def load(self, file=None): """ If no file is defined, the .env file will be searched in invoker module's directory """ - if file is not None: - self.files.append({'file': file, 'exists': '', 'loaded': False}) - else: - self.files.append({'file': self._invoker(), 'exists': '', 'loaded': False}) + if file is None: + file = self._invoker() + + self.files.append({'file': file, 'exists': '', 'loaded': False}) # search all files given and load them for file_dict in self.files: @@ -45,26 +49,36 @@ class LocalEnv: self.data[key] = value file_dict['loaded'] = True + def _cast(self, cast, data): + if cast is bool and str(data).lower() not in self._BOOLEANS: + raise ValueError(f'value can not be parsed as boolean') + elif cast is bool: + return self._BOOLEANS[str(data).lower()] + else: + return cast(data) + def get(self, key, default=DEFAULT, cast=None): + if not self.first_load: + self.load() + self.first_load = True + try: - ret_val = self.data[key] if cast is None else cast(self.data[key]) + ret_val = self.data[key] if cast is None else self._cast(cast, self.data[key]) except KeyError: if default != DEFAULT: - ret_val = default if cast is None else cast(default) + ret_val = default if cast is None else self._cast(cast, default) else: raise KeyNotFound(f'value not found in files: \n{json.dumps(self.files, indent=4)}') return ret_val - @staticmethod - def _invoker(): + def _invoker(self): # tip from: # https://github.com/henriquebastos/python-decouple/blob/master/decouple.py # MAGIC! Get the caller's module path. frame = sys._getframe() - path = os.path.dirname(frame.f_back.f_back.f_code.co_filename) + path = os.path.dirname(frame.f_back.f_back.f_back.f_code.co_filename) file = os.path.join(path, '.env') return file localenv = LocalEnv() -localenv.load()