aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Bersenev <bay@hackerdom.ru>2014-02-17 17:55:51 +0600
committerAlexander Bersenev <bay@hackerdom.ru>2014-02-17 17:55:51 +0600
commit5a3f506c9ef1cfd78940b0509f10ef94b4434e29 (patch)
tree147c35a17a8bcd8ff467bb3063adab623da51fac /portage_with_autodep/pym/portage/versions.py
parentfixed a deadlock (diff)
downloadautodep-5a3f506c9ef1cfd78940b0509f10ef94b4434e29.tar.gz
autodep-5a3f506c9ef1cfd78940b0509f10ef94b4434e29.tar.bz2
autodep-5a3f506c9ef1cfd78940b0509f10ef94b4434e29.zip
updated portage to 2.2.8-r1
Diffstat (limited to 'portage_with_autodep/pym/portage/versions.py')
-rw-r--r--portage_with_autodep/pym/portage/versions.py187
1 files changed, 134 insertions, 53 deletions
diff --git a/portage_with_autodep/pym/portage/versions.py b/portage_with_autodep/pym/portage/versions.py
index f8691d1..db14e99 100644
--- a/portage_with_autodep/pym/portage/versions.py
+++ b/portage_with_autodep/pym/portage/versions.py
@@ -1,5 +1,5 @@
# versions.py -- core Portage functionality
-# Copyright 1998-2010 Gentoo Foundation
+# Copyright 1998-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
__all__ = [
@@ -9,14 +9,26 @@ __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'
+ 'portage.repository.config:_gen_valid_repo',
+ '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 _
+_unknown_repo = "__unknown__"
+
# \w is [a-zA-Z0-9_]
# 2.1.1 A category name may contain any of the characters [A-Za-z0-9+_.-].
@@ -26,15 +38,27 @@ _cat = r'[\w+][\w+.-]*'
# 2.1.2 A package name may contain any of the characters [A-Za-z0-9+_-].
# It must not begin with a hyphen,
# and must not end in a hyphen followed by one or more digits.
-_pkg = r'[\w+][\w+-]*?'
+_pkg = {
+ "dots_disallowed_in_PN": r'[\w+][\w+-]*?',
+ "dots_allowed_in_PN": r'[\w+][\w+.-]*?',
+}
_v = r'(cvs\.)?(\d+)((\.\d+)*)([a-z]?)((_(pre|p|beta|alpha|rc)\d*)*)'
_rev = r'\d+'
_vr = _v + '(-r(' + _rev + '))?'
-_cp = '(' + _cat + '/' + _pkg + '(-' + _vr + ')?)'
-_cpv = '(' + _cp + '-' + _vr + ')'
-_pv = '(?P<pn>' + _pkg + '(?P<pn_inval>-' + _vr + ')?)' + '-(?P<ver>' + _v + ')(-r(?P<rev>' + _rev + '))?'
+_cp = {
+ "dots_disallowed_in_PN": '(' + _cat + '/' + _pkg['dots_disallowed_in_PN'] + '(-' + _vr + ')?)',
+ "dots_allowed_in_PN": '(' + _cat + '/' + _pkg['dots_allowed_in_PN'] + '(-' + _vr + ')?)',
+}
+_cpv = {
+ "dots_disallowed_in_PN": '(' + _cp['dots_disallowed_in_PN'] + '-' + _vr + ')',
+ "dots_allowed_in_PN": '(' + _cp['dots_allowed_in_PN'] + '-' + _vr + ')',
+}
+_pv = {
+ "dots_disallowed_in_PN": '(?P<pn>' + _pkg['dots_disallowed_in_PN'] + '(?P<pn_inval>-' + _vr + ')?)' + '-(?P<ver>' + _v + ')(-r(?P<rev>' + _rev + '))?',
+ "dots_allowed_in_PN": '(?P<pn>' + _pkg['dots_allowed_in_PN'] + '(?P<pn_inval>-' + _vr + ')?)' + '-(?P<ver>' + _v + ')(-r(?P<rev>' + _rev + '))?',
+}
ver_regexp = re.compile("^" + _vr + "$")
suffix_regexp = re.compile("^(alpha|beta|rc|pre|p)(\\d*)$")
@@ -49,7 +73,6 @@ def ververify(myver, silent=1):
print(_("!!! syntax error in version: %s") % myver)
return 0
-vercmp_cache = {}
def vercmp(ver1, ver2, silent=1):
"""
Compare two versions
@@ -76,11 +99,7 @@ def vercmp(ver1, ver2, silent=1):
if ver1 == ver2:
return 0
- mykey=ver1+":"+ver2
- try:
- return vercmp_cache[mykey]
- except KeyError:
- pass
+
match1 = ver_regexp.match(ver1)
match2 = ver_regexp.match(ver2)
@@ -96,10 +115,8 @@ def vercmp(ver1, ver2, silent=1):
# shortcut for cvs ebuilds (new style)
if match1.group(1) and not match2.group(1):
- vercmp_cache[mykey] = 1
return 1
elif match2.group(1) and not match1.group(1):
- vercmp_cache[mykey] = -1
return -1
# building lists of the version parts before the suffix
@@ -153,16 +170,13 @@ def vercmp(ver1, ver2, silent=1):
for i in range(0, max(len(list1), len(list2))):
if len(list1) <= i:
- vercmp_cache[mykey] = -1
return -1
elif len(list2) <= i:
- vercmp_cache[mykey] = 1
return 1
elif list1[i] != list2[i]:
a = list1[i]
b = list2[i]
rval = (a > b) - (a < b)
- vercmp_cache[mykey] = rval
return rval
# main version is equal, so now compare the _suffix part
@@ -183,7 +197,6 @@ def vercmp(ver1, ver2, silent=1):
a = suffix_value[s1[0]]
b = suffix_value[s2[0]]
rval = (a > b) - (a < b)
- vercmp_cache[mykey] = rval
return rval
if s1[1] != s2[1]:
# it's possible that the s(1|2)[1] == ''
@@ -198,7 +211,6 @@ def vercmp(ver1, ver2, silent=1):
r2 = 0
rval = (r1 > r2) - (r1 < r2)
if rval:
- vercmp_cache[mykey] = rval
return rval
# the suffix part is equal to, so finally check the revision
@@ -211,7 +223,6 @@ def vercmp(ver1, ver2, silent=1):
else:
r2 = 0
rval = (r1 > r2) - (r1 < r2)
- vercmp_cache[mykey] = rval
return rval
def pkgcmp(pkg1, pkg2):
@@ -240,16 +251,25 @@ def pkgcmp(pkg1, pkg2):
return None
return vercmp("-".join(pkg1[1:]), "-".join(pkg2[1:]))
-_pv_re = re.compile('^' + _pv + '$', re.VERBOSE)
+_pv_re = {
+ "dots_disallowed_in_PN": re.compile('^' + _pv['dots_disallowed_in_PN'] + '$', re.VERBOSE),
+ "dots_allowed_in_PN": re.compile('^' + _pv['dots_allowed_in_PN'] + '$', re.VERBOSE),
+}
-def _pkgsplit(mypkg):
+def _get_pv_re(eapi):
+ if eapi is None or eapi_allows_dots_in_PN(eapi):
+ return _pv_re["dots_allowed_in_PN"]
+ else:
+ return _pv_re["dots_disallowed_in_PN"]
+
+def _pkgsplit(mypkg, eapi=None):
"""
@param mypkg: pv
@return:
1. None if input is invalid.
2. (pn, ver, rev) if input is pv
"""
- m = _pv_re.match(mypkg)
+ m = _get_pv_re(eapi).match(mypkg)
if m is None:
return None
@@ -266,8 +286,8 @@ def _pkgsplit(mypkg):
_cat_re = re.compile('^%s$' % _cat)
_missing_cat = 'null'
-catcache={}
-def catpkgsplit(mydata,silent=1):
+
+def catpkgsplit(mydata, silent=1, eapi=None):
"""
Takes a Category/Package-Version-Rev and returns a list of each.
@@ -281,28 +301,65 @@ def catpkgsplit(mydata,silent=1):
2. If cat is not specificed in mydata, cat will be "null"
3. if rev does not exist it will be '-r0'
"""
-
try:
- return catcache[mydata]
- except KeyError:
+ return mydata.cpv_split
+ except AttributeError:
pass
mysplit = mydata.split('/', 1)
p_split=None
if len(mysplit)==1:
cat = _missing_cat
- p_split = _pkgsplit(mydata)
+ p_split = _pkgsplit(mydata, eapi=eapi)
elif len(mysplit)==2:
cat = mysplit[0]
if _cat_re.match(cat) is not None:
- p_split = _pkgsplit(mysplit[1])
+ p_split = _pkgsplit(mysplit[1], eapi=eapi)
if not p_split:
- catcache[mydata]=None
return None
retval = (cat, p_split[0], p_split[1], p_split[2])
- catcache[mydata]=retval
return retval
-def pkgsplit(mypkg, silent=1):
+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, slot=None, repo=None, eapi=None):
+ return _unicode.__new__(cls, cpv)
+
+ def __init__(self, cpv, slot=None, repo=None, 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]
+ if self.cpv_split[-1] == "r0" and cpv[-3:] != "-r0":
+ self.__dict__['version'] = "-".join(self.cpv_split[2:-1])
+ else:
+ self.__dict__['version'] = "-".join(self.cpv_split[2:])
+ # for match_from_list introspection
+ self.__dict__['cpv'] = self
+ if slot is not None:
+ self.__dict__['slot'] = slot
+ if repo is not None:
+ repo = _gen_valid_repo(repo)
+ if not repo:
+ repo = _unknown_repo
+ self.__dict__['repo'] = repo
+
+ 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
@return:
@@ -310,7 +367,7 @@ def pkgsplit(mypkg, silent=1):
2. (pn, ver, rev) if input is pv
3. (cp, ver, rev) if input is a cpv
"""
- catpsplit = catpkgsplit(mypkg)
+ catpsplit = catpkgsplit(mypkg, eapi=eapi)
if catpsplit is None:
return None
cat, pn, ver, rev = catpsplit
@@ -319,9 +376,13 @@ def pkgsplit(mypkg, silent=1):
else:
return (cat + '/' + pn, ver, rev)
-def cpv_getkey(mycpv):
+def cpv_getkey(mycpv, eapi=None):
"""Calls catpkgsplit on a cpv and returns only the cp."""
- mysplit = catpkgsplit(mycpv)
+ try:
+ return mycpv.cp
+ except AttributeError:
+ pass
+ mysplit = catpkgsplit(mycpv, eapi=eapi)
if mysplit is not None:
return mysplit[0] + '/' + mysplit[1]
@@ -330,7 +391,7 @@ def cpv_getkey(mycpv):
DeprecationWarning, stacklevel=2)
myslash = mycpv.split("/", 1)
- mysplit = _pkgsplit(myslash[-1])
+ mysplit = _pkgsplit(myslash[-1], eapi=eapi)
if mysplit is None:
return None
mylen = len(myslash)
@@ -339,14 +400,18 @@ def cpv_getkey(mycpv):
else:
return mysplit[0]
-def cpv_getversion(mycpv):
+def cpv_getversion(mycpv, eapi=None):
"""Returns the v (including revision) from an cpv."""
- cp = cpv_getkey(mycpv)
+ try:
+ return mycpv.version
+ except AttributeError:
+ pass
+ cp = cpv_getkey(mycpv, eapi=eapi)
if cp is None:
return None
return mycpv[len(cp+"-"):]
-def cpv_sort_key():
+def cpv_sort_key(eapi=None):
"""
Create an object for sorting cpvs, to be used as the 'key' parameter
in places like list.sort() or sorted(). This calls catpkgsplit() once for
@@ -365,39 +430,55 @@ def cpv_sort_key():
split1 = split_cache.get(cpv1, False)
if split1 is False:
- split1 = catpkgsplit(cpv1)
- if split1 is not None:
- split1 = (split1[:2], '-'.join(split1[2:]))
+ split1 = None
+ try:
+ split1 = cpv1.cpv
+ except AttributeError:
+ try:
+ split1 = _pkg_str(cpv1, eapi=eapi)
+ except InvalidData:
+ pass
split_cache[cpv1] = split1
split2 = split_cache.get(cpv2, False)
if split2 is False:
- split2 = catpkgsplit(cpv2)
- if split2 is not None:
- split2 = (split2[:2], '-'.join(split2[2:]))
+ split2 = None
+ try:
+ split2 = cpv2.cpv
+ except AttributeError:
+ try:
+ split2 = _pkg_str(cpv2, eapi=eapi)
+ except InvalidData:
+ pass
split_cache[cpv2] = split2
- if split1 is None or split2 is None or split1[0] != split2[0]:
+ if split1 is None or split2 is None or split1.cp != split2.cp:
return (cpv1 > cpv2) - (cpv1 < cpv2)
- return vercmp(split1[1], split2[1])
+ return vercmp(split1.version, split2.version)
return cmp_sort_key(cmp_cpv)
def catsplit(mydep):
return mydep.split("/", 1)
-def best(mymatches):
+def best(mymatches, eapi=None):
"""Accepts None arguments; assumes matches are valid."""
if not mymatches:
return ""
if len(mymatches) == 1:
return mymatches[0]
bestmatch = mymatches[0]
- p2 = catpkgsplit(bestmatch)[1:]
+ try:
+ v2 = bestmatch.version
+ except AttributeError:
+ v2 = _pkg_str(bestmatch, eapi=eapi).version
for x in mymatches[1:]:
- p1 = catpkgsplit(x)[1:]
- if pkgcmp(p1, p2) > 0:
+ try:
+ v1 = x.version
+ except AttributeError:
+ v1 = _pkg_str(x, eapi=eapi).version
+ if vercmp(v1, v2) > 0:
bestmatch = x
- p2 = catpkgsplit(bestmatch)[1:]
+ v2 = v1
return bestmatch