From: Fabian Groffen Date: Mon, 14 Sep 2009 07:53:17 +0000 (-0000) Subject: Merged from trunk -r14250:14256 X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=906993eee738ef94d7d364dae7483d47f3e56b54;p=portage.git Merged from trunk -r14250:14256 | 14251 | Simplify the _pkg regex and fix validation for some cases by | | zmedico | using the _version regex to match unwanted version-like | | | components which can not be at the end of a _pkg match. For | | | example isvalidatom('app-doc/php-docs-20071125-r2') now | | | correctly returns False. | | 14252 | Simplify isvalidatom() to simply use the Atom class. Thanks | | zmedico | to Marat Radchenko for the | | | suggestion. | | 14253 | Add more test cases. | | zmedico | | | 14254 | Use the Atom class to implement dep_getkey(), and fall back | | zmedico | to legacy code when necessary for backward compatibility. | | 14255 | Make isspecific() use the Atom class and fall back to legacy | | zmedico | code if the atom is invalid. Also, optimize called | | | isjustname() legacy code to only check the last 2 | | | components. | | 14256 | Make get_operator() use Atom, and remove unnecessary | | zmedico | reflection code from dep_getkey(). Thanks to Marat Radchenko | | | for suggestions. | svn path=/main/branches/prefix/; revision=14260 --- diff --git a/pym/portage/dep.py b/pym/portage/dep.py index e1f669970..929e31dbe 100644 --- a/pym/portage/dep.py +++ b/pym/portage/dep.py @@ -545,6 +545,21 @@ class Atom(object): m = _atom_re.match(s) if m is None: raise InvalidAtom(mypkg) + + # Package name must not end in pattern + # which appears to be a valid version. + if m.group('op') is not None: + if m.group(_atom_re.groupindex['op'] + 4) is not None: + raise InvalidAtom(mypkg) + elif m.group('star') is not None: + if m.group(_atom_re.groupindex['star'] + 3) is not None: + raise InvalidAtom(mypkg) + elif m.group('simple') is not None: + if m.group(_atom_re.groupindex['simple'] + 2) is not None: + raise InvalidAtom(mypkg) + else: + raise AssertionError(_("required group not found in atom: '%s'") % mypkg) + if m.group('op'): op = m.group(_atom_re.groupindex['op'] + 1) cpv = m.group(_atom_re.groupindex['op'] + 2) @@ -557,7 +572,7 @@ class Atom(object): op = None cpv = cp = m.group(_atom_re.groupindex['simple'] + 1) else: - raise AssertionError("required group not found in atom: '%s'" % s) + raise AssertionError(_("required group not found in atom: '%s'") % s) obj_setattr(self, "cp", cp) obj_setattr(self, "cpv", cpv) obj_setattr(self, "slot", m.group(_atom_re.groups - 1)) @@ -695,9 +710,13 @@ def get_operator(mydep): @return: The operator. One of: '~', '=', '>', '<', '=*', '>=', or '<=' """ - operator = getattr(mydep, "operator", False) - if operator is not False: - return operator + try: + return Atom(mydep).operator + except InvalidAtom: + pass + + # Fall back to legacy code for backward compatibility. + operator = None if mydep: mydep = remove_slot(mydep) if not mydep: @@ -865,15 +884,7 @@ _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+](?: - -? # All other 2-char are handled by next - |[\w+]*? # No hyphens - no problems - |[\w+-]+?(?: # String with a hyphen... - [A-Za-z+_-] # ... must end in nondigit - |[A-Za-z+_][\w+]+? # ... or in nondigit and then nonhyphens - ) -)''' +_pkg = r'[\w+][\w+-]*?' # 2.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. @@ -882,10 +893,9 @@ _optional_slot = '(?:' + _slot + ')?' _use = r'(\[.*\])?' _op = r'([=~]|[><]=?)' -_cp = '(' + _cat + '/' + _pkg + ')' +_cp = '(' + _cat + '/' + _pkg + '(-' + _version + ')?)' _cpv = '(' + _cp + '-' + _version + ')' -_cpv_re = re.compile('^' + _cpv + '$', re.VERBOSE) _atom_re = re.compile('^(?:' + '(?P' + _op + _cpv + ')|' + '(?P=' + _cpv + r'\*)|' + @@ -908,24 +918,10 @@ def isvalidatom(atom, allow_blockers=False): 1) False if the atom is invalid 2) True if the atom is valid """ - existing_atom = Atom._atoms.get(atom) - if existing_atom is not None: - atom = existing_atom - if isinstance(atom, Atom): - return allow_blockers or not atom.blocker - if len(atom) < 2: - return False - if allow_blockers and atom[0] == '!': - if atom[1] == '!': - atom = atom[2:] - else: - atom = atom[1:] - if _atom_re.match(atom) is None: - return False try: - use = dep_getusedeps(atom) - if use: - use = _use_dep(use) + atom = Atom(atom) + if not allow_blockers and atom.blocker: + return False return True except InvalidAtom: return False @@ -952,23 +948,20 @@ def isjustname(mypkg): except InvalidAtom: pass - myparts = mypkg.split('-') - for x in myparts: + for x in mypkg.split('-')[-2:]: if ververify(x): return False return True -iscache = {} - def isspecific(mypkg): """ - Checks to see if a package is in category/package-version or package-version format, - possibly returning a cached result. + Checks to see if a package is in =category/package-version or + package-version format. Example usage: >>> isspecific('media-libs/test') False - >>> isspecific('media-libs/test-3.0') + >>> isspecific('=media-libs/test-3.0') True @param mypkg: The package depstring to check against @@ -979,12 +972,12 @@ def isspecific(mypkg): 2) True if it is """ try: - return iscache[mypkg] - except KeyError: + return mypkg != Atom(mypkg).cp + except InvalidAtom: pass - retval = _cpv_re.match(mypkg) is not None - iscache[mypkg] = retval - return retval + + # Fall back to legacy code for backward compatibility. + return not isjustname(mypkg) def dep_getkey(mydep): """ @@ -999,9 +992,16 @@ def dep_getkey(mydep): @rtype: String @return: The package category/package-version """ - cp = getattr(mydep, "cp", None) - if cp is not None: - return cp + + try: + return Atom(mydep).cp + except InvalidAtom: + try: + return Atom('=' + mydep).cp + except InvalidAtom: + pass + + # Fall back to legacy code for backward compatibility. mydep = dep_getcpv(mydep) if mydep and isspecific(mydep): mysplit = catpkgsplit(mydep) diff --git a/pym/portage/tests/dep/test_isvalidatom.py b/pym/portage/tests/dep/test_isvalidatom.py index 7e9d8c23d..da91a8cfa 100644 --- a/pym/portage/tests/dep/test_isvalidatom.py +++ b/pym/portage/tests/dep/test_isvalidatom.py @@ -68,11 +68,20 @@ class IsValidAtom(TestCase): ( "~null/portage-2.1", True ), ( "=null/portage-2.1*", True ), ( "null/portage-2.1*", False ), + ( "app-doc/php-docs-20071125", False), + ( "app-doc/php-docs-20071125-r2", False), + ( "=foo/bar-1-r1-1-r1", False ), + ( "foo/-z-1", False ), # These are invalid because pkg name must not end in hyphen # followed by numbers + ( "=foo/bar-1-r1-1-r1", False ), ( "=foo/bar-123-1", False ), + ( "=foo/bar-123-1*", False ), + ( "foo/bar-123", False ), ( "=foo/bar-123-1-r1", False ), + ( "=foo/bar-123-1-r1*", False ), + ( "foo/bar-123-r1", False ), ( "foo/bar-1", False ), ( "=foo/bar--baz-1-r1", True ),