From 077d96998e66a42e9def5b4bdd393f0751ecb573 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Wed, 25 Jun 2008 06:38:15 +0000 Subject: [PATCH] For the Package.metadata attribute, only implement the dict interface instead of actually inheriting from dict. This slightly decreases the memory footprint by defining __slots__ and storing items as object attributes. svn path=/main/trunk/; revision=10776 --- pym/_emerge/__init__.py | 162 ++++++++++++++++++++++++++-------------- pym/portage/__init__.py | 6 +- 2 files changed, 110 insertions(+), 58 deletions(-) diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index c387bfe05..9d0ca28f4 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -1285,7 +1285,7 @@ class Package(Task): def __init__(self, **kwargs): Task.__init__(self, **kwargs) self.root = self.root_config.root - self.metadata = self._metadata_wrapper(self, self.metadata) + self.metadata = _PackageMetadataWrapper(self, self.metadata) self.cp = portage.cpv_getkey(self.cpv) self.slot_atom = portage.dep.Atom("%s:%s" % (self.cp, self.slot)) self.category, self.pf = portage.catsplit(self.cpv) @@ -1332,60 +1332,6 @@ class Package(Task): chain((re.escape(x) for x in all), iuse_implicit))) return object.__getattribute__(self, name) - class _metadata_wrapper(dict): - """ - Detect metadata updates and synchronize Package attributes. - """ - _wrapped_keys = frozenset( - ["COUNTER", "INHERITED", "IUSE", "SLOT", "USE", "_mtime_"]) - - def __init__(self, pkg, metadata): - dict.__init__(self) - self._pkg = pkg - i = getattr(metadata, "iteritems", None) - if i is None: - i = metadata - else: - i = i() - for k, v in i: - self[k] = v - - def __setitem__(self, k, v): - dict.__setitem__(self, k, v) - if k in self._wrapped_keys: - getattr(self, "_set_" + k.lower())(k, v) - - 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_use(self, k, v): - self._pkg.use = self._pkg._use(v.split()) - - def _set_counter(self, k, v): - if isinstance(v, basestring): - try: - v = int(v.strip()) - except ValueError: - v = 0 - self._pkg.counter = v - - def _set__mtime_(self, k, v): - if isinstance(v, basestring): - try: - v = float(v.strip()) - except ValueError: - v = 0 - self._pkg.mtime = v - def _get_hash_key(self): hash_key = getattr(self, "_hash_key", None) if hash_key is None: @@ -1425,6 +1371,112 @@ class Package(Task): return True return False +class _PackageMetadataWrapper(object): + """ + Detect metadata updates and synchronize Package attributes. + """ + _keys = Package.metadata_keys + __slots__ = ("__weakref__", "_pkg") + tuple("_val_" + k for k in _keys) + _wrapped_keys = frozenset( + ["COUNTER", "INHERITED", "IUSE", "SLOT", "USE", "_mtime_"]) + + def __init__(self, pkg, metadata): + self._pkg = pkg + self.update(metadata) + + def __iter__(self): + for k, v in self.iteritems(): + yield k + + def __len__(self): + l = 0 + for i in self.iteritems(): + l += 1 + return l + + def keys(self): + return list(self) + + def iteritems(self): + for k in self._keys: + try: + yield (k, getattr(self, "_val_" + k)) + except AttributeError: + pass + + def items(self): + return list(self.iteritems()) + + def itervalues(self): + for k, v in self.itervalues(): + yield v + + def values(self): + return list(self.itervalues()) + + def __delitem__(self, k): + try: + delattr(self, "_val_" + k) + except AttributeError: + raise KeyError(k) + + def __setitem__(self, k, v): + setattr(self, "_val_" + k, v) + if k in self._wrapped_keys: + getattr(self, "_set_" + k.lower())(k, v) + + def update(self, d): + i = getattr(d, "iteritems", None) + if i is None: + i = d + else: + i = i() + for k, v in i: + self[k] = v + + def __getitem__(self, k): + try: + return getattr(self, "_val_" + k) + except AttributeError: + raise KeyError(k) + + def get(self, key, default=None): + try: + return self[key] + except KeyError: + return default + + 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_use(self, k, v): + self._pkg.use = self._pkg._use(v.split()) + + def _set_counter(self, k, v): + if isinstance(v, basestring): + try: + v = int(v.strip()) + except ValueError: + v = 0 + self._pkg.counter = v + + def _set__mtime_(self, k, v): + if isinstance(v, basestring): + try: + v = float(v.strip()) + except ValueError: + v = 0 + self._pkg.mtime = v + class DependencyArg(object): def __init__(self, arg=None, root_config=None): self.arg = arg diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 8d3fa56fd..cedbd2b8e 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -1940,7 +1940,7 @@ class config(object): pkginternaluse = "" iuse = "" if mydb: - if isinstance(mydb, dict): + if not hasattr(mydb, "aux_get"): slot = mydb["SLOT"] iuse = mydb["IUSE"] else: @@ -2414,7 +2414,7 @@ class config(object): if len(self.virtuals) == 0: self.getvirtuals() # Grab the virtuals this package provides and add them into the tree virtuals. - if isinstance(mydbapi, dict): + if not hasattr(mydbapi, "aux_get"): provides = mydbapi["PROVIDE"] else: provides = mydbapi.aux_get(mycpv, ["PROVIDE"])[0] @@ -2423,7 +2423,7 @@ class config(object): if isinstance(mydbapi, portdbapi): self.setcpv(mycpv, mydb=mydbapi) myuse = self["PORTAGE_USE"] - elif isinstance(mydbapi, dict): + elif not hasattr(mydbapi, "aux_get"): myuse = mydbapi["USE"] else: myuse = mydbapi.aux_get(mycpv, ["USE"])[0] -- 2.26.2