Mercurial > hgrepos > Python > libs > ConfigMix
view configmix/ini.py @ 31:50721b43e76c v0.2
+++++ v0.2
| author | Franz Glasner <hg@dom66.de> |
|---|---|
| date | Fri, 18 Mar 2016 09:28:34 +0100 |
| parents | 7c7955da42ab |
| children | aa8345dae995 |
line wrap: on
line source
# -*- coding: utf-8 -*- r"""Read INI-style configuration files. """ from __future__ import division, absolute_import, print_function import sys import os import io import locale try: from configparser import SafeConfigParser, NoSectionError, NoOptionError except ImportError: from ConfigParser import SafeConfigParser, NoSectionError, NoOptionError try: from collections import OrderedDict as DictImpl except ImportError: try: from ordereddict import OrderedDict as DictImpl except ImportError: DictImpl = dict from .compat import PY2, u __all__ = ["INIConfigParser", "NoSectionError", "NoOptionError", "load"] class INIConfigParser(SafeConfigParser): """A case sensitive config parser that returns all-unicode string values. """ def __init__(self, filename, executable=None, encoding=None): SafeConfigParser.__init__(self) if executable is None: executable = sys.argv[0] if PY2: if isinstance(filename, str): filename = filename.decode(locale.getpreferredencoding()) if isinstance(executable, str): executable = executable.decode(locale.getpreferredencoding()) self.executable = os.path.normpath(os.path.abspath(executable)) if encoding is None: encoding = locale.getpreferredencoding() self.encoding = encoding with io.open(filename, mode="rt", encoding=self.encoding) as cf: self.readfp(cf, filename) def optionxform(self, option): return option def get_path_list(self, section, option): v = self.get(section, option) return v.split(os.pathsep) def read(self, filenames): raise NotImplementedError("use `readfp()' instead") def readfp(self, fp, filename): if hasattr(self, "filename"): raise RuntimeError("already initialized") filename = os.path.normpath(os.path.abspath(filename)) if PY2: if isinstance(filename, str): filename = filename.decode(locale.getpreferredencoding()) self.set(None, u("self"), filename) self.set(None, u("here"), os.path.dirname(filename)) self.set(None, u("root"), os.path.dirname(self.executable)) SafeConfigParser.readfp(self, fp, filename=filename) self.filename = filename self.root = os.path.dirname(self.executable) def getx(self, section, option): """Extended get() with some automatic type conversion support. Default: Fetch as string (like `get()`). If annotated with ``:bool:`` fetch as bool, if annotated with ``:int:`` fetch as int, if annotated with ``:float:`` fetch as float. """ v = self.get(section, option) if v.startswith(u(":bool:")): v = v[6:].lower() if v not in self._BOOL_CVT: raise ValueError("Not a boolean: %r" % v) return self._BOOL_CVT[v] elif v.startswith(u(":int:")): return int(v[5:], 0) elif v.startswith(u(":float:")): return float(v[7:]) else: return v _BOOL_CVT = {u('1'): True, u('yes'): True, u('true'): True, u('on'): True, u('0'): False, u('no'): False, u('false'): False, u('off'): False} def itemsx(self, section, options): """Get all the options given in `options` of section `section`. Fetch them with `self.getx()` in the order given. Return a list of ``(name, value)`` pairs for each option in `options` in the given `section`. """ d = [] for option in options: try: val = self.getx(section, option) except (NoSectionError, NoOptionError): pass else: d.append((option, val, )) return d def items_as_dictx(self, section, options): """Similar to `self.itemsx()` but return a (possibly ordered) dict instead of a list of key-value pairs. """ return DictImpl(self.itemsx(section, options)) def load(filename, extract=["config"]): """Load a single INI file and read/interpolate the sections given in `extract`. Flattens the given sections into the resulting dictionary. """ conf = DictImpl() ini = INIConfigParser(filename) for sect in extract: try: cfg = ini.options(sect) except NoSectionError: pass else: for option in cfg: value = ini.getx(sect, option) conf[option] = value return conf
