import sys
from itertools import chain
import portage
+from portage.cache.mappings import slot_dict_class
from portage.dep import paren_reduce, use_reduce, \
paren_normalize, paren_enclose
from _emerge.Task import Task
_all_metadata_keys.update(Package.metadata_keys)
_all_metadata_keys = frozenset(_all_metadata_keys)
-class _PackageMetadataWrapper(dict):
+_PackageMetadataWrapperBase = slot_dict_class(_all_metadata_keys)
+
+class _PackageMetadataWrapper(_PackageMetadataWrapperBase):
"""
Detect metadata updates and synchronize Package attributes.
"""
__slots__ = ("_pkg",)
+ _wrapped_keys = frozenset(
+ ["COUNTER", "INHERITED", "IUSE", "SLOT", "_mtime_"])
_use_conditional_keys = frozenset(
['LICENSE', 'PROPERTIES', 'PROVIDE', 'RESTRICT',])
def __init__(self, pkg, metadata):
+ _PackageMetadataWrapperBase.__init__(self)
self._pkg = pkg
if not pkg.built:
# USE is lazy, but we want it to show up in self.keys().
self['USE'] = ''
+
self.update(metadata)
- for k, v in self.items():
- if k == 'INHERITED':
- if isinstance(v, basestring):
- v = frozenset(v.split())
- self._pkg.inherited = v
- elif k == 'SLOT':
- self._pkg.slot = v
- elif k == 'IUSE':
- self._pkg.iuse = self._pkg._iuse(
- v.split(), self._pkg.root_config.iuse_implicit)
- elif k == 'COUNTER':
- if isinstance(v, basestring):
- try:
- v = long(v.strip())
- except ValueError:
- v = 0
- self['COUNTER'] = str(v)
- self._pkg.counter = v
- elif k == '_mtime_':
- if isinstance(v, basestring):
- try:
- v = long(v.strip())
- except ValueError:
- v = 0
- self._pkg.mtime = v
- elif k in self._use_conditional_keys:
- try:
- use_reduce(paren_reduce(v), matchall=1)
- except portage.exception.InvalidDependString as e:
- self._pkg._invalid_metadata(k + ".syntax", "%s: %s" % (k, e))
def __getitem__(self, k):
- v = dict.__getitem__(self, k)
+ v = _PackageMetadataWrapperBase.__getitem__(self, k)
if k in self._use_conditional_keys:
if self._pkg.root_config.settings.local_config and '?' in v:
try:
return v
+ def __setitem__(self, k, v):
+ _PackageMetadataWrapperBase.__setitem__(self, k, v)
+ if k in self._wrapped_keys:
+ getattr(self, "_set_" + k.lower())(k, v)
+ elif k in self._use_conditional_keys:
+ try:
+ use_reduce(paren_reduce(v), matchall=1)
+ except portage.exception.InvalidDependString, e:
+ self._pkg._invalid_metadata(k + ".syntax", "%s: %s" % (k, e))
+
+ def _set_inherited(self, k, v):
+ if isinstance(v, basestring):
+ v = frozenset(v.split())
+ self._pkg.inherited = v
+
+ def _set_iuse(self, k, v):
+ self._pkg.iuse = self._pkg._iuse(
+ v.split(), self._pkg.root_config.iuse_implicit)
+
+ def _set_slot(self, k, v):
+ self._pkg.slot = v
+
+ def _set_counter(self, k, v):
+ if isinstance(v, basestring):
+ try:
+ v = long(v.strip())
+ except ValueError:
+ v = 0
+ self._pkg.counter = v
+
+ def _set__mtime_(self, k, v):
+ if isinstance(v, basestring):
+ try:
+ v = long(v.strip())
+ except ValueError:
+ v = 0
+ self._pkg.mtime = v
+
@property
def properties(self):
return self['PROPERTIES'].split()
tbz2_path = self.bintree.getname(mycpv)
if not os.path.exists(tbz2_path):
raise KeyError(mycpv)
- tbz2 = portage.xpak.tbz2(tbz2_path)
+ metadata_bytes = portage.xpak.tbz2(tbz2_path).get_data()
def getitem(k):
- v = tbz2.getfile(k)
+ v = metadata_bytes.get(_unicode_encode(k,
+ encoding=_encodings['repo.content'],
+ errors='backslashreplace'))
if v is not None:
v = _unicode_decode(v,
encoding=_encodings['repo.content'], errors='replace')
if st is not None:
# For invalid packages, other_cat could be None.
- other_cat = portage.xpak.tbz2(dest_path).getfile("CATEGORY")
+ other_cat = portage.xpak.tbz2(dest_path).getfile(
+ _unicode_encode("CATEGORY",
+ encoding=_encodings['repo.content']))
if other_cat:
+ other_cat = _unicode_decode(other_cat,
+ encoding=_encodings['repo.content'], errors='replace')
other_cat = other_cat.strip()
other_cpv = other_cat + "/" + mypkg
self._move_from_all(other_cpv)
noiselevel=-1)
self.invalids.append(myfile[:-5])
continue
- mytbz2 = portage.xpak.tbz2(full_path)
- # For invalid packages, mycat could be None.
- mycat = mytbz2.getfile("CATEGORY")
- mypf = mytbz2.getfile("PF")
- slot = mytbz2.getfile("SLOT")
+ metadata_bytes = portage.xpak.tbz2(full_path).get_data()
+ mycat = _unicode_decode(metadata_bytes.get(
+ _unicode_encode("CATEGORY",
+ encoding=_encodings['repo.content']), ""),
+ encoding=_encodings['repo.content'], errors='replace')
+ mypf = _unicode_decode(metadata_bytes.get(
+ _unicode_encode("PF",
+ encoding=_encodings['repo.content']), ""),
+ encoding=_encodings['repo.content'], errors='replace')
+ slot = _unicode_decode(metadata_bytes.get(
+ _unicode_encode("SLOT",
+ encoding=_encodings['repo.content']), ""),
+ encoding=_encodings['repo.content'], errors='replace')
mypkg = myfile[:-5]
if not mycat or not mypf or not slot:
#old-style or corrupt package