Add a _pkg_str class to cache catpkgsplit results
authorZac Medico <zmedico@gentoo.org>
Sat, 12 May 2012 09:25:39 +0000 (02:25 -0700)
committerZac Medico <zmedico@gentoo.org>
Sat, 12 May 2012 09:32:31 +0000 (02:32 -0700)
This will compensate for the removal of the catpkgsplit cache in commit
68888b0450b1967cb70673a5f06b04c167ef879c.

pym/_emerge/BlockerCache.py
pym/portage/dbapi/bintree.py
pym/portage/dbapi/porttree.py
pym/portage/dbapi/vartree.py
pym/portage/dep/__init__.py
pym/portage/versions.py

index 06598a44ec150bac9908a50dc3bc6f3070260312..3ec63ced5dd61b2ea727c176154b93ac5a879edd 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2012 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
 import errno
@@ -16,6 +16,9 @@ except ImportError:
 if sys.hexversion >= 0x3000000:
        basestring = str
        long = int
+       _unicode = str
+else:
+       _unicode = unicode
 
 class BlockerCache(portage.cache.mappings.MutableMapping):
        """This caches blockers of installed packages so that dep_check does not
@@ -159,7 +162,7 @@ class BlockerCache(portage.cache.mappings.MutableMapping):
                @param blocker_data: An object with counter and atoms attributes.
                @type blocker_data: BlockerData
                """
-               self._cache_data["blockers"][cpv] = \
+               self._cache_data["blockers"][_unicode(cpv)] = \
                        (blocker_data.counter, tuple(str(x) for x in blocker_data.atoms))
                self._modified.add(cpv)
 
index 810163d0fa14490447ac2b8e44cf8943c390acc0..52b85b88e13610ae27069d280cbc50b436af2eeb 100644 (file)
@@ -16,7 +16,7 @@ portage.proxy.lazyimport.lazyimport(globals(),
        'portage.util:atomic_ofstream,ensure_dirs,normalize_path,' + \
                'writemsg,writemsg_stdout',
        'portage.util.listdir:listdir',
-       'portage.versions:best,catpkgsplit,catsplit',
+       'portage.versions:best,catpkgsplit,catsplit,_pkg_str',
 )
 
 from portage.cache.mappings import slot_dict_class
@@ -236,7 +236,7 @@ def _pkgindex_cpv_map_latest_build(pkgindex):
                        if other_btime and (not btime or other_btime > btime):
                                continue
 
-               cpv_map[cpv] = d
+               cpv_map[_pkg_str(cpv)] = d
 
        return cpv_map
 
@@ -658,6 +658,7 @@ class binarytree(object):
                                                        if mycpv in pkg_paths:
                                                                # discard duplicates (All/ is preferred)
                                                                continue
+                                                       mycpv = _pkg_str(mycpv)
                                                        pkg_paths[mycpv] = mypath
                                                        # update the path if the package has been moved
                                                        oldpath = d.get("PATH")
@@ -733,6 +734,7 @@ class binarytree(object):
                                                        (mycpv, self.settings["PORTAGE_CONFIGROOT"]),
                                                        noiselevel=-1)
                                                continue
+                                       mycpv = _pkg_str(mycpv)
                                        pkg_paths[mycpv] = mypath
                                        self.dbapi.cpv_inject(mycpv)
                                        update_pkgindex = True
index f348a15295d70e5d01b88e07e87b2c8a2c0d58c1..663b62dc3f753011f37f7634b0647241f56ac954 100644 (file)
@@ -14,7 +14,7 @@ portage.proxy.lazyimport.lazyimport(globals(),
        'portage.package.ebuild.doebuild:doebuild',
        'portage.util:ensure_dirs,shlex_split,writemsg,writemsg_level',
        'portage.util.listdir:listdir',
-       'portage.versions:best,catpkgsplit,_pkgsplit@pkgsplit,ver_regexp',
+       'portage.versions:best,catpkgsplit,_pkgsplit@pkgsplit,ver_regexp,_pkg_str',
 )
 
 from portage.cache import volatile
@@ -708,7 +708,7 @@ class portdbapi(dbapi):
                                                writemsg(_("\nInvalid ebuild version: %s\n") % \
                                                        os.path.join(oroot, mycp, x), noiselevel=-1)
                                                continue
-                                       d[mysplit[0]+"/"+pf] = None
+                                       d[_pkg_str(mysplit[0]+"/"+pf)] = None
                if invalid_category and d:
                        writemsg(_("\n!!! '%s' has a category that is not listed in " \
                                "%setc/portage/categories\n") % \
index 158fc4a02b56ad922433cc8d1f394efaaa24371f..fe352c5f8c2ac01dec0fe5dcb874a5c83c7e3d41 100644 (file)
@@ -31,7 +31,7 @@ portage.proxy.lazyimport.lazyimport(globals(),
        'portage.util._dyn_libs.PreservedLibsRegistry:PreservedLibsRegistry',
        'portage.util._dyn_libs.LinkageMapELF:LinkageMapELF@LinkageMap',
        'portage.versions:best,catpkgsplit,catsplit,cpv_getkey,pkgcmp,' + \
-               '_pkgsplit@pkgsplit',
+               '_pkgsplit@pkgsplit,_pkg_str',
        'subprocess',
        'tarfile',
 )
@@ -87,6 +87,9 @@ except ImportError:
 if sys.hexversion >= 0x3000000:
        basestring = str
        long = int
+       _unicode = str
+else:
+       _unicode = unicode
 
 class vardbapi(dbapi):
 
@@ -386,7 +389,7 @@ class vardbapi(dbapi):
                                continue
                        if len(mysplit) > 1:
                                if ps[0] == mysplit[1]:
-                                       returnme.append(mysplit[0]+"/"+x)
+                                       returnme.append(_pkg_str(mysplit[0]+"/"+x))
                self._cpv_sort_ascending(returnme)
                if use_cache:
                        self.cpcache[mycp] = [mystat, returnme[:]]
@@ -680,7 +683,8 @@ class vardbapi(dbapi):
                                        cache_data.update(metadata)
                                for aux_key in cache_these:
                                        cache_data[aux_key] = mydata[aux_key]
-                               self._aux_cache["packages"][mycpv] = (mydir_mtime, cache_data)
+                               self._aux_cache["packages"][_unicode(mycpv)] = \
+                                       (mydir_mtime, cache_data)
                                self._aux_cache["modified"].add(mycpv)
 
                if _slot_re.match(mydata['SLOT']) is None:
@@ -1059,7 +1063,7 @@ class vardbapi(dbapi):
                                counter = int(counter)
                        except ValueError:
                                counter = 0
-                       return (cpv, counter, mtime)
+                       return (_unicode(cpv), counter, mtime)
 
        class _owners_db(object):
 
index 2e3444de5819442aeda65ecd14eff1588119eb02..de8d1c4d13ff2f34d02b96f3c8f2ab62b8da7d05 100644 (file)
@@ -43,7 +43,7 @@ from portage.eapi import eapi_has_slot_deps, eapi_has_src_uri_arrows, \
 from portage.exception import InvalidAtom, InvalidData, InvalidDependString
 from portage.localization import _
 from portage.versions import catpkgsplit, catsplit, \
-       pkgcmp, vercmp, ververify, _cp, _cpv
+       pkgcmp, vercmp, ververify, _cp, _cpv, _pkg_str
 import portage.cache.mappings
 
 if sys.hexversion >= 0x3000000:
@@ -1137,7 +1137,11 @@ class Atom(_atom_base):
                else:
                        raise AssertionError(_("required group not found in atom: '%s'") % self)
                self.__dict__['cp'] = cp
-               self.__dict__['cpv'] = cpv
+               try:
+                       self.__dict__['cpv'] = _pkg_str(cpv)
+               except InvalidData:
+                       # plain cp, wildcard, or something
+                       self.__dict__['cpv'] = cpv
                self.__dict__['repo'] = repo
                self.__dict__['slot'] = slot
                self.__dict__['operator'] = op
index e2761b53e2a0ea938772d201db1d3ac8914c982c..de2fe709ffd1be3d9ec063fdb76d28b7832e879e 100644 (file)
@@ -9,13 +9,21 @@ __all__ = [
 ]
 
 import re
+import sys
 import warnings
 
+if sys.hexversion < 0x3000000:
+       _unicode = unicode
+else:
+       _unicode = str
+
 import portage
 portage.proxy.lazyimport.lazyimport(globals(),
        'portage.util:cmp_sort_key'
 )
+from portage import _unicode_decode
 from portage.eapi import eapi_allows_dots_in_PN
+from portage.exception import InvalidData
 from portage.localization import _
 
 # \w is [a-zA-Z0-9_]
@@ -303,7 +311,10 @@ def catpkgsplit(mydata, silent=1, eapi=None):
        2.  If cat is not specificed in mydata, cat will be "null"
        3.  if rev does not exist it will be '-r0'
        """
-
+       try:
+               return mydata.cpv_split
+       except AttributeError:
+               pass
        mysplit = mydata.split('/', 1)
        p_split=None
        if len(mysplit)==1:
@@ -318,6 +329,33 @@ def catpkgsplit(mydata, silent=1, eapi=None):
        retval = (cat, p_split[0], p_split[1], p_split[2])
        return retval
 
+class _pkg_str(_unicode):
+       """
+       This class represents a cpv. It inherits from str (unicode in python2) and
+       has attributes that cache results for use by functions like catpkgsplit and
+       cpv_getkey which are called frequently (especially in match_from_list).
+       Instances are typically created in dbapi.cp_list() or the Atom contructor,
+       and propagate from there. Generally, code that pickles these objects will
+       manually convert them to a plain unicode object first.
+       """
+
+       def __new__(cls, cpv, eapi=None):
+               return _unicode.__new__(cls, cpv)
+
+       def __init__(self, cpv, eapi=None):
+               if not isinstance(cpv, _unicode):
+                       # Avoid TypeError from _unicode.__init__ with PyPy.
+                       cpv = _unicode_decode(cpv)
+               _unicode.__init__(cpv)
+               self.__dict__['cpv_split'] = catpkgsplit(cpv, eapi=eapi)
+               if self.cpv_split is None:
+                       raise InvalidData(cpv)
+               self.__dict__['cp'] = self.cpv_split[0] + '/' + self.cpv_split[1]
+
+       def __setattr__(self, name, value):
+               raise AttributeError("_pkg_str instances are immutable",
+                       self.__class__, name, value)
+
 def pkgsplit(mypkg, silent=1, eapi=None):
        """
        @param mypkg: either a pv or cpv
@@ -337,6 +375,10 @@ def pkgsplit(mypkg, silent=1, eapi=None):
 
 def cpv_getkey(mycpv, eapi=None):
        """Calls catpkgsplit on a cpv and returns only the cp."""
+       try:
+               return mycpv.cp
+       except AttributeError:
+               pass
        mysplit = catpkgsplit(mycpv, eapi=eapi)
        if mysplit is not None:
                return mysplit[0] + '/' + mysplit[1]