-# 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
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
""" 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
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()
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:
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):