diff options
Diffstat (limited to 'lib/portage/util/configparser.py')
-rw-r--r-- | lib/portage/util/configparser.py | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/lib/portage/util/configparser.py b/lib/portage/util/configparser.py new file mode 100644 index 000000000..c4c92a603 --- /dev/null +++ b/lib/portage/util/configparser.py @@ -0,0 +1,76 @@ +# Copyright 2016 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +__all__ = ['ConfigParserError', 'NoOptionError', 'ParsingError', + 'RawConfigParser', 'SafeConfigParser', 'read_configs'] + +# the following scary compatibility thing provides two classes: +# - SafeConfigParser that provides safe interpolation for values, +# - RawConfigParser that provides no interpolation for values. + +import io +import sys + +try: + from configparser import (Error as ConfigParserError, + NoOptionError, ParsingError, RawConfigParser) + if sys.hexversion >= 0x3020000: + from configparser import ConfigParser as SafeConfigParser + else: + from configparser import SafeConfigParser +except ImportError: + from ConfigParser import (Error as ConfigParserError, + NoOptionError, ParsingError, RawConfigParser, SafeConfigParser) + +from portage import _encodings +from portage import _unicode_encode + + +if sys.hexversion >= 0x3000000: + # pylint: disable=W0622 + basestring = str + + +def read_configs(parser, paths): + """ + Read configuration files from given paths into the specified + ConfigParser, handling path encoding portably. + @param parser: target *ConfigParser instance + @type parser: SafeConfigParser or RawConfigParser + @param paths: list of paths to read + @type paths: iterable + """ + # use read_file/readfp in order to control decoding of unicode + try: + # Python >=3.2 + read_file = parser.read_file + source_kwarg = 'source' + except AttributeError: + read_file = parser.readfp + source_kwarg = 'filename' + + for p in paths: + if isinstance(p, basestring): + f = None + try: + f = io.open(_unicode_encode(p, + encoding=_encodings['fs'], errors='strict'), + mode='r', encoding=_encodings['repo.content'], + errors='replace') + except EnvironmentError: + pass + else: + # The 'source' keyword argument is needed since otherwise + # ConfigParser in Python <3.3.3 may throw a TypeError + # because it assumes that f.name is a native string rather + # than binary when constructing error messages. + kwargs = {source_kwarg: p} + read_file(f, **kwargs) + finally: + if f is not None: + f.close() + elif isinstance(p, io.StringIO): + kwargs = {source_kwarg: "<io.StringIO>"} + read_file(p, **kwargs) + else: + raise TypeError("Unsupported type %r of element %r of 'paths' argument" % (type(p), p)) |