Source code for tanium_kit.ini_reader

"""IniReader."""
from __future__ import absolute_import, division, print_function, unicode_literals

import os
import sys
from io import StringIO, open

_VERSION = sys.version_info
IS_PY2 = _VERSION[0] == 2
IS_PY3 = _VERSION[0] == 3

if IS_PY2:
    integer_types = (int, long)  # noqa
    text_type = unicode  # noqa
    import ConfigParser as configparser
elif IS_PY3:
    integer_types = int,
    text_type = str
    import configparser as configparser


[docs]class IniReaderError(Exception): """Reader exceptions."""
[docs]class IniReader(object): """IniReader.""" TEXT_PRE = "__TEXT::" BOOL_OPTS = ["true", "false", "yes", "no", "on", "off", 0, "0", 1, "1"] BOOL_TRUE = ["true", "yes", "on", 1, "1"] _value_cache = {} _parser_type = configparser.RawConfigParser
[docs] def read(self, ini_path=None, ini_text=None, ini_handle=None, **kwargs): """IniReader.""" if ini_text: fh = StringIO(ini_text) path = "<ini_text stream>" elif ini_path: if os.path.isfile(ini_path): fh = open(ini_path, encoding="utf-8") path = ini_path else: m = "Unable to find 'ini_path': '{}'" raise IniReaderError(m.format(ini_path)) elif ini_handle: fh = ini_handle path = "<ini_handle stream>" else: m = "Must provide ini_text, ini_path, or ini_handle as an argument" raise IniReaderError(m) cp = configparser.RawConfigParser() try: cp.readfp(fh) except Exception as e: m = "Unable to parse INI file '{}', error: {}" raise IniReaderError(m.format(path, e)) ret = {s: {i[0]: self._tv(i[1]) for i in cp.items(s)} for s in cp.sections()} return path, ret
[docs] def _tv(self, value): """Cache to avoid transforming value too many times.""" if value not in self._value_cache: new_value = value if self.is_txt(value): new_value = self.to_txt(value) elif self.is_int(value): new_value = int(value) elif self.is_float(value): new_value = float(value) elif self.is_bool(value): new_value = self.to_bool(value) elif self.is_none(value): new_value = None self._value_cache[value] = new_value return self._value_cache[value]
[docs] def is_float(self, value): """Check if the value is a float.""" return self._is_type(value, float)
[docs] def is_int(self, value): """Check if the value is an int.""" return any([self._is_type(value, t) for t in integer_types])
[docs] def is_txt(self, value): """Check if the value begins with TEXT_PRE.""" return text_type(value).startswith(self.TEXT_PRE)
[docs] def is_bool(self, value): """Check if the value is a bool.""" return value.lower() in self.BOOL_OPTS
[docs] def is_none(self, value): """Check if the value is a None.""" return value.lower() == text_type(None).lower()
[docs] def to_txt(self, value): """Convert a value to text, removing FORCE_TEXT::.""" return "".join(text_type(value).split(self.TEXT_PRE, 1)[1:])
[docs] def to_bool(self, value): """Convert value to a bool.""" return value.lower() in self.BOOL_TRUE
[docs] def _is_type(self, value, ptype): """Try to set value to python type ptype.""" try: ptype(value) ret = True except Exception: ret = False return ret