else:
if need_bracket or "(" in token or ")" in token or "|" in token or \
(need_simple_token and "/" in token):
- raise portage.exception.InvalidDependString(
- _("malformed syntax: '%s'") % depstr)
+ if not (need_bracket or "|" in token or (need_simple_token and "/" in token)):
+ #We have '(' and/or ')' in token. Make sure it's not a use dep default
+ tmp = token.replace("(+)", "").replace("(-)", "")
+ if "(" in tmp or ")" in tmp:
+ raise portage.exception.InvalidDependString(
+ _("malformed syntax: '%s'") % depstr)
+ else:
+ raise portage.exception.InvalidDependString(
+ _("malformed syntax: '%s'") % depstr)
if token[-1] == "?":
need_bracket = True
class _use_dep(object):
- __slots__ = ("__weakref__", "conditional",
+ __slots__ = ("__weakref__", "conditional", "missing_enabled", "missing_disabled",
"disabled", "enabled", "tokens", "required")
_conditionals_class = portage.cache.mappings.slot_dict_class(
("disabled", "enabled", "equal", "not_equal"), prefix="")
- _valid_use_re = re.compile(r'^[^-?!=][^?!=]*$')
+ _valid_use_re = re.compile(r'^[A-Za-z0-9][A-Za-z0-9+_@-]*$')
def __init__(self, use):
enabled_flags = []
disabled_flags = []
+ missing_enabled = []
+ missing_disabled = []
+ no_default = []
+
conditional = self._conditionals_class()
for k in conditional.allowed_keys:
conditional[k] = []
for x in use:
last_char = x[-1:]
first_char = x[:1]
+ flag = x
+ default = ""
+ if last_char in ("?", "="):
+ flag = flag[:-1]
+ if first_char in ("-", "!"):
+ flag = flag[1:]
+
+ if flag[-3:] in ("(+)", "(-)"):
+ default = flag[-3:]
+ flag = flag[:-3]
if "?" == last_char:
if "!" == first_char:
conditional.disabled.append(
- self._validate_flag(x, x[1:-1]))
+ self._validate_flag(x, flag))
elif first_char in ("-", "=", "?"):
raise InvalidAtom(_("Invalid use dep: '%s'") % (x,))
else:
conditional.enabled.append(
- self._validate_flag(x, x[:-1]))
+ self._validate_flag(x, flag))
elif "=" == last_char:
if "!" == first_char:
conditional.not_equal.append(
- self._validate_flag(x, x[1:-1]))
+ self._validate_flag(x, flag))
elif first_char in ("-", "=", "?"):
raise InvalidAtom(_("Invalid use dep: '%s'") % (x,))
else:
conditional.equal.append(
- self._validate_flag(x, x[:-1]))
+ self._validate_flag(x, flag))
elif last_char in ("!", "-"):
raise InvalidAtom(_("Invalid use dep: '%s'") % (x,))
else:
if "-" == first_char:
- disabled_flags.append(self._validate_flag(x, x[1:]))
+ disabled_flags.append(self._validate_flag(x, flag))
elif first_char in ("!", "=", "?"):
raise InvalidAtom(_("Invalid use dep: '%s'") % (x,))
else:
- enabled_flags.append(self._validate_flag(x, x))
+ enabled_flags.append(self._validate_flag(x, flag))
+
+ if default:
+ if default == "(+)":
+ if flag in missing_disabled or flag in no_default:
+ raise InvalidAtom(_("Invalid use dep: '%s'") % (x,))
+ missing_enabled.append(flag)
+ else:
+ if flag in missing_enabled or flag in no_default:
+ raise InvalidAtom(_("Invalid use dep: '%s'") % (x,))
+ missing_disabled.append(flag)
+ else:
+ if flag in missing_enabled or flag in missing_disabled:
+ raise InvalidAtom(_("Invalid use dep: '%s'") % (x,))
+ no_default.append(flag)
self.tokens = use
if not isinstance(self.tokens, tuple):
self.enabled = frozenset(enabled_flags)
self.disabled = frozenset(disabled_flags)
+ self.missing_enabled = frozenset(missing_enabled)
+ self.missing_disabled = frozenset(missing_disabled)
self.conditional = None
for v in conditional.values():
def __repr__(self):
return "portage.dep._use_dep(%s)" % repr(self.tokens)
+
+ def _append_use_default(self, output, flag):
+ default = None
+ if flag in self.missing_enabled:
+ default = "(+)"
+ elif flag in self.missing_disabled:
+ default = "(-)"
+
+ if not default:
+ return output
+
+ if output[-1] in ("=", "?"):
+ return output[:-1] + default + output[-1]
+ else:
+ return output + default
+
def evaluate_conditionals(self, use):
"""
Create a new instance with conditionals evaluated.
tokens = []
conditional = self.conditional
- tokens.extend(self.enabled)
- tokens.extend("-" + x for x in self.disabled)
- tokens.extend(x for x in conditional.enabled if x in use)
- tokens.extend("-" + x for x in conditional.disabled if x not in use)
+ tokens.extend(self._append_use_default(x, x) for x in self.enabled)
+ tokens.extend(self._append_use_default("-" + x, x) for x in self.disabled)
+ tokens.extend(self._append_use_default(x, x) for x in conditional.enabled if x in use)
+ tokens.extend(self._append_use_default("-" + x, x) for x in conditional.disabled if x not in use)
- tokens.extend(x for x in conditional.equal if x in use)
- tokens.extend("-" + x for x in conditional.equal if x not in use)
- tokens.extend("-" + x for x in conditional.not_equal if x in use)
- tokens.extend(x for x in conditional.not_equal if x not in use)
+ tokens.extend(self._append_use_default(x, x) for x in conditional.equal if x in use)
+ tokens.extend(self._append_use_default("-" + x, x) for x in conditional.equal if x not in use)
+ tokens.extend(self._append_use_default("-" + x, x) for x in conditional.not_equal if x in use)
+ tokens.extend(self._append_use_default(x, x) for x in conditional.not_equal if x not in use)
return _use_dep(tokens)
- def violated_conditionals(self, other_use, parent_use=None):
+ def violated_conditionals(self, other_use, iuse, parent_use=None):
"""
Create a new instance with satisfied use deps removed.
"""
tokens = []
conditional = self.conditional
- tokens.extend(x for x in self.enabled if x not in other_use)
- tokens.extend("-" + x for x in self.disabled if x in other_use)
- if conditional:
- if parent_use is None:
- raise InvalidAtom("violated_conditionals needs 'parent_use'" + \
- " parameter for conditional flags.")
- tokens.extend(x + "?" for x in conditional.enabled if x in parent_use and not x in other_use)
- tokens.extend("!" + x + "?" for x in conditional.disabled if x not in parent_use and x in other_use)
- tokens.extend(x + "=" for x in conditional.equal if x in parent_use and x not in other_use)
- tokens.extend(x + "=" for x in conditional.equal if x not in parent_use and x in other_use)
- tokens.extend("!" + x + "=" for x in conditional.not_equal if x in parent_use and x in other_use)
- tokens.extend("!" + x + "=" for x in conditional.not_equal if x not in parent_use and x not in other_use)
+
+ for x in self.enabled:
+ if x not in other_use:
+ if x in iuse:
+ tokens.append(self._append_use_default(x, x))
+ else:
+ if x in self.missing_disabled:
+ tokens.append(self._append_use_default(x, x))
+
+ for x in self.disabled:
+ if x not in other_use:
+ if x not in iuse:
+ if x in self.missing_enabled:
+ tokens.append(self._append_use_default("-" + x, x))
+ else:
+ tokens.append(self._append_use_default("-" + x, x))
+
+ if not conditional:
+ return _use_dep(tokens)
+
+ if parent_use is None:
+ raise InvalidAtom("violated_conditionals needs 'parent_use'" + \
+ " parameter for conditional flags.")
+
+ for x in conditional.enabled:
+ if x not in parent_use:
+ continue
+
+ if x not in other_use:
+ if x in iuse:
+ tokens.append(self._append_use_default(x + "?", x))
+ else:
+ if x in self.missing_disabled:
+ tokens.append(self._append_use_default(x + "?", x))
+
+ for x in conditional.disabled:
+ if x in parent_use:
+ continue
+
+ if x not in other_use:
+ if x not in iuse:
+ if x in self.missing_enabled:
+ tokens.append(self._append_use_default("!" + x + "?", x))
+ else:
+ tokens.append(self._append_use_default("!" + x + "?", x))
+
+ for x in conditional.equal:
+ if x not in parent_use:
+ continue
+
+ if x not in other_use:
+ if x in iuse:
+ tokens.append(self._append_use_default(x + "=", x))
+ else:
+ if x in self.missing_disabled:
+ tokens.append(self._append_use_default(x + "=", x))
+
+ for x in conditional.equal:
+ if x in parent_use:
+ continue
+
+ if x not in other_use:
+ if x not in iuse:
+ if x in self.missing_enabled:
+ tokens.append(self._append_use_default(x + "=", x))
+ else:
+ tokens.append(self._append_use_default(x + "=", x))
+
+ for x in conditional.not_equal:
+ if x in parent_use:
+ continue
+
+ if x not in other_use:
+ if x in iuse:
+ tokens.append(self._append_use_default("!" + x + "=", x))
+ else:
+ if x in self.missing_disabled:
+ tokens.append(self._append_use_default("!" + x + "=", x))
+
+ for x in conditional.not_equal:
+ if x not in parent_use:
+ continue
+
+ if x not in other_use:
+ if x not in iuse:
+ if x in self.missing_enabled:
+ tokens.append(self._append_use_default("!" + x + "=", x))
+ else:
+ tokens.append(self._append_use_default("!" + x + "=", x))
return _use_dep(tokens)
tokens = []
conditional = self.conditional
- tokens.extend(self.enabled)
- tokens.extend("-" + x for x in self.disabled)
- tokens.extend(x for x in conditional.enabled if x not in use_mask)
- tokens.extend("-" + x for x in conditional.disabled if x not in use_force)
+ tokens.extend(self._append_use_default(x, x) for x in self.enabled)
+ tokens.extend(self._append_use_default("-" + x, x) for x in self.disabled)
+ tokens.extend(self._append_use_default(x, x) for x in conditional.enabled if x not in use_mask)
+ tokens.extend(self._append_use_default("-" + x, x) for x in conditional.disabled if x not in use_force)
- tokens.extend(x for x in conditional.equal if x not in use_mask)
- tokens.extend("-" + x for x in conditional.equal if x not in use_force)
- tokens.extend("-" + x for x in conditional.not_equal if x not in use_mask)
- tokens.extend(x for x in conditional.not_equal if x not in use_force)
+ tokens.extend(self._append_use_default(x, x) for x in conditional.equal if x not in use_mask)
+ tokens.extend(self._append_use_default("-" + x, x) for x in conditional.equal if x not in use_force)
+ tokens.extend(self._append_use_default("-" + x, x) for x in conditional.not_equal if x not in use_mask)
+ tokens.extend(self._append_use_default(x, x) for x in conditional.not_equal if x not in use_force)
return _use_dep(tokens)
atom += str(self.use.evaluate_conditionals(use))
return Atom(atom, unevaluated_atom=self)
- def violated_conditionals(self, other_use, parent_use=None):
+ def violated_conditionals(self, other_use, iuse, parent_use=None):
"""
Create an atom instance with any USE conditional removed, that is
satisfied by other_use.
atom = remove_slot(self)
if self.slot:
atom += ":%s" % self.slot
- atom += str(self.use.violated_conditionals(other_use, parent_use))
+ atom += str(self.use.violated_conditionals(other_use, iuse, parent_use))
return Atom(atom, unevaluated_atom=self)
def _eval_qa_conditionals(self, use_mask, use_force):
use = getattr(x, "use", None)
if use is not None:
is_valid_flag = x.iuse.is_valid_flag
- missing_iuse = False
- for y in mydep.use.required:
- if not is_valid_flag(y):
- missing_iuse = True
- break
- if missing_iuse:
- continue
- if mydep.use.enabled.difference(use.enabled):
+ use_config_mismatch = False
+
+ for y in mydep.use.enabled:
+ if is_valid_flag(y):
+ if y not in use.enabled:
+ use_config_mismatch = True
+ break
+ else:
+ if y not in mydep.use.missing_enabled:
+ use_config_mismatch = True
+ break
+
+ if use_config_mismatch:
continue
- if mydep.use.disabled.intersection(use.enabled):
+
+ for y in mydep.use.disabled:
+ if is_valid_flag(y):
+ if y in use.enabled:
+ use_config_mismatch = True
+ break
+ else:
+ if y not in mydep.use.missing_disabled:
+ use_config_mismatch = True
+ break
+
+ if use_config_mismatch:
continue
- mylist.append(x)
+ mylist.append(x)
return mylist
def check_required_use(required_use, use, iuse):
-# test_isvalidatom.py -- Portage Unit Testing Functionality
-# Copyright 2006 Gentoo Foundation
+# Copyright 2006, 2010 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
from portage.tests import TestCase
from portage.exception import InvalidAtom
class TestAtom(TestCase):
- """ A simple testcase for isvalidatom
- """
def testAtom(self):
- tests = [
- ( "=sys-apps/portage-2.1-r1:0[doc,a=,!b=,c?,!d?,-e]",
+ tests = (
+ ( "=sys-apps/portage-2.1-r1:0[doc,a=,!b=,c?,!d?,-e]",
('=', 'sys-apps/portage', '2.1-r1', '0', '[doc,a=,!b=,c?,!d?,-e]'), False ),
- ( "=sys-apps/portage-2.1-r1*:0[doc]",
+ ( "=sys-apps/portage-2.1-r1*:0[doc]",
('=*', 'sys-apps/portage', '2.1-r1', '0', '[doc]'), False ),
- ( "sys-apps/portage:0[doc]",
+ ( "sys-apps/portage:0[doc]",
(None, 'sys-apps/portage', None, '0', '[doc]'), False ),
- ( "sys-apps/portage:0[doc]",
+ ( "sys-apps/portage:0[doc]",
(None, 'sys-apps/portage', None, '0', '[doc]'), False ),
- ( "*/*",
+ ( "*/*",
(None, '*/*', None, None, None), True ),
- ( "sys-apps/*",
+ ( "sys-apps/*",
(None, 'sys-apps/*', None, None, None), True ),
- ( "*/portage",
+ ( "*/portage",
(None, '*/portage', None, None, None), True ),
- ( "s*s-*/portage:1",
+ ( "s*s-*/portage:1",
(None, 's*s-*/portage', None, '1', None), True ),
- ( "*/po*ge:2",
+ ( "*/po*ge:2",
(None, '*/po*ge', None, '2', None), True ),
- ( "!dev-libs/A",
+ ( "!dev-libs/A",
(None, 'dev-libs/A', None, None, None), True ),
- ( "!!dev-libs/A",
+ ( "!!dev-libs/A",
(None, 'dev-libs/A', None, None, None), True ),
- ]
+ ( "!!dev-libs/A",
+ (None, 'dev-libs/A', None, None, None), True ),
+ ( "dev-libs/A[foo(+)]",
+ (None, 'dev-libs/A', None, None, "[foo(+)]"), True ),
+ ( "dev-libs/A[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]",
+ (None, 'dev-libs/A', None, None, "[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]"), True ),
+ ( "dev-libs/A:2[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]",
+ (None, 'dev-libs/A', None, "2", "[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]"), True ),
+ )
- tests_xfail = [
+ tests_xfail = (
( Atom("sys-apps/portage"), False ),
( "cat/pkg[a!]", False ),
( "cat/pkg[a-]", False ),
( "*/portage", False ),
( "*/**", True ),
( "*/portage[use]", True ),
- ( "*/portage:slot", True )
- ]
+ ( "cat/pkg[a()]", False ),
+ ( "cat/pkg[a(]", False ),
+ ( "cat/pkg[a)]", False ),
+ ( "cat/pkg[a(,b]", False ),
+ ( "cat/pkg[a),b]", False ),
+ ( "cat/pkg[a(*)]", False ),
+ ( "cat/pkg[a(*)]", True ),
+ ( "cat/pkg[a(+-)]", False ),
+ ( "cat/pkg[a()]", False ),
+ ( "cat/pkg[(+)a]", False ),
+ ( "cat/pkg[a=(+)]", False ),
+ ( "cat/pkg[!(+)a=]", False ),
+ ( "cat/pkg[!a=(+)]", False ),
+ ( "cat/pkg[a?(+)]", False ),
+ ( "cat/pkg[!a?(+)]", False ),
+ ( "cat/pkg[!(+)a?]", False ),
+ ( "cat/pkg[-(+)a]", False ),
+ ( "cat/pkg[a(+),-a]", False ),
+ ( "cat/pkg[a(-),-a]", False ),
+ ( "cat/pkg[-a,a(+)]", False ),
+ ( "cat/pkg[-a,a(-)]", False ),
+ ( "cat/pkg[-a(+),a(-)]", False ),
+ ( "cat/pkg[-a(-),a(+)]", False ),
+ )
for atom, parts, allow_wildcard in tests:
a = Atom(atom, allow_wildcard=allow_wildcard)
op, cp, ver, slot, use = parts
self.assertEqual( op, a.operator,
- msg="Atom('%s').operator == '%s'" % ( atom, a.operator ) )
+ msg="Atom('%s').operator = %s == '%s'" % ( atom, a.operator, op ) )
self.assertEqual( cp, a.cp,
- msg="Atom('%s').cp == '%s'" % ( atom, a.cp ) )
+ msg="Atom('%s').cp = %s == '%s'" % ( atom, a.cp, cp ) )
if ver is not None:
cpv = "%s-%s" % (cp, ver)
else:
cpv = cp
self.assertEqual( cpv, a.cpv,
- msg="Atom('%s').cpv == '%s'" % ( atom, a.cpv ) )
+ msg="Atom('%s').cpv = %s == '%s'" % ( atom, a.cpv, cpv ) )
self.assertEqual( slot, a.slot,
- msg="Atom('%s').slot == '%s'" % ( atom, a.slot ) )
+ msg="Atom('%s').slot = %s == '%s'" % ( atom, a.slot, slot ) )
if a.use:
- expected_use = str(a.use)
+ returned_use = str(a.use)
else:
- expected_use = None
- self.assertEqual( use, expected_use,
- msg="Atom('%s').use == '%s'" % ( atom, a.use ) )
+ returned_use = None
+ self.assertEqual( use, returned_use,
+ msg="Atom('%s').use = %s == '%s'" % ( atom, returned_use, use ) )
for atom, allow_wildcard in tests_xfail:
- self.assertRaisesMsg(atom, (InvalidAtom, TypeError), Atom, atom)
+ self.assertRaisesMsg(atom, (InvalidAtom, TypeError), Atom, atom, allow_wildcard=allow_wildcard)
+
+ def test_intersects(self):
+ test_cases = (
+ ("dev-libs/A", "dev-libs/A", True),
+ ("dev-libs/A", "dev-libs/B", False),
+ ("dev-libs/A", "sci-libs/A", False),
+ ("dev-libs/A[foo]", "sci-libs/A[bar]", False),
+ ("dev-libs/A[foo(+)]", "sci-libs/A[foo(-)]", False),
+ ("=dev-libs/A-1", "=dev-libs/A-1-r1", False),
+ ("~dev-libs/A-1", "=dev-libs/A-1", False),
+ ("=dev-libs/A-1:1", "=dev-libs/A-1", True),
+ ("=dev-libs/A-1:1", "=dev-libs/A-1:1", True),
+ ("=dev-libs/A-1:1", "=dev-libs/A-1:2", False),
+ )
+
+ for atom, other, expected_result in test_cases:
+ self.assertEqual(Atom(atom).intersects(Atom(other)), expected_result, \
+ "%s and %s should intersect: %s" % (atom, other, expected_result))
def test_violated_conditionals(self):
test_cases = (
- ("dev-libs/A", ["foo"], None, "dev-libs/A"),
- ("dev-libs/A[foo]", [], None, "dev-libs/A[foo]"),
- ("dev-libs/A[foo]", ["foo"], None, "dev-libs/A"),
- ("dev-libs/A[foo]", [], [], "dev-libs/A[foo]"),
- ("dev-libs/A[foo]", ["foo"], [], "dev-libs/A"),
+ ("dev-libs/A", ["foo"], ["foo"], None, "dev-libs/A"),
+ ("dev-libs/A[foo]", [], ["foo"], None, "dev-libs/A[foo]"),
+ ("dev-libs/A[foo]", ["foo"], ["foo"], None, "dev-libs/A"),
+ ("dev-libs/A[foo]", [], ["foo"], [], "dev-libs/A[foo]"),
+ ("dev-libs/A[foo]", ["foo"], ["foo"], [], "dev-libs/A"),
- ("dev-libs/A:0[foo]", ["foo"], [], "dev-libs/A:0"),
+ ("dev-libs/A:0[foo]", ["foo"], ["foo"], [], "dev-libs/A:0"),
- ("dev-libs/A[foo,-bar]", [], None, "dev-libs/A[foo]"),
- ("dev-libs/A[-foo,bar]", [], None, "dev-libs/A[bar]"),
+ ("dev-libs/A[foo,-bar]", [], ["foo", "bar"], None, "dev-libs/A[foo]"),
+ ("dev-libs/A[-foo,bar]", [], ["foo", "bar"], None, "dev-libs/A[bar]"),
- ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", [], [], "dev-libs/A[a,!c=]"),
-
- ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["a"], [], "dev-libs/A[!c=]"),
- ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["b"], [], "dev-libs/A[a,b=,!c=]"),
- ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["c"], [], "dev-libs/A[a]"),
- ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["d"], [], "dev-libs/A[a,!c=]"),
- ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["e"], [], "dev-libs/A[a,!e?,!c=]"),
- ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["f"], [], "dev-libs/A[a,-f,!c=]"),
-
- ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["a"], ["a"], "dev-libs/A[!c=]"),
- ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["b"], ["b"], "dev-libs/A[a,!c=]"),
- ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["c"], ["c"], "dev-libs/A[a,!c=]"),
- ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["d"], ["d"], "dev-libs/A[a,!c=]"),
- ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["e"], ["e"], "dev-libs/A[a,!c=]"),
- ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["f"], ["f"], "dev-libs/A[a,-f,!c=]"),
+ ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", [], ["a", "b", "c", "d", "e", "f"], [], "dev-libs/A[a,!c=]"),
+
+ ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["a"], ["a", "b", "c", "d", "e", "f"], [], "dev-libs/A[!c=]"),
+ ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["b"], ["a", "b", "c", "d", "e", "f"], [], "dev-libs/A[a,b=,!c=]"),
+ ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["c"], ["a", "b", "c", "d", "e", "f"], [], "dev-libs/A[a]"),
+ ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["d"], ["a", "b", "c", "d", "e", "f"], [], "dev-libs/A[a,!c=]"),
+ ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["e"], ["a", "b", "c", "d", "e", "f"], [], "dev-libs/A[a,!e?,!c=]"),
+ ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["f"], ["a", "b", "c", "d", "e", "f"], [], "dev-libs/A[a,-f,!c=]"),
+
+ ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["a"], ["a", "b", "c", "d", "e", "f"], ["a"], "dev-libs/A[!c=]"),
+ ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["b"], ["a", "b", "c", "d", "e", "f"], ["b"], "dev-libs/A[a,!c=]"),
+ ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["c"], ["a", "b", "c", "d", "e", "f"], ["c"], "dev-libs/A[a,!c=]"),
+ ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["d"], ["a", "b", "c", "d", "e", "f"], ["d"], "dev-libs/A[a,!c=]"),
+ ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["e"], ["a", "b", "c", "d", "e", "f"], ["e"], "dev-libs/A[a,!c=]"),
+ ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["f"], ["a", "b", "c", "d", "e", "f"], ["f"], "dev-libs/A[a,-f,!c=]"),
+
+ ("dev-libs/A[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]", ["a"], ["a", "b", "c", "d", "e", "f"], ["a"], "dev-libs/A[!c(+)=]"),
+ ("dev-libs/A[a(-),b(+)=,!c(-)=,d(+)?,!e(-)?,-f(+)]", ["b"], ["a", "b", "c", "d", "e", "f"], ["b"], "dev-libs/A[a(-),!c(-)=]"),
+ ("dev-libs/A[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]", ["c"], ["a", "b", "c", "d", "e", "f"], ["c"], "dev-libs/A[a(+),!c(+)=]"),
+ ("dev-libs/A[a(-),b(+)=,!c(-)=,d(+)?,!e(-)?,-f(+)]", ["d"], ["a", "b", "c", "d", "e", "f"], ["d"], "dev-libs/A[a(-),!c(-)=]"),
+ ("dev-libs/A[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]", ["e"], ["a", "b", "c", "d", "e", "f"], ["e"], "dev-libs/A[a(+),!c(+)=]"),
+ ("dev-libs/A[a(-),b(+)=,!c(-)=,d(+)?,!e(-)?,-f(+)]", ["f"], ["a", "b", "c", "d", "e", "f"], ["f"], "dev-libs/A[a(-),-f(+),!c(-)=]"),
+
+ ("dev-libs/A[a(+),b(+)=,!c(+)=,d(-)?,!e(+)?,-f(-)]", ["a"], ["a"], ["a"], "dev-libs/A[!e(+)?,b(+)=]"),
+ ("dev-libs/A[a(-),b(+)=,!c(-)=,d(+)?,!e(-)?,-f(+)]", ["b"], ["b"], ["b"], "dev-libs/A[a(-),-f(+),!c(-)=]"),
+ ("dev-libs/A[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]", ["c"], ["c"], ["c"], "dev-libs/A[!e(+)?,!c(+)=]"),
+ ("dev-libs/A[a(-),b(+)=,!c(-)=,d(+)?,!e(-)?,-f(+)]", ["d"], ["d"], ["d"], "dev-libs/A[a(-),-f(+),b(+)=,!c(-)=]"),
+ ("dev-libs/A[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]", ["e"], ["e"], ["e"], "dev-libs/A"),
+ ("dev-libs/A[a(-),b(+)=,!c(-)=,d(+)?,!e(-)?,-f(+)]", ["f"], ["f"], ["f"], "dev-libs/A[a(-),-f(+),b(+)=,!c(-)=]"),
+
+ #Some more test cases to trigger all remaining code paths
+ ("dev-libs/B[x?]", [], ["x"], ["x"], "dev-libs/B[x?]"),
+ ("dev-libs/B[x(+)?]", [], [], ["x"], "dev-libs/B"),
+ ("dev-libs/B[x(-)?]", [], [], ["x"], "dev-libs/B[x(-)?]"),
+
+ ("dev-libs/C[x=]", [], ["x"], ["x"], "dev-libs/C[x=]"),
+ ("dev-libs/C[x(+)=]", [], [], ["x"], "dev-libs/C"),
+ ("dev-libs/C[x(-)=]", [], [], ["x"], "dev-libs/C[x(-)=]"),
+
+ ("dev-libs/D[!x=]", [], ["x"], ["x"], "dev-libs/D"),
+ ("dev-libs/D[!x(+)=]", [], [], ["x"], "dev-libs/D[!x(+)=]"),
+ ("dev-libs/D[!x(-)=]", [], [], ["x"], "dev-libs/D"),
)
test_cases_xfail = (
- ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", [], None),
+ ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", [], ["a", "b", "c", "d", "e", "f"], None),
)
- for atom, other_use, parent_use, expected_violated_atom in test_cases:
+ for atom, other_use, iuse, parent_use, expected_violated_atom in test_cases:
a = Atom(atom)
- violated_atom = a.violated_conditionals(other_use, parent_use)
+ violated_atom = a.violated_conditionals(other_use, iuse, parent_use)
if parent_use is None:
- fail_msg = "Atom: %s, other_use: %s, parent_use: %s, got: %s, expected: %s" % \
- (atom, " ".join(other_use), "None", str(violated_atom), expected_violated_atom)
+ fail_msg = "Atom: %s, other_use: %s, iuse: %s, parent_use: %s, got: %s, expected: %s" % \
+ (atom, " ".join(other_use), " ".join(iuse), "None", str(violated_atom), expected_violated_atom)
else:
- fail_msg = "Atom: %s, other_use: %s, parent_use: %s, got: %s, expected: %s" % \
- (atom, " ".join(other_use), " ".join(parent_use), str(violated_atom), expected_violated_atom)
+ fail_msg = "Atom: %s, other_use: %s, iuse: %s, parent_use: %s, got: %s, expected: %s" % \
+ (atom, " ".join(other_use), " ".join(iuse), " ".join(parent_use), str(violated_atom), expected_violated_atom)
self.assertEqual(str(violated_atom), expected_violated_atom, fail_msg)
- for atom, other_use, parent_use in test_cases_xfail:
+ for atom, other_use, iuse, parent_use in test_cases_xfail:
a = Atom(atom)
self.assertRaisesMsg(atom, InvalidAtom, \
- a.violated_conditionals, other_use, parent_use)
+ a.violated_conditionals, other_use, iuse, parent_use)
def test_evaluate_conditionals(self):
test_cases = (
("dev-libs/A[foo]", [], "dev-libs/A[foo]"),
("dev-libs/A[foo]", ["foo"], "dev-libs/A[foo]"),
- ("dev-libs/A:0[foo]", ["foo"], "dev-libs/A:0[foo]"),
+ ("dev-libs/A:0[foo=]", ["foo"], "dev-libs/A:0[foo]"),
("dev-libs/A[foo,-bar]", [], "dev-libs/A[foo,-bar]"),
("dev-libs/A[-foo,bar]", [], "dev-libs/A[-foo,bar]"),
("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["d"], "dev-libs/A[a,-f,d,-e,-b,c]"),
("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["e"], "dev-libs/A[a,-f,-b,c]"),
("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["f"], "dev-libs/A[a,-f,-e,-b,c]"),
+ ("dev-libs/A[a(-),b(+)=,!c(-)=,d(+)?,!e(-)?,-f(+)]", ["d"], "dev-libs/A[a(-),-f(+),d(+),-e(-),-b(+),c(-)]"),
+ ("dev-libs/A[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]", ["f"], "dev-libs/A[a(+),-f(-),-e(+),-b(-),c(+)]"),
)
-
-
+
for atom, use, expected_atom in test_cases:
- self.assertEqual(str(Atom(atom).evaluate_conditionals(use)), expected_atom)
+ a = Atom(atom)
+ b = a.evaluate_conditionals(use)
+ self.assertEqual(str(b), expected_atom)
+ self.assertEqual(str(b.unevaluated_atom), atom)
+
+ def test__eval_qa_conditionals(self):
+ test_cases = (
+ ("dev-libs/A[foo]", [], [], "dev-libs/A[foo]"),
+ ("dev-libs/A[foo]", ["foo"], [], "dev-libs/A[foo]"),
+ ("dev-libs/A[foo]", [], ["foo"], "dev-libs/A[foo]"),
+
+ ("dev-libs/A:0[foo]", [], [], "dev-libs/A:0[foo]"),
+ ("dev-libs/A:0[foo]", ["foo"], [], "dev-libs/A:0[foo]"),
+ ("dev-libs/A:0[foo]", [], ["foo"], "dev-libs/A:0[foo]"),
+ ("dev-libs/A:0[foo=]", [], ["foo"], "dev-libs/A:0[foo]"),
+
+ ("dev-libs/A[foo,-bar]", ["foo"], ["bar"], "dev-libs/A[foo,-bar]"),
+ ("dev-libs/A[-foo,bar]", ["foo", "bar"], [], "dev-libs/A[-foo,bar]"),
+
+ ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["a", "b", "c"], [], "dev-libs/A[a,-f,d,-e,-b,c]"),
+ ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", [], ["a", "b", "c"], "dev-libs/A[a,-f,d,-e,b,-c]"),
+ ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["d", "e", "f"], [], "dev-libs/A[a,-f,-e,b,-b,-c,c]"),
+ ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", [], ["d", "e", "f"], "dev-libs/A[a,-f,d,b,-b,-c,c]"),
+
+ ("dev-libs/A[a(-),b(+)=,!c(-)=,d(+)?,!e(-)?,-f(+)]", \
+ ["a", "b", "c", "d", "e", "f"], [], "dev-libs/A[a(-),-f(+),-e(-),-b(+),c(-)]"),
+ ("dev-libs/A[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]", \
+ [], ["a", "b", "c", "d", "e", "f"], "dev-libs/A[a(+),-f(-),d(-),b(-),-c(+)]"),
+ )
+
+ for atom, use_mask, use_force, expected_atom in test_cases:
+ a = Atom(atom)
+ b = a._eval_qa_conditionals(use_mask, use_force)
+ self.assertEqual(str(b), expected_atom)
+ self.assertEqual(str(b.unevaluated_atom), atom)
-# test_match_from_list.py -- Portage Unit Testing Functionality
-# Copyright 2006 Gentoo Foundation
+# Copyright 2006, 2010 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
from portage.tests import TestCase
-from portage.dep import match_from_list
+from portage.dep import Atom, match_from_list
+from portage.versions import catpkgsplit
+
+class Package(object):
+ """
+ Provides a minimal subset of attributes of _emerge.Package.Package
+ """
+ def __init__(self, atom):
+ atom = Atom(atom)
+ self.cp = atom.cp
+ self.cpv = atom.cpv
+ self.cpv_split = catpkgsplit(self.cpv)
+ self.slot = atom.slot
+ if atom.use:
+ self.use = self._use_class(atom.use.enabled)
+ self.iuse = self._iuse_class(atom.use.required)
+ else:
+ self.use = self._use_class([])
+ self.iuse = self._iuse_class([])
+
+ class _use_class(object):
+ def __init__(self, use):
+ self.enabled = frozenset(use)
+
+ class _iuse_class(object):
+ def __init__(self, iuse):
+ self.all = frozenset(iuse)
+
+ def is_valid_flag(self, flags):
+ if isinstance(flags, basestring):
+ flags = [flags]
+ missing_iuse = []
+ for flag in flags:
+ if not flag in self.all:
+ return False
+ return True
class Test_match_from_list(TestCase):
def testMatch_from_list(self):
- tests = [ ("=sys-apps/portage-45*", ["sys-apps/portage-045"], ["sys-apps/portage-045"] ),
- ("=sys-fs/udev-1*", ["sys-fs/udev-123"], ["sys-fs/udev-123"]),
- ("=sys-fs/udev-4*", ["sys-fs/udev-456"], ["sys-fs/udev-456"] ),
- ("*/*", ["sys-fs/udev-456"], ["sys-fs/udev-456"] ),
- ("sys-fs/*", ["sys-fs/udev-456"], ["sys-fs/udev-456"] ),
- ("*/udev", ["sys-fs/udev-456"], ["sys-fs/udev-456"] ),
- ("=sys-apps/portage-2*", ["sys-apps/portage-2.1"], ["sys-apps/portage-2.1"] ),
- ("=sys-apps/portage-2.1*", ["sys-apps/portage-2.1.2"], ["sys-apps/portage-2.1.2"] ),
- ("dev-libs/*", ["sys-apps/portage-2.1.2"], [] ),
- ("*/tar", ["sys-apps/portage-2.1.2"], [] ),
- ("*/*", ["dev-libs/A-1", "dev-libs/B-1"], ["dev-libs/A-1", "dev-libs/B-1"] ),
- ("dev-libs/*", ["dev-libs/A-1", "sci-libs/B-1"], ["dev-libs/A-1"] )
- ]
-
- for atom, cpv_list, result in tests:
- self.assertEqual( match_from_list( atom, cpv_list ), result )
+ tests = (
+ ("=sys-apps/portage-45*", [], [] ),
+ ("=sys-apps/portage-45*", ["sys-apps/portage-045"], ["sys-apps/portage-045"] ),
+ ("!=sys-apps/portage-45*", ["sys-apps/portage-045"], ["sys-apps/portage-045"] ),
+ ("!!=sys-apps/portage-45*", ["sys-apps/portage-045"], ["sys-apps/portage-045"] ),
+ ("=sys-apps/portage-045", ["sys-apps/portage-045"], ["sys-apps/portage-045"] ),
+ ("=sys-apps/portage-045", ["sys-apps/portage-046"], [] ),
+ ("~sys-apps/portage-045", ["sys-apps/portage-045-r1"], ["sys-apps/portage-045-r1"] ),
+ ("~sys-apps/portage-045", ["sys-apps/portage-046-r1"], [] ),
+ ("<=sys-apps/portage-045", ["sys-apps/portage-045"], ["sys-apps/portage-045"] ),
+ ("<=sys-apps/portage-045", ["sys-apps/portage-046"], [] ),
+ ("<sys-apps/portage-046", ["sys-apps/portage-045"], ["sys-apps/portage-045"] ),
+ ("<sys-apps/portage-046", ["sys-apps/portage-046"], [] ),
+ (">=sys-apps/portage-045", ["sys-apps/portage-045"], ["sys-apps/portage-045"] ),
+ (">=sys-apps/portage-047", ["sys-apps/portage-046-r1"], [] ),
+ (">sys-apps/portage-044", ["sys-apps/portage-045"], ["sys-apps/portage-045"] ),
+ (">sys-apps/portage-047", ["sys-apps/portage-046-r1"], [] ),
+ ("sys-apps/portage:0", [Package("=sys-apps/portage-045:0")], ["sys-apps/portage-045"] ),
+ ("sys-apps/portage:0", [Package("=sys-apps/portage-045:1")], [] ),
+ ("=sys-fs/udev-1*", ["sys-fs/udev-123"], ["sys-fs/udev-123"]),
+ ("=sys-fs/udev-4*", ["sys-fs/udev-456"], ["sys-fs/udev-456"] ),
+ ("*/*", ["sys-fs/udev-456"], ["sys-fs/udev-456"] ),
+ ("sys-fs/*", ["sys-fs/udev-456"], ["sys-fs/udev-456"] ),
+ ("*/udev", ["sys-fs/udev-456"], ["sys-fs/udev-456"] ),
+ ("=sys-apps/portage-2*", ["sys-apps/portage-2.1"], ["sys-apps/portage-2.1"] ),
+ ("=sys-apps/portage-2.1*", ["sys-apps/portage-2.1.2"], ["sys-apps/portage-2.1.2"] ),
+ ("dev-libs/*", ["sys-apps/portage-2.1.2"], [] ),
+ ("*/tar", ["sys-apps/portage-2.1.2"], [] ),
+ ("*/*", ["dev-libs/A-1", "dev-libs/B-1"], ["dev-libs/A-1", "dev-libs/B-1"] ),
+ ("dev-libs/*", ["dev-libs/A-1", "sci-libs/B-1"], ["dev-libs/A-1"] ),
+
+ ("dev-libs/A[foo]", [Package("=dev-libs/A-1[foo]"), Package("=dev-libs/A-2[-foo]")], ["dev-libs/A-1"] ),
+ ("dev-libs/A[-foo]", [Package("=dev-libs/A-1[foo]"), Package("=dev-libs/A-2[-foo]")], ["dev-libs/A-2"] ),
+ ("dev-libs/A[-foo]", [Package("=dev-libs/A-1[foo]"), Package("=dev-libs/A-2")], [] ),
+ ("dev-libs/A[foo,bar]", [Package("=dev-libs/A-1[foo]"), Package("=dev-libs/A-2[-foo]")], [] ),
+ ("dev-libs/A[foo,bar]", [Package("=dev-libs/A-1[foo]"), Package("=dev-libs/A-2[-foo,bar]")], [] ),
+ ("dev-libs/A[foo,bar]", [Package("=dev-libs/A-1[foo]"), Package("=dev-libs/A-2[foo,bar]")], ["dev-libs/A-2"] ),
+ ("dev-libs/A[foo,bar(+)]", [Package("=dev-libs/A-1[-foo]"), Package("=dev-libs/A-2[foo]")], ["dev-libs/A-2"] ),
+ ("dev-libs/A[foo,bar(-)]", [Package("=dev-libs/A-1[-foo]"), Package("=dev-libs/A-2[foo]")], [] ),
+ ("dev-libs/A[foo,-bar(-)]", [Package("=dev-libs/A-1[-foo,bar]"), Package("=dev-libs/A-2[foo]")], ["dev-libs/A-2"] ),
+ )
+
+ for atom, cpv_list, expected_result in tests:
+ result = []
+ for pkg in match_from_list( atom, cpv_list ):
+ if isinstance(pkg, Package):
+ result.append(pkg.cpv)
+ else:
+ result.append(pkg)
+ self.assertEqual( result, expected_result )