diff options
author | Alexander Bersenev <bay@hackerdom.ru> | 2014-02-17 17:57:05 +0600 |
---|---|---|
committer | Alexander Bersenev <bay@hackerdom.ru> | 2014-02-17 17:57:05 +0600 |
commit | 6563293d18daed502ccdb663f3c72b4bae5fe23a (patch) | |
tree | d0a7d53a7c137feb4073c963408829f88ea75c92 /portage_with_autodep/pym/portage/versions.py | |
parent | updated portage to 2.2.8-r1 (diff) | |
download | autodep-master.tar.gz autodep-master.tar.bz2 autodep-master.zip |
Diffstat (limited to 'portage_with_autodep/pym/portage/versions.py')
-rw-r--r-- | portage_with_autodep/pym/portage/versions.py | 115 |
1 files changed, 97 insertions, 18 deletions
diff --git a/portage_with_autodep/pym/portage/versions.py b/portage_with_autodep/pym/portage/versions.py index db14e99..3bfc388 100644 --- a/portage_with_autodep/pym/portage/versions.py +++ b/portage_with_autodep/pym/portage/versions.py @@ -1,7 +1,9 @@ # versions.py -- core Portage functionality -# Copyright 1998-2012 Gentoo Foundation +# Copyright 1998-2013 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 +from __future__ import unicode_literals + __all__ = [ 'best', 'catpkgsplit', 'catsplit', 'cpv_getkey', 'cpv_getversion', 'cpv_sort_key', 'pkgcmp', 'pkgsplit', @@ -23,7 +25,7 @@ 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.eapi import _get_eapi_attrs from portage.exception import InvalidData from portage.localization import _ @@ -31,6 +33,10 @@ _unknown_repo = "__unknown__" # \w is [a-zA-Z0-9_] +# PMS 3.1.3: A slot name may contain any of the characters [A-Za-z0-9+_.-]. +# It must not begin with a hyphen or a dot. +_slot = r'([\w+][\w+.-]*)' + # 2.1.1 A category name may contain any of the characters [A-Za-z0-9+_.-]. # It must not begin with a hyphen or a dot. _cat = r'[\w+][\w+.-]*' @@ -65,6 +71,42 @@ suffix_regexp = re.compile("^(alpha|beta|rc|pre|p)(\\d*)$") suffix_value = {"pre": -2, "p": 0, "alpha": -4, "beta": -3, "rc": -1} endversion_keys = ["pre", "p", "alpha", "beta", "rc"] +_slot_re_cache = {} + +def _get_slot_re(eapi_attrs): + cache_key = eapi_attrs.slot_operator + slot_re = _slot_re_cache.get(cache_key) + if slot_re is not None: + return slot_re + + if eapi_attrs.slot_operator: + slot_re = _slot + r'(/' + _slot + r')?' + else: + slot_re = _slot + + slot_re = re.compile('^' + slot_re + '$', re.VERBOSE | re.UNICODE) + + _slot_re_cache[cache_key] = slot_re + return slot_re + +_pv_re_cache = {} + +def _get_pv_re(eapi_attrs): + cache_key = eapi_attrs.dots_in_PN + pv_re = _pv_re_cache.get(cache_key) + if pv_re is not None: + return pv_re + + if eapi_attrs.dots_in_PN: + pv_re = _pv['dots_allowed_in_PN'] + else: + pv_re = _pv['dots_disallowed_in_PN'] + + pv_re = re.compile(r'^' + pv_re + r'$', re.VERBOSE | re.UNICODE) + + _pv_re_cache[cache_key] = pv_re + return pv_re + def ververify(myver, silent=1): if ver_regexp.match(myver): return 1 @@ -251,17 +293,6 @@ def pkgcmp(pkg1, pkg2): return None return vercmp("-".join(pkg1[1:]), "-".join(pkg2[1:])) -_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 _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 @@ -269,7 +300,7 @@ def _pkgsplit(mypkg, eapi=None): 1. None if input is invalid. 2. (pn, ver, rev) if input is pv """ - m = _get_pv_re(eapi).match(mypkg) + m = _get_pv_re(_get_eapi_attrs(eapi)).match(mypkg) if m is None: return None @@ -284,7 +315,7 @@ def _pkgsplit(mypkg, eapi=None): return (m.group('pn'), m.group('ver'), rev) -_cat_re = re.compile('^%s$' % _cat) +_cat_re = re.compile('^%s$' % _cat, re.UNICODE) _missing_cat = 'null' def catpkgsplit(mydata, silent=1, eapi=None): @@ -329,14 +360,25 @@ class _pkg_str(_unicode): manually convert them to a plain unicode object first. """ - def __new__(cls, cpv, slot=None, repo=None, eapi=None): + def __new__(cls, cpv, metadata=None, settings=None, eapi=None, + repo=None, slot=None): return _unicode.__new__(cls, cpv) - def __init__(self, cpv, slot=None, repo=None, eapi=None): + def __init__(self, cpv, metadata=None, settings=None, eapi=None, + repo=None, slot=None): if not isinstance(cpv, _unicode): # Avoid TypeError from _unicode.__init__ with PyPy. cpv = _unicode_decode(cpv) _unicode.__init__(cpv) + if metadata is not None: + self.__dict__['_metadata'] = metadata + slot = metadata.get('SLOT', slot) + repo = metadata.get('repository', repo) + eapi = metadata.get('EAPI', eapi) + if settings is not None: + self.__dict__['_settings'] = settings + if eapi is not None: + self.__dict__['eapi'] = eapi self.__dict__['cpv_split'] = catpkgsplit(cpv, eapi=eapi) if self.cpv_split is None: raise InvalidData(cpv) @@ -348,7 +390,25 @@ class _pkg_str(_unicode): # for match_from_list introspection self.__dict__['cpv'] = self if slot is not None: - self.__dict__['slot'] = slot + eapi_attrs = _get_eapi_attrs(eapi) + slot_match = _get_slot_re(eapi_attrs).match(slot) + if slot_match is None: + # Avoid an InvalidAtom exception when creating SLOT atoms + self.__dict__['slot'] = '0' + self.__dict__['sub_slot'] = '0' + self.__dict__['slot_invalid'] = slot + else: + if eapi_attrs.slot_operator: + slot_split = slot.split("/") + self.__dict__['slot'] = slot_split[0] + if len(slot_split) > 1: + self.__dict__['sub_slot'] = slot_split[1] + else: + self.__dict__['sub_slot'] = slot_split[0] + else: + self.__dict__['slot'] = slot + self.__dict__['sub_slot'] = slot + if repo is not None: repo = _gen_valid_repo(repo) if not repo: @@ -359,6 +419,25 @@ class _pkg_str(_unicode): raise AttributeError("_pkg_str instances are immutable", self.__class__, name, value) + @property + def stable(self): + try: + return self._stable + except AttributeError: + try: + metadata = self._metadata + settings = self._settings + except AttributeError: + raise AttributeError('stable') + if not settings.local_config: + # Since repoman uses different config instances for + # different profiles, our local instance does not + # refer to the correct profile. + raise AssertionError('invalid context') + stable = settings._isStable(self) + self.__dict__['_stable'] = stable + return stable + def pkgsplit(mypkg, silent=1, eapi=None): """ @param mypkg: either a pv or cpv |