1 |
Author: grobian |
2 |
Date: 2008-06-27 14:47:19 +0000 (Fri, 27 Jun 2008) |
3 |
New Revision: 10814 |
4 |
|
5 |
Modified: |
6 |
main/branches/prefix/cnf/sets.conf |
7 |
main/branches/prefix/pym/_emerge/__init__.py |
8 |
main/branches/prefix/pym/portage/__init__.py |
9 |
main/branches/prefix/pym/portage/cache/mappings.py |
10 |
main/branches/prefix/pym/portage/dbapi/bintree.py |
11 |
main/branches/prefix/pym/portage/dbapi/porttree.py |
12 |
main/branches/prefix/pym/portage/getbinpkg.py |
13 |
main/branches/prefix/pym/portage/util.py |
14 |
Log: |
15 |
Merged from trunk 10788:10801 |
16 |
|
17 |
| 10789 | Swap out the whole Package.root_config attribute inside | |
18 |
| zmedico | depgraph.break_refs(). | |
19 |
|
20 |
| 10790 | Add a generic portage.cache.mappings.slot_dict_class() | |
21 |
| zmedico | function which generates mapping classes that behave similar | |
22 |
| | to a dict but store values as object attributes that are | |
23 |
| | allocated via __slots__. Instances of these objects have a | |
24 |
| | smaller memory footprint than a normal dict object. These | |
25 |
| | classes are used to reduce the memory footprint of the | |
26 |
| | dbapi.aux_get() caches and the Package.metadata attribute. | |
27 |
|
28 |
| 10791 | Fix indentation. | |
29 |
| zmedico | | |
30 |
|
31 |
| 10792 | Fix KeyError constructor style. | |
32 |
| zmedico | | |
33 |
|
34 |
| 10793 | Fix typo. | |
35 |
| zmedico | | |
36 |
|
37 |
| 10794 | Add docstring to slot_dict_class(). | |
38 |
| zmedico | | |
39 |
|
40 |
| 10795 | Fix typo. | |
41 |
| zmedico | | |
42 |
|
43 |
| 10796 | Use SlotDict where appropriate in binarytree._populate(). | |
44 |
| zmedico | | |
45 |
|
46 |
| 10797 | Make PackageIndex use SlotDict for package metadata storage. | |
47 |
| zmedico | The set of allowed keys is passed into the PackageIndex | |
48 |
| | constructor (normal dict instances will be used if the set | |
49 |
| | of keys is not passed in for some reason). A | |
50 |
| | SlotDict.allowed_keys attribute now provides access to a | |
51 |
| | frozenset of allowed keys. | |
52 |
|
53 |
| 10798 | Implement lazy initialization of global "portdb", "settings" | |
54 |
| zmedico | and other variables that pollute the portage module. This | |
55 |
| | works by initializing the global variables with dummy | |
56 |
| | "proxy" objects that serve as a means to trigger lazy | |
57 |
| | initialization. As soon as the first attribute access or | |
58 |
| | method call occurs on one of the proxy objects, it causes | |
59 |
| | all the proxy objects to be replaced with the real ones. | |
60 |
| | It's possible for an unsupported attribute access or method | |
61 |
| | call on a proxy object to trigger an error, leading to | |
62 |
| | breakage. However, hopefully these such corner cases will | |
63 |
| | negligible (only time will tell). | |
64 |
|
65 |
| 10799 | Use a separate proxy type to trigger portage.portdb | |
66 |
| zmedico | initialization separately from the rest of the legacy global | |
67 |
| | variables. This can be useful since sometimes the other | |
68 |
| | variables are needed while the portdb is not. | |
69 |
|
70 |
| 10800 | Also use a separate proxy type for portage.mtimedb since | |
71 |
| zmedico | it's independent from the portdb and settings. | |
72 |
|
73 |
| 10801 | change default name of EverythingSet to @all-installed (bug | |
74 |
| genone | #229467) | |
75 |
|
76 |
|
77 |
Modified: main/branches/prefix/cnf/sets.conf |
78 |
=================================================================== |
79 |
--- main/branches/prefix/cnf/sets.conf 2008-06-27 12:11:33 UTC (rev 10813) |
80 |
+++ main/branches/prefix/cnf/sets.conf 2008-06-27 14:47:19 UTC (rev 10814) |
81 |
@@ -25,7 +25,7 @@ |
82 |
world-candidate = False |
83 |
|
84 |
# Again, not much to change here, though people might prefer a different name |
85 |
-[everything] |
86 |
+[all-installed] |
87 |
class = portage.sets.dbapi.EverythingSet |
88 |
world-candidate = False |
89 |
|
90 |
|
91 |
Modified: main/branches/prefix/pym/_emerge/__init__.py |
92 |
=================================================================== |
93 |
--- main/branches/prefix/pym/_emerge/__init__.py 2008-06-27 12:11:33 UTC (rev 10813) |
94 |
+++ main/branches/prefix/pym/_emerge/__init__.py 2008-06-27 14:47:19 UTC (rev 10814) |
95 |
@@ -1398,108 +1398,33 @@ |
96 |
return True |
97 |
return False |
98 |
|
99 |
-class _PackageMetadataWrapper(object): |
100 |
+_all_metadata_keys = set(x for x in portage.auxdbkeys \ |
101 |
+ if not x.startswith("UNUSED_")) |
102 |
+_all_metadata_keys.discard("CDEPEND") |
103 |
+_all_metadata_keys.update(Package.metadata_keys) |
104 |
+ |
105 |
+from portage.cache.mappings import slot_dict_class |
106 |
+_PackageMetadataWrapperBase = slot_dict_class(_all_metadata_keys) |
107 |
+ |
108 |
+class _PackageMetadataWrapper(_PackageMetadataWrapperBase): |
109 |
""" |
110 |
Detect metadata updates and synchronize Package attributes. |
111 |
""" |
112 |
- _keys = set(x for x in portage.auxdbkeys \ |
113 |
- if not x.startswith("UNUSED_")) |
114 |
- _keys.discard("CDEPEND") |
115 |
- _keys.update(Package.metadata_keys) |
116 |
- _keys = tuple(sorted(_keys)) |
117 |
- __slots__ = ("__weakref__", "_pkg") + tuple("_val_" + k for k in _keys) |
118 |
+ |
119 |
+ __slots__ = ("_pkg",) |
120 |
_wrapped_keys = frozenset( |
121 |
["COUNTER", "INHERITED", "IUSE", "SLOT", "USE", "_mtime_"]) |
122 |
|
123 |
def __init__(self, pkg, metadata): |
124 |
+ _PackageMetadataWrapperBase.__init__(self) |
125 |
self._pkg = pkg |
126 |
self.update(metadata) |
127 |
|
128 |
- def __iter__(self): |
129 |
- for k, v in self.iteritems(): |
130 |
- yield k |
131 |
- |
132 |
- def __len__(self): |
133 |
- l = 0 |
134 |
- for i in self.iteritems(): |
135 |
- l += 1 |
136 |
- return l |
137 |
- |
138 |
- def keys(self): |
139 |
- return list(self) |
140 |
- |
141 |
- def iteritems(self): |
142 |
- for k in self._keys: |
143 |
- try: |
144 |
- yield (k, getattr(self, "_val_" + k)) |
145 |
- except AttributeError: |
146 |
- pass |
147 |
- |
148 |
- def items(self): |
149 |
- return list(self.iteritems()) |
150 |
- |
151 |
- def itervalues(self): |
152 |
- for k, v in self.itervalues(): |
153 |
- yield v |
154 |
- |
155 |
- def values(self): |
156 |
- return list(self.itervalues()) |
157 |
- |
158 |
- def __delitem__(self, k): |
159 |
- try: |
160 |
- delattr(self, "_val_" + k) |
161 |
- except AttributeError: |
162 |
- raise KeyError(k) |
163 |
- |
164 |
def __setitem__(self, k, v): |
165 |
- setattr(self, "_val_" + k, v) |
166 |
+ _PackageMetadataWrapperBase.__setitem__(self, k, v) |
167 |
if k in self._wrapped_keys: |
168 |
getattr(self, "_set_" + k.lower())(k, v) |
169 |
|
170 |
- def update(self, d): |
171 |
- i = getattr(d, "iteritems", None) |
172 |
- if i is None: |
173 |
- i = d |
174 |
- else: |
175 |
- i = i() |
176 |
- for k, v in i: |
177 |
- self[k] = v |
178 |
- |
179 |
- def __getitem__(self, k): |
180 |
- try: |
181 |
- return getattr(self, "_val_" + k) |
182 |
- except AttributeError: |
183 |
- raise KeyError(k) |
184 |
- |
185 |
- def get(self, key, default=None): |
186 |
- try: |
187 |
- return self[key] |
188 |
- except KeyError: |
189 |
- return default |
190 |
- |
191 |
- def __contains__(self, k): |
192 |
- return hasattr(self, "_val_" + k) |
193 |
- |
194 |
- def pop(self, key, *args): |
195 |
- if len(args) > 1: |
196 |
- raise TypeError("pop expected at most 2 arguments, got " + \ |
197 |
- repr(1 + len(args))) |
198 |
- try: |
199 |
- value = self[key] |
200 |
- except KeyError: |
201 |
- if args: |
202 |
- return args[0] |
203 |
- raise |
204 |
- del self[key] |
205 |
- return value |
206 |
- |
207 |
- def clear(self): |
208 |
- for k in self._keys: |
209 |
- try: |
210 |
- delattr(self, "_val_" + k) |
211 |
- except AttributError: |
212 |
- pass |
213 |
- |
214 |
def _set_inherited(self, k, v): |
215 |
if isinstance(v, basestring): |
216 |
v = frozenset(v.split()) |
217 |
@@ -3977,18 +3902,15 @@ |
218 |
if not isinstance(node, Package): |
219 |
continue |
220 |
|
221 |
- # The visible packages cache has fullfilled it's purpose |
222 |
- # and it's no longer needed, so free the memory. |
223 |
- node.root_config.visible_pkgs.clear() |
224 |
+ # The FakeVartree references the _package_cache which |
225 |
+ # references the depgraph. So that Package instances don't |
226 |
+ # hold the depgraph and FakeVartree on the heap, replace |
227 |
+ # the RootConfig that references the FakeVartree with the |
228 |
+ # original RootConfig instance which references the actual |
229 |
+ # vartree. |
230 |
+ node.root_config = \ |
231 |
+ self._trees_orig[node.root]["root_config"] |
232 |
|
233 |
- if isinstance(node.root_config.trees["vartree"], FakeVartree): |
234 |
- # The FakeVartree references the _package_cache which |
235 |
- # references the depgraph. So that Package instances don't |
236 |
- # hold the depgraph and FakeVartree on the heap, replace |
237 |
- # the FakeVartree reference with the real vartree. |
238 |
- node.root_config.trees["vartree"] = \ |
239 |
- self._trees_orig[node.root]["vartree"] |
240 |
- |
241 |
def _resolve_conflicts(self): |
242 |
if not self._complete_graph(): |
243 |
raise self._unknown_internal_error() |
244 |
|
245 |
Modified: main/branches/prefix/pym/portage/__init__.py |
246 |
=================================================================== |
247 |
--- main/branches/prefix/pym/portage/__init__.py 2008-06-27 12:11:33 UTC (rev 10813) |
248 |
+++ main/branches/prefix/pym/portage/__init__.py 2008-06-27 14:47:19 UTC (rev 10814) |
249 |
@@ -6993,6 +6993,54 @@ |
250 |
binarytree, myroot, mysettings["PKGDIR"], settings=mysettings) |
251 |
return trees |
252 |
|
253 |
+class _LegacyGlobalProxy(portage.util.ObjectProxy): |
254 |
+ """ |
255 |
+ Instances of these serve as proxies to global variables |
256 |
+ that are initialized on demand. |
257 |
+ """ |
258 |
+ def __init__(self, name): |
259 |
+ portage.util.ObjectProxy.__init__(self) |
260 |
+ object.__setattr__(self, '_name', name) |
261 |
+ |
262 |
+ def _get_target(self): |
263 |
+ init_legacy_globals() |
264 |
+ name = object.__getattribute__(self, '_name') |
265 |
+ return globals()[name] |
266 |
+ |
267 |
+class _PortdbProxy(portage.util.ObjectProxy): |
268 |
+ """ |
269 |
+ The portdb is initialized separately from the rest |
270 |
+ of the variables, since sometimes the other variables |
271 |
+ are needed while the portdb is not. |
272 |
+ """ |
273 |
+ |
274 |
+ def _get_target(self): |
275 |
+ init_legacy_globals() |
276 |
+ global db, portdb, root, _portdb_initialized |
277 |
+ if not _portdb_initialized: |
278 |
+ portdb = db[root]["porttree"].dbapi |
279 |
+ _portdb_initialized = True |
280 |
+ return portdb |
281 |
+ |
282 |
+class _MtimedbProxy(portage.util.ObjectProxy): |
283 |
+ """ |
284 |
+ The mtimedb is independent from the portdb and other globals. |
285 |
+ """ |
286 |
+ |
287 |
+ def __init__(self, name): |
288 |
+ portage.util.ObjectProxy.__init__(self) |
289 |
+ object.__setattr__(self, '_name', name) |
290 |
+ |
291 |
+ def _get_target(self): |
292 |
+ global mtimedb, mtimedbfile, _mtimedb_initialized |
293 |
+ if not _mtimedb_initialized: |
294 |
+ mtimedbfile = os.path.join("/", |
295 |
+ CACHE_PATH.lstrip(os.path.sep), "mtimedb") |
296 |
+ mtimedb = MtimeDB(mtimedbfile) |
297 |
+ _mtimedb_initialized = True |
298 |
+ name = object.__getattribute__(self, '_name') |
299 |
+ return globals()[name] |
300 |
+ |
301 |
# Initialization of legacy globals. No functions/classes below this point |
302 |
# please! When the above functions and classes become independent of the |
303 |
# below global variables, it will be possible to make the below code |
304 |
@@ -7002,6 +7050,11 @@ |
305 |
# overhead (and other issues!) of initializing the legacy globals. |
306 |
|
307 |
def init_legacy_globals(): |
308 |
+ global _globals_initialized |
309 |
+ if _globals_initialized: |
310 |
+ return |
311 |
+ _globals_initialized = True |
312 |
+ |
313 |
global db, settings, root, portdb, selinux_enabled, mtimedbfile, mtimedb, \ |
314 |
archlist, features, groups, pkglines, thirdpartymirrors, usedefaults, \ |
315 |
profiledir, flushmtimedb |
316 |
@@ -7019,18 +7072,14 @@ |
317 |
del _initializing_globals |
318 |
|
319 |
settings = db["/"]["vartree"].settings |
320 |
- portdb = db["/"]["porttree"].dbapi |
321 |
|
322 |
for myroot in db: |
323 |
if myroot != "/": |
324 |
settings = db[myroot]["vartree"].settings |
325 |
- portdb = db[myroot]["porttree"].dbapi |
326 |
break |
327 |
|
328 |
root = settings["ROOT"] |
329 |
|
330 |
- mtimedbfile = os.path.join("/", CACHE_PATH.lstrip(os.path.sep), "mtimedb") |
331 |
- mtimedb = MtimeDB(mtimedbfile) |
332 |
|
333 |
# ======================================================================== |
334 |
# COMPATIBILITY |
335 |
@@ -7060,8 +7109,22 @@ |
336 |
# use within Portage. External use of this variable is unsupported because |
337 |
# it is experimental and it's behavior is likely to change. |
338 |
if "PORTAGE_LEGACY_GLOBALS" not in os.environ: |
339 |
- init_legacy_globals() |
340 |
|
341 |
+ _mtimedb_initialized = False |
342 |
+ mtimedb = _MtimedbProxy("mtimedb") |
343 |
+ mtimedbfile = _MtimedbProxy("mtimedbfile") |
344 |
+ |
345 |
+ _portdb_initialized = False |
346 |
+ portdb = _PortdbProxy() |
347 |
+ |
348 |
+ _globals_initialized = False |
349 |
+ |
350 |
+ for k in ("db", "settings", "root", "selinux_enabled", |
351 |
+ "archlist", "features", "groups", |
352 |
+ "pkglines", "thirdpartymirrors", "usedefaults", "profiledir", |
353 |
+ "flushmtimedb"): |
354 |
+ globals()[k] = _LegacyGlobalProxy(k) |
355 |
+ |
356 |
# Clear the cache |
357 |
dircache={} |
358 |
|
359 |
|
360 |
Modified: main/branches/prefix/pym/portage/cache/mappings.py |
361 |
=================================================================== |
362 |
--- main/branches/prefix/pym/portage/cache/mappings.py 2008-06-27 12:11:33 UTC (rev 10813) |
363 |
+++ main/branches/prefix/pym/portage/cache/mappings.py 2008-06-27 14:47:19 UTC (rev 10814) |
364 |
@@ -4,6 +4,7 @@ |
365 |
# $Id$ |
366 |
|
367 |
import UserDict |
368 |
+import weakref |
369 |
|
370 |
class ProtectedDict(UserDict.DictMixin): |
371 |
""" |
372 |
@@ -101,3 +102,140 @@ |
373 |
self.pull = None |
374 |
return key in self.d |
375 |
|
376 |
+_slot_dict_classes = weakref.WeakValueDictionary() |
377 |
+ |
378 |
+def slot_dict_class(keys): |
379 |
+ """ |
380 |
+ Generates mapping classes that behave similar to a dict but store values |
381 |
+ as object attributes that are allocated via __slots__. Instances of these |
382 |
+ objects have a smaller memory footprint than a normal dict object. |
383 |
+ |
384 |
+ @param keys: Fixed set of allowed keys |
385 |
+ @type keys: iterable |
386 |
+ @rtype: SlotDict |
387 |
+ @returns: A class that constructs SlotDict instances |
388 |
+ having the specified keys. |
389 |
+ """ |
390 |
+ if isinstance(keys, frozenset): |
391 |
+ keys_set = keys |
392 |
+ else: |
393 |
+ keys_set = frozenset(keys) |
394 |
+ v = _slot_dict_classes.get(keys_set) |
395 |
+ if v is None: |
396 |
+ |
397 |
+ class SlotDict(object): |
398 |
+ |
399 |
+ allowed_keys = keys_set |
400 |
+ __slots__ = ("__weakref__",) + \ |
401 |
+ tuple("_val_" + k for k in allowed_keys) |
402 |
+ |
403 |
+ def __iter__(self): |
404 |
+ for k, v in self.iteritems(): |
405 |
+ yield k |
406 |
+ |
407 |
+ def __len__(self): |
408 |
+ l = 0 |
409 |
+ for i in self.iteritems(): |
410 |
+ l += 1 |
411 |
+ return l |
412 |
+ |
413 |
+ def keys(self): |
414 |
+ return list(self) |
415 |
+ |
416 |
+ def iteritems(self): |
417 |
+ for k in self.allowed_keys: |
418 |
+ try: |
419 |
+ yield (k, getattr(self, "_val_" + k)) |
420 |
+ except AttributeError: |
421 |
+ pass |
422 |
+ |
423 |
+ def items(self): |
424 |
+ return list(self.iteritems()) |
425 |
+ |
426 |
+ def itervalues(self): |
427 |
+ for k, v in self.iteritems(): |
428 |
+ yield v |
429 |
+ |
430 |
+ def values(self): |
431 |
+ return list(self.itervalues()) |
432 |
+ |
433 |
+ def __delitem__(self, k): |
434 |
+ try: |
435 |
+ delattr(self, "_val_" + k) |
436 |
+ except AttributeError: |
437 |
+ raise KeyError(k) |
438 |
+ |
439 |
+ def __setitem__(self, k, v): |
440 |
+ setattr(self, "_val_" + k, v) |
441 |
+ |
442 |
+ def setdefault(self, key, default=None): |
443 |
+ try: |
444 |
+ return self[key] |
445 |
+ except KeyError: |
446 |
+ self[key] = default |
447 |
+ return default |
448 |
+ |
449 |
+ def update(self, d): |
450 |
+ i = getattr(d, "iteritems", None) |
451 |
+ if i is None: |
452 |
+ i = d |
453 |
+ else: |
454 |
+ i = i() |
455 |
+ for k, v in i: |
456 |
+ self[k] = v |
457 |
+ |
458 |
+ def __getitem__(self, k): |
459 |
+ try: |
460 |
+ return getattr(self, "_val_" + k) |
461 |
+ except AttributeError: |
462 |
+ raise KeyError(k) |
463 |
+ |
464 |
+ def get(self, key, default=None): |
465 |
+ try: |
466 |
+ return self[key] |
467 |
+ except KeyError: |
468 |
+ return default |
469 |
+ |
470 |
+ def __contains__(self, k): |
471 |
+ return hasattr(self, "_val_" + k) |
472 |
+ |
473 |
+ def has_key(self, k): |
474 |
+ return k in self |
475 |
+ |
476 |
+ def pop(self, key, *args): |
477 |
+ if len(args) > 1: |
478 |
+ raise TypeError( |
479 |
+ "pop expected at most 2 arguments, got " + \ |
480 |
+ repr(1 + len(args))) |
481 |
+ try: |
482 |
+ value = self[key] |
483 |
+ except KeyError: |
484 |
+ if args: |
485 |
+ return args[0] |
486 |
+ raise |
487 |
+ del self[key] |
488 |
+ return value |
489 |
+ |
490 |
+ def popitem(self): |
491 |
+ try: |
492 |
+ k, v = self.iteritems().next() |
493 |
+ except StopIteration: |
494 |
+ raise KeyError('container is empty') |
495 |
+ del self[k] |
496 |
+ return (k, v) |
497 |
+ |
498 |
+ def copy(self): |
499 |
+ c = self.__class__() |
500 |
+ c.update(self) |
501 |
+ return c |
502 |
+ |
503 |
+ def clear(self): |
504 |
+ for k in self.allowed_keys: |
505 |
+ try: |
506 |
+ delattr(self, "_val_" + k) |
507 |
+ except AttributeError: |
508 |
+ pass |
509 |
+ |
510 |
+ v = SlotDict |
511 |
+ _slot_dict_classes[v.allowed_keys] = v |
512 |
+ return v |
513 |
|
514 |
Modified: main/branches/prefix/pym/portage/dbapi/bintree.py |
515 |
=================================================================== |
516 |
--- main/branches/prefix/pym/portage/dbapi/bintree.py 2008-06-27 12:11:33 UTC (rev 10813) |
517 |
+++ main/branches/prefix/pym/portage/dbapi/bintree.py 2008-06-27 14:47:19 UTC (rev 10814) |
518 |
@@ -2,6 +2,7 @@ |
519 |
# Distributed under the terms of the GNU General Public License v2 |
520 |
# $Id$ |
521 |
|
522 |
+from portage.cache.mappings import slot_dict_class |
523 |
from portage.dep import isvalidatom, isjustname, dep_getkey, match_from_list |
524 |
from portage.dbapi.virtual import fakedbapi |
525 |
from portage.exception import InvalidPackageName, InvalidAtom, \ |
526 |
@@ -18,7 +19,7 @@ |
527 |
|
528 |
import os, errno, stat |
529 |
import re |
530 |
-from itertools import izip |
531 |
+from itertools import chain, izip |
532 |
|
533 |
class bindbapi(fakedbapi): |
534 |
_known_keys = frozenset(list(fakedbapi._known_keys) + \ |
535 |
@@ -35,6 +36,7 @@ |
536 |
"LICENSE", "PDEPEND", "PROVIDE", |
537 |
"RDEPEND", "repository", "RESTRICT", "SLOT", "USE", |
538 |
"EPREFIX"]) |
539 |
+ self._aux_cache_slot_dict = slot_dict_class(self._aux_cache_keys) |
540 |
self._aux_cache = {} |
541 |
|
542 |
def match(self, *pargs, **kwargs): |
543 |
@@ -77,7 +79,7 @@ |
544 |
if not mydata.setdefault("EAPI", "0"): |
545 |
mydata["EAPI"] = "0" |
546 |
if cache_me: |
547 |
- aux_cache = {} |
548 |
+ aux_cache = self._aux_cache_slot_dict() |
549 |
for x in self._aux_cache_keys: |
550 |
aux_cache[x] = mydata.get(x, "") |
551 |
self._aux_cache[mycpv] = aux_cache |
552 |
@@ -187,6 +189,16 @@ |
553 |
("repository" , "REPO"), |
554 |
) |
555 |
|
556 |
+ self._pkgindex_allowed_pkg_keys = set(chain( |
557 |
+ self._pkgindex_keys, |
558 |
+ self._pkgindex_aux_keys, |
559 |
+ self._pkgindex_hashes, |
560 |
+ self._pkgindex_default_pkg_data, |
561 |
+ self._pkgindex_inherited_keys, |
562 |
+ self._pkgindex_default_header_data, |
563 |
+ chain(*self._pkgindex_translated_keys) |
564 |
+ )) |
565 |
+ |
566 |
def move_ent(self, mylist): |
567 |
if not self.populated: |
568 |
self.populate() |
569 |
@@ -483,7 +495,7 @@ |
570 |
update_pkgindex = True |
571 |
self.dbapi.cpv_inject(mycpv) |
572 |
if not self.dbapi._aux_cache_keys.difference(d): |
573 |
- aux_cache = {} |
574 |
+ aux_cache = self.dbapi._aux_cache_slot_dict() |
575 |
for k in self.dbapi._aux_cache_keys: |
576 |
aux_cache[k] = d[k] |
577 |
self.dbapi._aux_cache[mycpv] = aux_cache |
578 |
@@ -580,7 +592,7 @@ |
579 |
d.pop("PATH", None) |
580 |
metadata[mycpv] = d |
581 |
if not self.dbapi._aux_cache_keys.difference(d): |
582 |
- aux_cache = {} |
583 |
+ aux_cache = self.dbapi._aux_cache_slot_dict() |
584 |
for k in self.dbapi._aux_cache_keys: |
585 |
aux_cache[k] = d[k] |
586 |
self.dbapi._aux_cache[mycpv] = aux_cache |
587 |
@@ -835,6 +847,7 @@ |
588 |
|
589 |
def _new_pkgindex(self): |
590 |
return portage.getbinpkg.PackageIndex( |
591 |
+ allowed_pkg_keys=self._pkgindex_allowed_pkg_keys, |
592 |
default_header_data=self._pkgindex_default_header_data, |
593 |
default_pkg_data=self._pkgindex_default_pkg_data, |
594 |
inherited_keys=self._pkgindex_inherited_keys, |
595 |
|
596 |
Modified: main/branches/prefix/pym/portage/dbapi/porttree.py |
597 |
=================================================================== |
598 |
--- main/branches/prefix/pym/portage/dbapi/porttree.py 2008-06-27 12:11:33 UTC (rev 10813) |
599 |
+++ main/branches/prefix/pym/portage/dbapi/porttree.py 2008-06-27 14:47:19 UTC (rev 10814) |
600 |
@@ -3,6 +3,7 @@ |
601 |
# $Id$ |
602 |
|
603 |
from portage.cache.cache_errors import CacheError |
604 |
+from portage.cache.mappings import slot_dict_class |
605 |
from portage.const import REPO_NAME_LOC |
606 |
from portage.data import portage_gid, secpass |
607 |
from portage.dbapi import dbapi |
608 |
@@ -138,6 +139,10 @@ |
609 |
["DEPEND", "EAPI", "IUSE", "KEYWORDS", "LICENSE", |
610 |
"PDEPEND", "PROVIDE", "RDEPEND", "repository", |
611 |
"RESTRICT", "SLOT"]) |
612 |
+ |
613 |
+ # Repoman modifies _aux_cache_keys, so delay _aux_cache_slot_dict |
614 |
+ # initialization until the first aux_get call. |
615 |
+ self._aux_cache_slot_dict = None |
616 |
self._aux_cache = {} |
617 |
self._broken_ebuilds = set() |
618 |
|
619 |
@@ -386,7 +391,10 @@ |
620 |
returnme.append(mydata.get(x,"")) |
621 |
|
622 |
if cache_me: |
623 |
- aux_cache = {} |
624 |
+ if self._aux_cache_slot_dict is None: |
625 |
+ self._aux_cache_slot_dict = \ |
626 |
+ slot_dict_class(self._aux_cache_keys) |
627 |
+ aux_cache = self._aux_cache_slot_dict() |
628 |
for x in self._aux_cache_keys: |
629 |
aux_cache[x] = mydata.get(x, "") |
630 |
self._aux_cache[mycpv] = aux_cache |
631 |
@@ -866,4 +874,3 @@ |
632 |
except Exception, e: |
633 |
pass |
634 |
return myslot |
635 |
- |
636 |
|
637 |
Modified: main/branches/prefix/pym/portage/getbinpkg.py |
638 |
=================================================================== |
639 |
--- main/branches/prefix/pym/portage/getbinpkg.py 2008-06-27 12:11:33 UTC (rev 10813) |
640 |
+++ main/branches/prefix/pym/portage/getbinpkg.py 2008-06-27 14:47:19 UTC (rev 10814) |
641 |
@@ -4,6 +4,7 @@ |
642 |
# $Id$ |
643 |
|
644 |
from portage.output import red, yellow, green |
645 |
+from portage.cache.mappings import slot_dict_class |
646 |
import portage.xpak |
647 |
import HTMLParser |
648 |
import sys |
649 |
@@ -681,8 +682,17 @@ |
650 |
|
651 |
class PackageIndex(object): |
652 |
|
653 |
- def __init__(self, default_header_data=None, default_pkg_data=None, |
654 |
- inherited_keys=None, translated_keys=None): |
655 |
+ def __init__(self, |
656 |
+ allowed_pkg_keys=None, |
657 |
+ default_header_data=None, |
658 |
+ default_pkg_data=None, |
659 |
+ inherited_keys=None, |
660 |
+ translated_keys=None): |
661 |
+ |
662 |
+ self._pkg_slot_dict = None |
663 |
+ if allowed_pkg_keys is not None: |
664 |
+ self._pkg_slot_dict = slot_dict_class(allowed_pkg_keys) |
665 |
+ |
666 |
self._default_header_data = default_header_data |
667 |
self._default_pkg_data = default_pkg_data |
668 |
self._inherited_keys = inherited_keys |
669 |
@@ -697,8 +707,15 @@ |
670 |
self.packages = [] |
671 |
self.modified = True |
672 |
|
673 |
- def _readpkgindex(self, pkgfile): |
674 |
- d = {} |
675 |
+ def _readpkgindex(self, pkgfile, pkg_entry=True): |
676 |
+ |
677 |
+ allowed_keys = None |
678 |
+ if self._pkg_slot_dict is None or not pkg_entry: |
679 |
+ d = {} |
680 |
+ else: |
681 |
+ d = self._pkg_slot_dict() |
682 |
+ allowed_keys = d.allowed_keys |
683 |
+ |
684 |
for line in pkgfile: |
685 |
line = line.rstrip("\n") |
686 |
if not line: |
687 |
@@ -709,7 +726,11 @@ |
688 |
k, v = line |
689 |
if v: |
690 |
v = v[1:] |
691 |
- d[self._read_translation_map.get(k, k)] = v |
692 |
+ k = self._read_translation_map.get(k, k) |
693 |
+ if allowed_keys is not None and \ |
694 |
+ k not in allowed_keys: |
695 |
+ continue |
696 |
+ d[k] = v |
697 |
return d |
698 |
|
699 |
def _writepkgindex(self, pkgfile, items): |
700 |
@@ -723,7 +744,7 @@ |
701 |
self.readBody(pkgfile) |
702 |
|
703 |
def readHeader(self, pkgfile): |
704 |
- self.header.update(self._readpkgindex(pkgfile)) |
705 |
+ self.header.update(self._readpkgindex(pkgfile, pkg_entry=False)) |
706 |
|
707 |
def readBody(self, pkgfile): |
708 |
while True: |
709 |
|
710 |
Modified: main/branches/prefix/pym/portage/util.py |
711 |
=================================================================== |
712 |
--- main/branches/prefix/pym/portage/util.py 2008-06-27 12:11:33 UTC (rev 10813) |
713 |
+++ main/branches/prefix/pym/portage/util.py 2008-06-27 14:47:19 UTC (rev 10814) |
714 |
@@ -913,6 +913,67 @@ |
715 |
perms_modified = apply_permissions(dir_path, *args, **kwargs) |
716 |
return created_dir or perms_modified |
717 |
|
718 |
+class ObjectProxy(object): |
719 |
+ |
720 |
+ """ |
721 |
+ Object that acts as a proxy to another object, forwarding |
722 |
+ attribute accesses and method calls. This can be useful |
723 |
+ for implementing lazy initialization. |
724 |
+ """ |
725 |
+ |
726 |
+ def _get_target(self): |
727 |
+ raise NotImplementedError(self) |
728 |
+ |
729 |
+ def __getattribute__(self, attr): |
730 |
+ result = object.__getattribute__(self, '_get_target')() |
731 |
+ return getattr(result, attr) |
732 |
+ |
733 |
+ def __setattr__(self, attr, value): |
734 |
+ result = object.__getattribute__(self, '_get_target')() |
735 |
+ setattr(result, attr, value) |
736 |
+ |
737 |
+ def __call__(self, *args, **kwargs): |
738 |
+ result = object.__getattribute__(self, '_get_target')() |
739 |
+ return result(*args, **kwargs) |
740 |
+ |
741 |
+ def __setitem__(self, key, value): |
742 |
+ object.__getattribute__(self, '_get_target')()[key] = value |
743 |
+ |
744 |
+ def __getitem__(self, key): |
745 |
+ return object.__getattribute__(self, '_get_target')()[key] |
746 |
+ |
747 |
+ def __delitem__(self, key): |
748 |
+ del object.__getattribute__(self, '_get_target')()[key] |
749 |
+ |
750 |
+ def __contains__(self, key): |
751 |
+ return key in object.__getattribute__(self, '_get_target')() |
752 |
+ |
753 |
+ def __iter__(self): |
754 |
+ return iter(object.__getattribute__(self, '_get_target')()) |
755 |
+ |
756 |
+ def __len__(self): |
757 |
+ return len(object.__getattribute__(self, '_get_target')()) |
758 |
+ |
759 |
+ def __repr__(self): |
760 |
+ return repr(object.__getattribute__(self, '_get_target')()) |
761 |
+ |
762 |
+ def __str__(self): |
763 |
+ return str(object.__getattribute__(self, '_get_target')()) |
764 |
+ |
765 |
+ def __hash__(self): |
766 |
+ return hash(object.__getattribute__(self, '_get_target')()) |
767 |
+ |
768 |
+ def __eq__(self, other): |
769 |
+ return object.__getattribute__(self, '_get_target')() == other |
770 |
+ |
771 |
+ def __ne__(self, other): |
772 |
+ return object.__getattribute__(self, '_get_target')() != other |
773 |
+ |
774 |
+ def __nonzero__(self): |
775 |
+ if object.__getattribute__(self, '_get_target')(): |
776 |
+ return True |
777 |
+ return False |
778 |
+ |
779 |
class LazyItemsDict(dict): |
780 |
"""A mapping object that behaves like a standard dict except that it allows |
781 |
for lazy initialization of values via callable objects. Lazy items can be |
782 |
|
783 |
-- |
784 |
gentoo-commits@l.g.o mailing list |