summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2012-02-17 18:01:27 -0800
committerZac Medico <zmedico@gentoo.org>2012-02-17 19:11:18 -0800
commit4c8d1060304a4e793c5d813a1d925e7cf1fcccbd (patch)
tree9eba02c86c6768544bbb7fb184a964f899b5fc94
parentrepoman: make virtual.oldstyle an error (diff)
downloadportage-4c8d1060304a4e793c5d813a1d925e7cf1fcccbd.tar.gz
portage-4c8d1060304a4e793c5d813a1d925e7cf1fcccbd.tar.bz2
portage-4c8d1060304a4e793c5d813a1d925e7cf1fcccbd.zip
PreservedLibsRegistry: add JSON read/write
Support serialization as JSON instead of pickle, so that /var/lib/portage/preserved_libs_registry is human readable/writable, for those rare cases where it may be useful. Currently, pickle is still used for writes. The plan is to migrate to JSON after JSON read has been supported for some time.
-rw-r--r--pym/portage/util/_dyn_libs/PreservedLibsRegistry.py61
1 files changed, 51 insertions, 10 deletions
diff --git a/pym/portage/util/_dyn_libs/PreservedLibsRegistry.py b/pym/portage/util/_dyn_libs/PreservedLibsRegistry.py
index 510c390af..405a23a88 100644
--- a/pym/portage/util/_dyn_libs/PreservedLibsRegistry.py
+++ b/pym/portage/util/_dyn_libs/PreservedLibsRegistry.py
@@ -1,7 +1,8 @@
-# Copyright 1998-2011 Gentoo Foundation
+# Copyright 1998-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
import errno
+import json
import logging
import sys
@@ -27,6 +28,19 @@ if sys.hexversion >= 0x3000000:
class PreservedLibsRegistry(object):
""" This class handles the tracking of preserved library objects """
+
+ # Enable this after JSON read has been supported for some time.
+ _json_write = False
+
+ _json_write_opts = {
+ "ensure_ascii": False,
+ "indent": "\t",
+ "sort_keys": True
+ }
+ if sys.hexversion < 0x3020000:
+ # indent only supports int number of spaces
+ _json_write_opts["indent"] = 4
+
def __init__(self, root, filename):
"""
@param root: root used to check existence of paths in pruneNonExisting
@@ -56,17 +70,11 @@ class PreservedLibsRegistry(object):
""" Reload the registry data from file """
self._data = None
f = None
+ content = None
try:
f = open(_unicode_encode(self._filename,
encoding=_encodings['fs'], errors='strict'), 'rb')
- if os.fstat(f.fileno()).st_size == 0:
- # ignore empty lock file
- pass
- else:
- self._data = pickle.load(f)
- except (AttributeError, EOFError, ValueError, pickle.UnpicklingError) as e:
- writemsg_level(_("!!! Error loading '%s': %s\n") % \
- (self._filename, e), level=logging.ERROR, noiselevel=-1)
+ content = f.read()
except EnvironmentError as e:
if not hasattr(e, 'errno'):
raise
@@ -79,8 +87,33 @@ class PreservedLibsRegistry(object):
finally:
if f is not None:
f.close()
+
+ # content is empty if it's an empty lock file
+ if content:
+ try:
+ self._data = pickle.loads(content)
+ except SystemExit:
+ raise
+ except Exception as e:
+ try:
+ self._data = json.loads(_unicode_decode(content,
+ encoding=_encodings['repo.content'], errors='strict'))
+ except SystemExit:
+ raise
+ except Exception:
+ writemsg_level(_("!!! Error loading '%s': %s\n") %
+ (self._filename, e), level=logging.ERROR,
+ noiselevel=-1)
+
if self._data is None:
self._data = {}
+ else:
+ for k, v in self._data.items():
+ if isinstance(v, (list, tuple)) and len(v) == 3 and \
+ isinstance(v[2], set):
+ # convert set to list, for write with JSONEncoder
+ self._data[k] = (v[0], v[1], list(v[2]))
+
self._data_orig = self._data.copy()
self.pruneNonExisting()
@@ -97,7 +130,12 @@ class PreservedLibsRegistry(object):
return
try:
f = atomic_ofstream(self._filename, 'wb')
- pickle.dump(self._data, f, protocol=2)
+ if self._json_write:
+ f.write(_unicode_encode(
+ json.dumps(self._data, **self._json_write_opts),
+ encoding=_encodings['repo.content'], errors='strict'))
+ else:
+ pickle.dump(self._data, f, protocol=2)
f.close()
except EnvironmentError as e:
if e.errno != PermissionDenied.errno:
@@ -138,6 +176,9 @@ class PreservedLibsRegistry(object):
self._normalize_counter(self._data[cps][1]) == counter:
del self._data[cps]
elif len(paths) > 0:
+ if isinstance(paths, set):
+ # convert set to list, for write with JSONEncoder
+ paths = list(paths)
self._data[cps] = (cpv, counter, paths)
def unregister(self, cpv, slot, counter):