summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pym/portage/dep/__init__.py27
-rw-r--r--pym/portage/tests/dep/test_paren_reduce.py16
2 files changed, 38 insertions, 5 deletions
diff --git a/pym/portage/dep/__init__.py b/pym/portage/dep/__init__.py
index 19e347cfb..89b384a5b 100644
--- a/pym/portage/dep/__init__.py
+++ b/pym/portage/dep/__init__.py
@@ -84,11 +84,11 @@ def strip_empty(myarr):
def paren_reduce(mystr):
"""
Take a string and convert all paren enclosed entities into sublists and
- split the list elements by spaces.
+ split the list elements by spaces. All redundant brackets are removed.
Example usage:
- >>> paren_reduce('foobar foo ( bar baz )')
- ['foobar', 'foo', ['bar', 'baz']]
+ >>> paren_reduce('foobar foo? ( bar baz )')
+ ['foobar', 'foo?', ['bar', 'baz']]
@param mystr: The string to reduce
@type mystr: String
@@ -111,7 +111,26 @@ def paren_reduce(mystr):
_("malformed syntax: '%s'") % mystr)
if level > 0:
level -= 1
- stack[level].append(stack.pop())
+ l = stack.pop()
+ if l:
+ if not stack[level] or (stack[level][-1] != "||" and not stack[level][-1][-1] == "?"):
+ #Optimize: ( ( ... ) ) -> ( ... )
+ stack[level].extend(l)
+ elif len(l) == 1 and stack[level][-1] == "||":
+ #Optimize: || ( A ) -> A
+ stack[level].pop()
+ stack[level].extend(l)
+ elif len(l) == 2 and (l[0] == "||" or l[0][-1] == "?") and stack[level][-1] in (l[0], "||"):
+ #Optimize: || ( || ( ... ) ) -> || ( ... )
+ # foo? ( foo? ( ... ) ) -> foo? ( ... )
+ # || ( foo? ( ... ) ) -> foo? ( ... )
+ stack[level].pop()
+ stack[level].extend(l)
+ else:
+ stack[level].append(l)
+ else:
+ if stack[level] and (stack[level][-1] == "||" or stack[level][-1][-1] == "?"):
+ stack[level].pop()
else:
raise portage.exception.InvalidDependString(
_("malformed syntax: '%s'") % mystr)
diff --git a/pym/portage/tests/dep/test_paren_reduce.py b/pym/portage/tests/dep/test_paren_reduce.py
index 3277ab58b..bd5f42584 100644
--- a/pym/portage/tests/dep/test_paren_reduce.py
+++ b/pym/portage/tests/dep/test_paren_reduce.py
@@ -11,12 +11,23 @@ class TestParenReduce(TestCase):
test_cases = (
( "A", ["A"]),
- ( "( A )", [["A"]]),
+ ( "( A )", ["A"]),
( "|| ( A B )", [ "||", ["A", "B"] ]),
( "|| ( A || ( B C ) )", [ "||", ["A", "||", ["B", "C"]]]),
( "|| ( A || ( B C D ) )", [ "||", ["A", "||", ["B", "C", "D"]] ]),
( "|| ( A || ( B || ( C D ) E ) )", [ "||", ["A", "||", ["B", "||", ["C", "D"], "E"]] ]),
( "a? ( A )", ["a?", ["A"]]),
+
+ ( "( || ( ( ( A ) B ) ) )", [ "||", ["A", "B"] ]),
+ ( "( || ( || ( ( A ) B ) ) )", [ "||", ["A", "B"] ]),
+ ( "( || ( || ( ( A ) B ) ) )", [ "||", ["A", "B"] ]),
+ ( "|| ( A )", ["A"]),
+ ( "( || ( || ( || ( A ) foo? ( B ) ) ) )", [ "||", ["A", "foo?", ["B"] ]]),
+ ( "( || ( || ( bar? ( A ) || ( foo? ( B ) ) ) ) )", [ "||", ["bar?", ["A"], "foo?", ["B"] ]]),
+ ( "A || ( ) foo? ( ) B", ["A", "B"]),
+
+ ( "|| ( A ) || ( B )", ["A", "B"]),
+ ( "foo? ( A ) foo? ( B )", ["foo?", ["A"], "foo?", ["B"]]),
)
test_cases_xfail = (
@@ -36,6 +47,9 @@ class TestParenReduce(TestCase):
"|| ( A B || )",
"a? A",
+
+ ( "( || ( || || ( A ) foo? ( B ) ) )"),
+ ( "( || ( || bar? ( A ) foo? ( B ) ) )"),
)
for dep_str, expected_result in test_cases: