1 |
--- |
2 |
pym/portage/_sets/__init__.py | 29 ++----------------- |
3 |
pym/portage/repository/config.py | 38 ++----------------------- |
4 |
pym/portage/util/_desktop_entry.py | 20 ++----------- |
5 |
pym/portage/util/configparser.py | 57 +++++++++++++++++++++++++++++++++++++- |
6 |
4 files changed, 64 insertions(+), 80 deletions(-) |
7 |
|
8 |
diff --git a/pym/portage/_sets/__init__.py b/pym/portage/_sets/__init__.py |
9 |
index ec42f7c..6d69bda 100644 |
10 |
--- a/pym/portage/_sets/__init__.py |
11 |
+++ b/pym/portage/_sets/__init__.py |
12 |
@@ -22,7 +22,7 @@ from portage.exception import PackageSetNotFound |
13 |
from portage.localization import _ |
14 |
from portage.util import writemsg_level |
15 |
from portage.util.configparser import (SafeConfigParser, |
16 |
- NoOptionError, ParsingError) |
17 |
+ NoOptionError, ParsingError, read_configs) |
18 |
|
19 |
SETPREFIX = "@" |
20 |
|
21 |
@@ -50,32 +50,7 @@ class SetConfig(object): |
22 |
}) |
23 |
|
24 |
if _ENABLE_SET_CONFIG: |
25 |
- # use read_file/readfp in order to control decoding of unicode |
26 |
- try: |
27 |
- # Python >=3.2 |
28 |
- read_file = self._parser.read_file |
29 |
- except AttributeError: |
30 |
- read_file = self._parser.readfp |
31 |
- |
32 |
- for p in paths: |
33 |
- f = None |
34 |
- try: |
35 |
- f = io.open(_unicode_encode(p, |
36 |
- encoding=_encodings['fs'], errors='strict'), |
37 |
- mode='r', encoding=_encodings['repo.content'], |
38 |
- errors='replace') |
39 |
- except EnvironmentError: |
40 |
- pass |
41 |
- else: |
42 |
- try: |
43 |
- read_file(f) |
44 |
- except ParsingError as e: |
45 |
- writemsg_level(_unicode_decode( |
46 |
- _("!!! Error while reading sets config file: %s\n") |
47 |
- ) % e, level=logging.ERROR, noiselevel=-1) |
48 |
- finally: |
49 |
- if f is not None: |
50 |
- f.close() |
51 |
+ read_configs(self._parser, paths) |
52 |
else: |
53 |
self._create_default_config() |
54 |
|
55 |
diff --git a/pym/portage/repository/config.py b/pym/portage/repository/config.py |
56 |
index 9039886..a23f4bd 100644 |
57 |
--- a/pym/portage/repository/config.py |
58 |
+++ b/pym/portage/repository/config.py |
59 |
@@ -17,7 +17,8 @@ from portage.eapi import eapi_allows_directories_on_profile_level_and_repository |
60 |
from portage.env.loaders import KeyValuePairFileLoader |
61 |
from portage.util import (normalize_path, read_corresponding_eapi_file, shlex_split, |
62 |
stack_lists, writemsg, writemsg_level, _recursive_file_list) |
63 |
-from portage.util.configparser import SafeConfigParser, ConfigParserError |
64 |
+from portage.util.configparser import (SafeConfigParser, ConfigParserError, |
65 |
+ read_configs) |
66 |
from portage.util._path import isdir_raise_eaccess |
67 |
from portage.util.path import first_existing |
68 |
from portage.localization import _ |
69 |
@@ -542,15 +543,6 @@ class RepoConfigLoader(object): |
70 |
"""Parse files in paths to load config""" |
71 |
parser = SafeConfigParser(defaults=default_opts) |
72 |
|
73 |
- # use read_file/readfp in order to control decoding of unicode |
74 |
- try: |
75 |
- # Python >=3.2 |
76 |
- read_file = parser.read_file |
77 |
- source_kwarg = 'source' |
78 |
- except AttributeError: |
79 |
- read_file = parser.readfp |
80 |
- source_kwarg = 'filename' |
81 |
- |
82 |
recursive_paths = [] |
83 |
for p in paths: |
84 |
if isinstance(p, basestring): |
85 |
@@ -558,31 +550,7 @@ class RepoConfigLoader(object): |
86 |
else: |
87 |
recursive_paths.append(p) |
88 |
|
89 |
- for p in recursive_paths: |
90 |
- if isinstance(p, basestring): |
91 |
- f = None |
92 |
- try: |
93 |
- f = io.open(_unicode_encode(p, |
94 |
- encoding=_encodings['fs'], errors='strict'), |
95 |
- mode='r', encoding=_encodings['repo.content'], |
96 |
- errors='replace') |
97 |
- except EnvironmentError: |
98 |
- pass |
99 |
- else: |
100 |
- # The 'source' keyword argument is needed since otherwise |
101 |
- # ConfigParser in Python <3.3.3 may throw a TypeError |
102 |
- # because it assumes that f.name is a native string rather |
103 |
- # than binary when constructing error messages. |
104 |
- kwargs = {source_kwarg: p} |
105 |
- read_file(f, **portage._native_kwargs(kwargs)) |
106 |
- finally: |
107 |
- if f is not None: |
108 |
- f.close() |
109 |
- elif isinstance(p, io.StringIO): |
110 |
- kwargs = {source_kwarg: "<io.StringIO>"} |
111 |
- read_file(p, **portage._native_kwargs(kwargs)) |
112 |
- else: |
113 |
- raise TypeError("Unsupported type %r of element %r of 'paths' argument" % (type(p), p)) |
114 |
+ read_configs(parser, recursive_paths) |
115 |
|
116 |
prepos['DEFAULT'] = RepoConfig("DEFAULT", |
117 |
parser.defaults(), local_config=local_config) |
118 |
diff --git a/pym/portage/util/_desktop_entry.py b/pym/portage/util/_desktop_entry.py |
119 |
index 95a015e..4fe4194 100644 |
120 |
--- a/pym/portage/util/_desktop_entry.py |
121 |
+++ b/pym/portage/util/_desktop_entry.py |
122 |
@@ -9,7 +9,8 @@ import sys |
123 |
import portage |
124 |
from portage import _encodings, _unicode_encode, _unicode_decode |
125 |
from portage.util import writemsg |
126 |
-from portage.util.configparser import ConfigParserError, RawConfigParser |
127 |
+from portage.util.configparser import (ConfigParserError, RawConfigParser, |
128 |
+ read_configs) |
129 |
|
130 |
|
131 |
def parse_desktop_entry(path): |
132 |
@@ -20,22 +21,7 @@ def parse_desktop_entry(path): |
133 |
""" |
134 |
parser = RawConfigParser() |
135 |
|
136 |
- # use read_file/readfp in order to control decoding of unicode |
137 |
- try: |
138 |
- # Python >=3.2 |
139 |
- read_file = parser.read_file |
140 |
- except AttributeError: |
141 |
- read_file = parser.readfp |
142 |
- |
143 |
- with io.open(_unicode_encode(path, |
144 |
- encoding=_encodings['fs'], errors='strict'), |
145 |
- mode='r', encoding=_encodings['repo.content'], |
146 |
- errors='replace') as f: |
147 |
- content = f.read() |
148 |
- |
149 |
- # In Python 3.2, read_file does not support bytes in file names |
150 |
- # (see bug #429544), so use StringIO to hide the file name. |
151 |
- read_file(io.StringIO(content)) |
152 |
+ read_configs(parser, [path]) |
153 |
|
154 |
return parser |
155 |
|
156 |
diff --git a/pym/portage/util/configparser.py b/pym/portage/util/configparser.py |
157 |
index d305052..fb1a351 100644 |
158 |
--- a/pym/portage/util/configparser.py |
159 |
+++ b/pym/portage/util/configparser.py |
160 |
@@ -2,12 +2,13 @@ |
161 |
# Distributed under the terms of the GNU General Public License v2 |
162 |
|
163 |
__all__ = ['ConfigParserError', 'NoOptionError', 'ParsingError', |
164 |
- 'RawConfigParser', 'SafeConfigParser'] |
165 |
+ 'RawConfigParser', 'SafeConfigParser', 'read_configs'] |
166 |
|
167 |
# the following scary compatibility thing provides two classes: |
168 |
# - SafeConfigParser that provides safe interpolation for values, |
169 |
# - RawConfigParser that provides no interpolation for values. |
170 |
|
171 |
+import io |
172 |
import sys |
173 |
|
174 |
try: |
175 |
@@ -20,3 +21,57 @@ try: |
176 |
except ImportError: |
177 |
from ConfigParser import (Error as ConfigParserError, |
178 |
NoOptionError, ParsingError, RawConfigParser, SafeConfigParser) |
179 |
+ |
180 |
+from portage import _encodings |
181 |
+from portage import _native_kwargs |
182 |
+from portage import _unicode_encode |
183 |
+ |
184 |
+ |
185 |
+if sys.hexversion >= 0x3000000: |
186 |
+ # pylint: disable=W0622 |
187 |
+ basestring = str |
188 |
+ |
189 |
+ |
190 |
+def read_configs(parser, paths): |
191 |
+ """ |
192 |
+ Read configuration files from given paths into the specified |
193 |
+ ConfigParser, handling path encoding portably. |
194 |
+ @param parser: target *ConfigParser instance |
195 |
+ @type parser: SafeConfigParser or RawConfigParser |
196 |
+ @param paths: list of paths to read |
197 |
+ @type paths: iterable |
198 |
+ """ |
199 |
+ # use read_file/readfp in order to control decoding of unicode |
200 |
+ try: |
201 |
+ # Python >=3.2 |
202 |
+ read_file = parser.read_file |
203 |
+ source_kwarg = 'source' |
204 |
+ except AttributeError: |
205 |
+ read_file = parser.readfp |
206 |
+ source_kwarg = 'filename' |
207 |
+ |
208 |
+ for p in paths: |
209 |
+ if isinstance(p, basestring): |
210 |
+ f = None |
211 |
+ try: |
212 |
+ f = io.open(_unicode_encode(p, |
213 |
+ encoding=_encodings['fs'], errors='strict'), |
214 |
+ mode='r', encoding=_encodings['repo.content'], |
215 |
+ errors='replace') |
216 |
+ except EnvironmentError: |
217 |
+ pass |
218 |
+ else: |
219 |
+ # The 'source' keyword argument is needed since otherwise |
220 |
+ # ConfigParser in Python <3.3.3 may throw a TypeError |
221 |
+ # because it assumes that f.name is a native string rather |
222 |
+ # than binary when constructing error messages. |
223 |
+ kwargs = {source_kwarg: p} |
224 |
+ read_file(f, **_native_kwargs(kwargs)) |
225 |
+ finally: |
226 |
+ if f is not None: |
227 |
+ f.close() |
228 |
+ elif isinstance(p, io.StringIO): |
229 |
+ kwargs = {source_kwarg: "<io.StringIO>"} |
230 |
+ read_file(p, **_native_kwargs(kwargs)) |
231 |
+ else: |
232 |
+ raise TypeError("Unsupported type %r of element %r of 'paths' argument" % (type(p), p)) |
233 |
-- |
234 |
2.8.3 |