Gentoo Archives: gentoo-commits

From: "Fabian Groffen (grobian)" <grobian@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] portage r15499 - in main/branches/prefix/pym/portage: . dbapi package/ebuild util
Date: Sun, 28 Feb 2010 14:18:25
Message-Id: E1NljyP-00058V-Ro@stork.gentoo.org
1 Author: grobian
2 Date: 2010-02-28 14:18:21 +0000 (Sun, 28 Feb 2010)
3 New Revision: 15499
4
5 Added:
6 main/branches/prefix/pym/portage/_legacy_globals.py
7 main/branches/prefix/pym/portage/package/ebuild/deprecated_profile_check.py
8 main/branches/prefix/pym/portage/util/mtimedb.py
9 Modified:
10 main/branches/prefix/pym/portage/__init__.py
11 main/branches/prefix/pym/portage/_deprecated.py
12 main/branches/prefix/pym/portage/dbapi/bintree.py
13 Log:
14 Merged from trunk -r15489:15493
15
16 | 15490 | Move the MtimeDB class to portage.util.mtimedb and deprecate |
17 | zmedico | the commit_mtimedb function. |
18
19 | 15491 | Move deprecated_profile_check to portage.package.ebuild |
20 | zmedico | submodule. |
21
22 | 15492 | Move legacy globals code into a _legacy_globals module |
23 | zmedico | that's imported on demand. |
24
25 | 15493 | Fix broken fakedbapi.cpv_inject/cpv_remove calls. |
26 | zmedico | |
27
28
29 Modified: main/branches/prefix/pym/portage/__init__.py
30 ===================================================================
31 --- main/branches/prefix/pym/portage/__init__.py 2010-02-28 14:11:50 UTC (rev 15498)
32 +++ main/branches/prefix/pym/portage/__init__.py 2010-02-28 14:18:21 UTC (rev 15499)
33 @@ -107,6 +107,8 @@
34 'doebuild_environment,spawn,spawnebuild',
35 'portage.package.ebuild.config:autouse,best_from_dict,' + \
36 'check_config_instance,config',
37 + 'portage.package.ebuild.deprecated_profile_check:' + \
38 + 'deprecated_profile_check',
39 'portage.package.ebuild.digestcheck:digestcheck',
40 'portage.package.ebuild.digestgen:digestgen',
41 'portage.package.ebuild.fetch:fetch',
42 @@ -131,12 +133,14 @@
43 'portage.util.ExtractKernelVersion:ExtractKernelVersion',
44 'portage.util.listdir:cacheddir,listdir',
45 'portage.util.movefile:movefile',
46 + 'portage.util.mtimedb:MtimeDB',
47 'portage.versions',
48 'portage.versions:best,catpkgsplit,catsplit,cpv_getkey,' + \
49 'cpv_getkey@getCPFromCPV,endversion_keys,' + \
50 'suffix_value@endversion,pkgcmp,pkgsplit,vercmp,ververify',
51 'portage.xpak',
52 - 'portage._deprecated:dep_virtual,digestParseFile,getvirtuals,pkgmerge',
53 + 'portage._deprecated:commit_mtimedb,dep_virtual,' + \
54 + 'digestParseFile,getvirtuals,pkgmerge',
55 )
56
57 import portage.const
58 @@ -504,122 +508,18 @@
59 )
60 auxdbkeylen=len(auxdbkeys)
61
62 -def deprecated_profile_check(settings=None):
63 - config_root = "/"
64 - if settings is not None:
65 - config_root = settings["PORTAGE_CONFIGROOT"]
66 - deprecated_profile_file = os.path.join(config_root,
67 - DEPRECATED_PROFILE_FILE)
68 - if not os.access(deprecated_profile_file, os.R_OK):
69 - return False
70 - dcontent = codecs.open(_unicode_encode(deprecated_profile_file,
71 - encoding=_encodings['fs'], errors='strict'),
72 - mode='r', encoding=_encodings['content'], errors='replace').readlines()
73 - writemsg(colorize("BAD", _("\n!!! Your current profile is "
74 - "deprecated and not supported anymore.")) + "\n", noiselevel=-1)
75 - writemsg(colorize("BAD", _("!!! Use eselect profile to update your "
76 - "profile.")) + "\n", noiselevel=-1)
77 - if not dcontent:
78 - writemsg(colorize("BAD", _("!!! Please refer to the "
79 - "Gentoo Upgrading Guide.")) + "\n", noiselevel=-1)
80 - return True
81 - newprofile = dcontent[0]
82 - writemsg(colorize("BAD", _("!!! Please upgrade to the "
83 - "following profile if possible:")) + "\n", noiselevel=-1)
84 - writemsg(8*" " + colorize("GOOD", newprofile) + "\n", noiselevel=-1)
85 - if len(dcontent) > 1:
86 - writemsg(_("To upgrade do the following steps:\n"), noiselevel=-1)
87 - for myline in dcontent[1:]:
88 - writemsg(myline, noiselevel=-1)
89 - writemsg("\n\n", noiselevel=-1)
90 - return True
91 -
92 -def commit_mtimedb(mydict=None, filename=None):
93 - if mydict is None:
94 - global mtimedb
95 - if "mtimedb" not in globals() or mtimedb is None:
96 - return
97 - mtimedb.commit()
98 - return
99 - if filename is None:
100 - global mtimedbfile
101 - filename = mtimedbfile
102 - mydict["version"] = VERSION
103 - d = {} # for full backward compat, pickle it as a plain dict object.
104 - d.update(mydict)
105 - try:
106 - f = atomic_ofstream(filename, mode='wb')
107 - pickle.dump(d, f, protocol=2)
108 - f.close()
109 - portage.util.apply_secpass_permissions(filename,
110 - uid=uid, gid=portage_gid, mode=0o644)
111 - except (IOError, OSError) as e:
112 - pass
113 -
114 def portageexit():
115 - global uid,portage_gid,portdb,db
116 - if secpass and os.environ.get("SANDBOX_ON") != "1":
117 + if secpass > 1 and os.environ.get("SANDBOX_ON") != "1":
118 close_portdbapi_caches()
119 - commit_mtimedb()
120 + try:
121 + mtimedb
122 + except NameError:
123 + pass
124 + else:
125 + mtimedb.commit()
126
127 atexit_register(portageexit)
128
129 -class MtimeDB(dict):
130 - def __init__(self, filename):
131 - dict.__init__(self)
132 - self.filename = filename
133 - self._load(filename)
134 -
135 - def _load(self, filename):
136 - try:
137 - f = open(_unicode_encode(filename), 'rb')
138 - mypickle = pickle.Unpickler(f)
139 - try:
140 - mypickle.find_global = None
141 - except AttributeError:
142 - # TODO: If py3k, override Unpickler.find_class().
143 - pass
144 - d = mypickle.load()
145 - f.close()
146 - del f
147 - except (IOError, OSError, EOFError, ValueError, pickle.UnpicklingError) as e:
148 - if isinstance(e, pickle.UnpicklingError):
149 - writemsg(_("!!! Error loading '%s': %s\n") % \
150 - (filename, str(e)), noiselevel=-1)
151 - del e
152 - d = {}
153 -
154 - if "old" in d:
155 - d["updates"] = d["old"]
156 - del d["old"]
157 - if "cur" in d:
158 - del d["cur"]
159 -
160 - d.setdefault("starttime", 0)
161 - d.setdefault("version", "")
162 - for k in ("info", "ldpath", "updates"):
163 - d.setdefault(k, {})
164 -
165 - mtimedbkeys = set(("info", "ldpath", "resume", "resume_backup",
166 - "starttime", "updates", "version"))
167 -
168 - for k in list(d):
169 - if k not in mtimedbkeys:
170 - writemsg(_("Deleting invalid mtimedb key: %s\n") % str(k))
171 - del d[k]
172 - self.update(d)
173 - self._clean_data = copy.deepcopy(d)
174 -
175 - def commit(self):
176 - if not self.filename:
177 - return
178 - d = {}
179 - d.update(self)
180 - # Only commit if the internal state has changed.
181 - if d != self._clean_data:
182 - commit_mtimedb(mydict=d, filename=self.filename)
183 - self._clean_data = copy.deepcopy(d)
184 -
185 def create_trees(config_root=None, target_root=None, trees=None):
186 if trees is None:
187 trees = {}
188 @@ -663,10 +563,6 @@
189 return trees
190
191 class _LegacyGlobalProxy(proxy.objectproxy.ObjectProxy):
192 - """
193 - Instances of these serve as proxies to global variables
194 - that are initialized on demand.
195 - """
196
197 __slots__ = ('_name',)
198
199 @@ -675,53 +571,19 @@
200 object.__setattr__(self, '_name', name)
201
202 def _get_target(self):
203 - init_legacy_globals()
204 name = object.__getattribute__(self, '_name')
205 - return globals()[name]
206 + from portage._legacy_globals import _get_legacy_global
207 + return _get_legacy_global(name)
208
209 -class _PortdbProxy(proxy.objectproxy.ObjectProxy):
210 - """
211 - The portdb is initialized separately from the rest
212 - of the variables, since sometimes the other variables
213 - are needed while the portdb is not.
214 - """
215 -
216 - __slots__ = ()
217 -
218 - def _get_target(self):
219 - init_legacy_globals()
220 - global db, portdb, root, _portdb_initialized
221 - if not _portdb_initialized:
222 - portdb = db[root]["porttree"].dbapi
223 - _portdb_initialized = True
224 - return portdb
225 -
226 -class _MtimedbProxy(proxy.objectproxy.ObjectProxy):
227 - """
228 - The mtimedb is independent from the portdb and other globals.
229 - """
230 -
231 - __slots__ = ('_name',)
232 -
233 - def __init__(self, name):
234 - proxy.objectproxy.ObjectProxy.__init__(self)
235 - object.__setattr__(self, '_name', name)
236 -
237 - def _get_target(self):
238 - global mtimedb, mtimedbfile, _mtimedb_initialized
239 - if not _mtimedb_initialized:
240 - mtimedbfile = os.path.join(os.path.sep,
241 - CACHE_PATH, "mtimedb")
242 - mtimedb = MtimeDB(mtimedbfile)
243 - _mtimedb_initialized = True
244 - name = object.__getattribute__(self, '_name')
245 - return globals()[name]
246 -
247 _legacy_global_var_names = ("archlist", "db", "features",
248 "groups", "mtimedb", "mtimedbfile", "pkglines",
249 "portdb", "profiledir", "root", "selinux_enabled",
250 "settings", "thirdpartymirrors", "usedefaults")
251
252 +for k in _legacy_global_var_names:
253 + globals()[k] = _LegacyGlobalProxy(k)
254 +del k
255 +
256 def _disable_legacy_globals():
257 """
258 This deletes the ObjectProxy instances that are used
259 @@ -732,80 +594,3 @@
260 global _legacy_global_var_names
261 for k in _legacy_global_var_names:
262 globals().pop(k, None)
263 -
264 -# Initialization of legacy globals. No functions/classes below this point
265 -# please! When the above functions and classes become independent of the
266 -# below global variables, it will be possible to make the below code
267 -# conditional on a backward compatibility flag (backward compatibility could
268 -# be disabled via an environment variable, for example). This will enable new
269 -# code that is aware of this flag to import portage without the unnecessary
270 -# overhead (and other issues!) of initializing the legacy globals.
271 -
272 -def init_legacy_globals():
273 - global _globals_initialized
274 - if _globals_initialized:
275 - return
276 - _globals_initialized = True
277 -
278 - global db, settings, root, portdb, selinux_enabled, mtimedbfile, mtimedb, \
279 - archlist, features, groups, pkglines, thirdpartymirrors, usedefaults, \
280 - profiledir
281 -
282 - # Portage needs to ensure a sane umask for the files it creates.
283 - os.umask(0o22)
284 -
285 - kwargs = {}
286 - kwargs["config_root"] = os.environ.get("PORTAGE_CONFIGROOT", EPREFIX + "/")
287 - kwargs["target_root"] = os.environ.get("ROOT", "/")
288 -
289 - global _initializing_globals
290 - _initializing_globals = True
291 - db = create_trees(**kwargs)
292 - del _initializing_globals
293 -
294 - settings = db["/"]["vartree"].settings
295 -
296 - for myroot in db:
297 - if myroot != "/":
298 - settings = db[myroot]["vartree"].settings
299 - break
300 -
301 - root = settings["ROOT"]
302 - output._init(config_root=settings['PORTAGE_CONFIGROOT'])
303 -
304 - # ========================================================================
305 - # COMPATIBILITY
306 - # These attributes should not be used
307 - # within Portage under any circumstances.
308 - # ========================================================================
309 - archlist = settings.archlist()
310 - features = settings.features
311 - groups = settings["ACCEPT_KEYWORDS"].split()
312 - pkglines = settings.packages
313 - selinux_enabled = settings.selinux_enabled()
314 - thirdpartymirrors = settings.thirdpartymirrors()
315 - usedefaults = settings.use_defs
316 - profiledir = os.path.join(settings["PORTAGE_CONFIGROOT"], PROFILE_PATH)
317 - if not os.path.isdir(profiledir):
318 - profiledir = None
319 - # ========================================================================
320 - # COMPATIBILITY
321 - # These attributes should not be used
322 - # within Portage under any circumstances.
323 - # ========================================================================
324 -
325 -if True:
326 -
327 - _mtimedb_initialized = False
328 - mtimedb = _MtimedbProxy("mtimedb")
329 - mtimedbfile = _MtimedbProxy("mtimedbfile")
330 -
331 - _portdb_initialized = False
332 - portdb = _PortdbProxy()
333 -
334 - _globals_initialized = False
335 -
336 - for k in ("db", "settings", "root", "selinux_enabled",
337 - "archlist", "features", "groups",
338 - "pkglines", "thirdpartymirrors", "usedefaults", "profiledir"):
339 - globals()[k] = _LegacyGlobalProxy(k)
340
341 Modified: main/branches/prefix/pym/portage/_deprecated.py
342 ===================================================================
343 --- main/branches/prefix/pym/portage/_deprecated.py 2010-02-28 14:11:50 UTC (rev 15498)
344 +++ main/branches/prefix/pym/portage/_deprecated.py 2010-02-28 14:18:21 UTC (rev 15499)
345 @@ -16,6 +16,11 @@
346 from portage.manifest import Manifest
347 from portage.util import writemsg, writemsg_stdout
348
349 +def commit_mtimedb(mydict=None, filename=None):
350 + warnings.warn("portage.commit_mtimedb() is deprecated, " + \
351 + "use portage.mtimedb.commit() instead",
352 + DeprecationWarning, stacklevel=2)
353 +
354 def digestParseFile(myfilename, mysettings=None):
355 """(filename) -- Parses a given file for entries matching:
356 <checksumkey> <checksum_hex_string> <filename> <filesize>
357
358 Copied: main/branches/prefix/pym/portage/_legacy_globals.py (from rev 15493, main/trunk/pym/portage/_legacy_globals.py)
359 ===================================================================
360 --- main/branches/prefix/pym/portage/_legacy_globals.py (rev 0)
361 +++ main/branches/prefix/pym/portage/_legacy_globals.py 2010-02-28 14:18:21 UTC (rev 15499)
362 @@ -0,0 +1,87 @@
363 +# Copyright 2010 Gentoo Foundation
364 +# Distributed under the terms of the GNU General Public License v2
365 +# $Id$
366 +
367 +import portage
368 +from portage import os
369 +from portage.const import CACHE_PATH, PROFILE_PATH
370 +
371 +_legacy_globals = {}
372 +
373 +def _get_legacy_global(name):
374 + global _legacy_globals
375 + target = _legacy_globals.get(name, _legacy_globals)
376 + if target is not _legacy_globals:
377 + return target
378 +
379 + if name == 'portdb':
380 + portage.portdb = portage.db[portage.root]["porttree"].dbapi
381 + _legacy_globals[name] = portage.portdb
382 + return _legacy_globals[name]
383 + elif name in ('mtimedb', 'mtimedbfile'):
384 + portage.mtimedbfile = os.path.join(portage.root,
385 + CACHE_PATH, "mtimedb")
386 + _legacy_globals['mtimedbfile'] = portage.mtimedbfile
387 + portage.mtimedb = portage.MtimeDB(portage.mtimedbfile)
388 + _legacy_globals['mtimedb'] = portage.mtimedb
389 + return _legacy_globals[name]
390 +
391 + # Portage needs to ensure a sane umask for the files it creates.
392 + os.umask(0o22)
393 +
394 + kwargs = {}
395 + kwargs["config_root"] = os.environ.get("PORTAGE_CONFIGROOT", EPREFIX + "/")
396 + kwargs["target_root"] = os.environ.get("ROOT", "/")
397 +
398 + portage._initializing_globals = True
399 + portage.db = portage.create_trees(**kwargs)
400 + _legacy_globals['db'] = portage.db
401 + del portage._initializing_globals
402 +
403 + settings = portage.db["/"]["vartree"].settings
404 +
405 + for root in portage.db:
406 + if root != "/":
407 + settings = portage.db[root]["vartree"].settings
408 + break
409 +
410 + portage.output._init(config_root=settings['PORTAGE_CONFIGROOT'])
411 +
412 + portage.settings = settings
413 + _legacy_globals['settings'] = settings
414 +
415 + portage.root = root
416 + _legacy_globals['root'] = root
417 +
418 + # COMPATIBILITY
419 + # These attributes should not be used within
420 + # Portage under any circumstances.
421 +
422 + portage.archlist = settings.archlist()
423 + _legacy_globals['archlist'] = portage.archlist
424 +
425 + portage.features = settings.features
426 + _legacy_globals['features'] = portage.features
427 +
428 + portage.groups = settings["ACCEPT_KEYWORDS"].split()
429 + _legacy_globals['groups'] = portage.groups
430 +
431 + portage.pkglines = settings.packages
432 + _legacy_globals['pkglines'] = portage.pkglines
433 +
434 + portage.selinux_enabled = settings.selinux_enabled()
435 + _legacy_globals['selinux_enabled'] = portage.selinux_enabled
436 +
437 + portage.thirdpartymirrors = settings.thirdpartymirrors()
438 + _legacy_globals['thirdpartymirrors'] = portage.thirdpartymirrors
439 +
440 + portage.usedefaults = settings.use_defs
441 + _legacy_globals['usedefaults'] = portage.usedefaults
442 +
443 + profiledir = os.path.join(settings["PORTAGE_CONFIGROOT"], PROFILE_PATH)
444 + if not os.path.isdir(profiledir):
445 + profiledir = None
446 + portage.profiledir = profiledir
447 + _legacy_globals['profiledir'] = portage.profiledir
448 +
449 + return _legacy_globals[name]
450
451 Modified: main/branches/prefix/pym/portage/dbapi/bintree.py
452 ===================================================================
453 --- main/branches/prefix/pym/portage/dbapi/bintree.py 2010-02-28 14:11:50 UTC (rev 15498)
454 +++ main/branches/prefix/pym/portage/dbapi/bintree.py 2010-02-28 14:18:21 UTC (rev 15499)
455 @@ -69,11 +69,11 @@
456
457 def cpv_inject(self, cpv, **kwargs):
458 self._aux_cache.pop(cpv, None)
459 - fakedbapi.cpv_inject(cpv, **kwargs)
460 + fakedbapi.cpv_inject(self, cpv, **kwargs)
461
462 def cpv_remove(self, cpv):
463 self._aux_cache.pop(cpv, None)
464 - fakedbapi.cpv_remove(cpv)
465 + fakedbapi.cpv_remove(self, cpv)
466
467 def aux_get(self, mycpv, wants):
468 if self.bintree and not self.bintree.populated:
469
470 Copied: main/branches/prefix/pym/portage/package/ebuild/deprecated_profile_check.py (from rev 15493, main/trunk/pym/portage/package/ebuild/deprecated_profile_check.py)
471 ===================================================================
472 --- main/branches/prefix/pym/portage/package/ebuild/deprecated_profile_check.py (rev 0)
473 +++ main/branches/prefix/pym/portage/package/ebuild/deprecated_profile_check.py 2010-02-28 14:18:21 UTC (rev 15499)
474 @@ -0,0 +1,43 @@
475 +# Copyright 2010 Gentoo Foundation
476 +# Distributed under the terms of the GNU General Public License v2
477 +# $Id$
478 +
479 +__all__ = ['deprecated_profile_check']
480 +
481 +import codecs
482 +
483 +from portage import os, _encodings, _unicode_encode
484 +from portage.const import DEPRECATED_PROFILE_FILE
485 +from portage.localization import _
486 +from portage.output import colorize
487 +from portage.util import writemsg
488 +
489 +def deprecated_profile_check(settings=None):
490 + config_root = "/"
491 + if settings is not None:
492 + config_root = settings["PORTAGE_CONFIGROOT"]
493 + deprecated_profile_file = os.path.join(config_root,
494 + DEPRECATED_PROFILE_FILE)
495 + if not os.access(deprecated_profile_file, os.R_OK):
496 + return False
497 + dcontent = codecs.open(_unicode_encode(deprecated_profile_file,
498 + encoding=_encodings['fs'], errors='strict'),
499 + mode='r', encoding=_encodings['content'], errors='replace').readlines()
500 + writemsg(colorize("BAD", _("\n!!! Your current profile is "
501 + "deprecated and not supported anymore.")) + "\n", noiselevel=-1)
502 + writemsg(colorize("BAD", _("!!! Use eselect profile to update your "
503 + "profile.")) + "\n", noiselevel=-1)
504 + if not dcontent:
505 + writemsg(colorize("BAD", _("!!! Please refer to the "
506 + "Gentoo Upgrading Guide.")) + "\n", noiselevel=-1)
507 + return True
508 + newprofile = dcontent[0]
509 + writemsg(colorize("BAD", _("!!! Please upgrade to the "
510 + "following profile if possible:")) + "\n", noiselevel=-1)
511 + writemsg(8*" " + colorize("GOOD", newprofile) + "\n", noiselevel=-1)
512 + if len(dcontent) > 1:
513 + writemsg(_("To upgrade do the following steps:\n"), noiselevel=-1)
514 + for myline in dcontent[1:]:
515 + writemsg(myline, noiselevel=-1)
516 + writemsg("\n\n", noiselevel=-1)
517 + return True
518
519 Copied: main/branches/prefix/pym/portage/util/mtimedb.py (from rev 15493, main/trunk/pym/portage/util/mtimedb.py)
520 ===================================================================
521 --- main/branches/prefix/pym/portage/util/mtimedb.py (rev 0)
522 +++ main/branches/prefix/pym/portage/util/mtimedb.py 2010-02-28 14:18:21 UTC (rev 15499)
523 @@ -0,0 +1,77 @@
524 +# Copyright 2010 Gentoo Foundation
525 +# Distributed under the terms of the GNU General Public License v2
526 +# $Id$
527 +
528 +__all__ = ['MtimeDB']
529 +
530 +import copy
531 +
532 +from portage import pickle, VERSION, _unicode_encode
533 +from portage.data import portage_gid, uid
534 +from portage.localization import _
535 +from portage.util import apply_secpass_permissions, atomic_ofstream, writemsg
536 +
537 +class MtimeDB(dict):
538 + def __init__(self, filename):
539 + dict.__init__(self)
540 + self.filename = filename
541 + self._load(filename)
542 +
543 + def _load(self, filename):
544 + try:
545 + f = open(_unicode_encode(filename), 'rb')
546 + mypickle = pickle.Unpickler(f)
547 + try:
548 + mypickle.find_global = None
549 + except AttributeError:
550 + # TODO: If py3k, override Unpickler.find_class().
551 + pass
552 + d = mypickle.load()
553 + f.close()
554 + del f
555 + except (IOError, OSError, EOFError, ValueError, pickle.UnpicklingError) as e:
556 + if isinstance(e, pickle.UnpicklingError):
557 + writemsg(_("!!! Error loading '%s': %s\n") % \
558 + (filename, str(e)), noiselevel=-1)
559 + del e
560 + d = {}
561 +
562 + if "old" in d:
563 + d["updates"] = d["old"]
564 + del d["old"]
565 + if "cur" in d:
566 + del d["cur"]
567 +
568 + d.setdefault("starttime", 0)
569 + d.setdefault("version", "")
570 + for k in ("info", "ldpath", "updates"):
571 + d.setdefault(k, {})
572 +
573 + mtimedbkeys = set(("info", "ldpath", "resume", "resume_backup",
574 + "starttime", "updates", "version"))
575 +
576 + for k in list(d):
577 + if k not in mtimedbkeys:
578 + writemsg(_("Deleting invalid mtimedb key: %s\n") % str(k))
579 + del d[k]
580 + self.update(d)
581 + self._clean_data = copy.deepcopy(d)
582 +
583 + def commit(self):
584 + if not self.filename:
585 + return
586 + d = {}
587 + d.update(self)
588 + # Only commit if the internal state has changed.
589 + if d != self._clean_data:
590 + d["version"] = VERSION
591 + try:
592 + f = atomic_ofstream(self.filename, mode='wb')
593 + except EnvironmentError:
594 + pass
595 + else:
596 + pickle.dump(d, f, protocol=2)
597 + f.close()
598 + apply_secpass_permissions(self.filename,
599 + uid=uid, gid=portage_gid, mode=0o644)
600 + self._clean_data = copy.deepcopy(d)