From: "Michał Górny" <mgorny@gentoo.org>
To: gentoo-portage-dev@lists.gentoo.org
Cc: "Michał Górny" <mgorny@gentoo.org>
Subject: [gentoo-portage-dev] [PATCH 2/2] portage.util.configparser: Commonize portable config file reading routine
Date: Sun, 22 May 2016 10:41:48 +0200 [thread overview]
Message-ID: <20160522084148.2658-2-mgorny@gentoo.org> (raw)
In-Reply-To: <20160522084148.2658-1-mgorny@gentoo.org>
---
pym/portage/_sets/__init__.py | 29 ++-----------------
pym/portage/repository/config.py | 38 ++-----------------------
pym/portage/util/_desktop_entry.py | 20 ++-----------
pym/portage/util/configparser.py | 57 +++++++++++++++++++++++++++++++++++++-
4 files changed, 64 insertions(+), 80 deletions(-)
diff --git a/pym/portage/_sets/__init__.py b/pym/portage/_sets/__init__.py
index ec42f7c..6d69bda 100644
--- a/pym/portage/_sets/__init__.py
+++ b/pym/portage/_sets/__init__.py
@@ -22,7 +22,7 @@ from portage.exception import PackageSetNotFound
from portage.localization import _
from portage.util import writemsg_level
from portage.util.configparser import (SafeConfigParser,
- NoOptionError, ParsingError)
+ NoOptionError, ParsingError, read_configs)
SETPREFIX = "@"
@@ -50,32 +50,7 @@ class SetConfig(object):
})
if _ENABLE_SET_CONFIG:
- # use read_file/readfp in order to control decoding of unicode
- try:
- # Python >=3.2
- read_file = self._parser.read_file
- except AttributeError:
- read_file = self._parser.readfp
-
- for p in paths:
- 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:
- try:
- read_file(f)
- except ParsingError as e:
- writemsg_level(_unicode_decode(
- _("!!! Error while reading sets config file: %s\n")
- ) % e, level=logging.ERROR, noiselevel=-1)
- finally:
- if f is not None:
- f.close()
+ read_configs(self._parser, paths)
else:
self._create_default_config()
diff --git a/pym/portage/repository/config.py b/pym/portage/repository/config.py
index 9039886..a23f4bd 100644
--- a/pym/portage/repository/config.py
+++ b/pym/portage/repository/config.py
@@ -17,7 +17,8 @@ from portage.eapi import eapi_allows_directories_on_profile_level_and_repository
from portage.env.loaders import KeyValuePairFileLoader
from portage.util import (normalize_path, read_corresponding_eapi_file, shlex_split,
stack_lists, writemsg, writemsg_level, _recursive_file_list)
-from portage.util.configparser import SafeConfigParser, ConfigParserError
+from portage.util.configparser import (SafeConfigParser, ConfigParserError,
+ read_configs)
from portage.util._path import isdir_raise_eaccess
from portage.util.path import first_existing
from portage.localization import _
@@ -542,15 +543,6 @@ class RepoConfigLoader(object):
"""Parse files in paths to load config"""
parser = SafeConfigParser(defaults=default_opts)
- # 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'
-
recursive_paths = []
for p in paths:
if isinstance(p, basestring):
@@ -558,31 +550,7 @@ class RepoConfigLoader(object):
else:
recursive_paths.append(p)
- for p in recursive_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, **portage._native_kwargs(kwargs))
- finally:
- if f is not None:
- f.close()
- elif isinstance(p, io.StringIO):
- kwargs = {source_kwarg: "<io.StringIO>"}
- read_file(p, **portage._native_kwargs(kwargs))
- else:
- raise TypeError("Unsupported type %r of element %r of 'paths' argument" % (type(p), p))
+ read_configs(parser, recursive_paths)
prepos['DEFAULT'] = RepoConfig("DEFAULT",
parser.defaults(), local_config=local_config)
diff --git a/pym/portage/util/_desktop_entry.py b/pym/portage/util/_desktop_entry.py
index 95a015e..4fe4194 100644
--- a/pym/portage/util/_desktop_entry.py
+++ b/pym/portage/util/_desktop_entry.py
@@ -9,7 +9,8 @@ import sys
import portage
from portage import _encodings, _unicode_encode, _unicode_decode
from portage.util import writemsg
-from portage.util.configparser import ConfigParserError, RawConfigParser
+from portage.util.configparser import (ConfigParserError, RawConfigParser,
+ read_configs)
def parse_desktop_entry(path):
@@ -20,22 +21,7 @@ def parse_desktop_entry(path):
"""
parser = RawConfigParser()
- # use read_file/readfp in order to control decoding of unicode
- try:
- # Python >=3.2
- read_file = parser.read_file
- except AttributeError:
- read_file = parser.readfp
-
- with io.open(_unicode_encode(path,
- encoding=_encodings['fs'], errors='strict'),
- mode='r', encoding=_encodings['repo.content'],
- errors='replace') as f:
- content = f.read()
-
- # In Python 3.2, read_file does not support bytes in file names
- # (see bug #429544), so use StringIO to hide the file name.
- read_file(io.StringIO(content))
+ read_configs(parser, [path])
return parser
diff --git a/pym/portage/util/configparser.py b/pym/portage/util/configparser.py
index d305052..fb1a351 100644
--- a/pym/portage/util/configparser.py
+++ b/pym/portage/util/configparser.py
@@ -2,12 +2,13 @@
# Distributed under the terms of the GNU General Public License v2
__all__ = ['ConfigParserError', 'NoOptionError', 'ParsingError',
- 'RawConfigParser', 'SafeConfigParser']
+ '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:
@@ -20,3 +21,57 @@ try:
except ImportError:
from ConfigParser import (Error as ConfigParserError,
NoOptionError, ParsingError, RawConfigParser, SafeConfigParser)
+
+from portage import _encodings
+from portage import _native_kwargs
+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, **_native_kwargs(kwargs))
+ finally:
+ if f is not None:
+ f.close()
+ elif isinstance(p, io.StringIO):
+ kwargs = {source_kwarg: "<io.StringIO>"}
+ read_file(p, **_native_kwargs(kwargs))
+ else:
+ raise TypeError("Unsupported type %r of element %r of 'paths' argument" % (type(p), p))
--
2.8.3
next prev parent reply other threads:[~2016-05-22 8:42 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-05-22 8:41 [gentoo-portage-dev] [PATCH 1/2] portage.util.configparser: Provide common code to handle cp imports Michał Górny
2016-05-22 8:41 ` Michał Górny [this message]
2016-05-22 18:04 ` [gentoo-portage-dev] [PATCH 2/2] portage.util.configparser: Commonize portable config file reading routine Zac Medico
2016-05-24 6:28 ` Michał Górny
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160522084148.2658-2-mgorny@gentoo.org \
--to=mgorny@gentoo.org \
--cc=gentoo-portage-dev@lists.gentoo.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox