commit:     9b83f08aa38fb713ff4c9fc8c20e9ff4a3fa896d
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Jul 17 19:11:38 2014 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Jul 17 19:11:38 2014 +0000
URL:        
http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=9b83f08a

package rules: optionally merge acceptor compounds

... of the same type, only AND and OR

OR(a,OR(b,AND(AND,c))) -> OR(a,b,AND(c))

---
 roverlay/packagerules/abstract/acceptors.py | 60 ++++++++++++++++++++++++++---
 1 file changed, 54 insertions(+), 6 deletions(-)

diff --git a/roverlay/packagerules/abstract/acceptors.py 
b/roverlay/packagerules/abstract/acceptors.py
index 7618f43..aafc0e7 100644
--- a/roverlay/packagerules/abstract/acceptors.py
+++ b/roverlay/packagerules/abstract/acceptors.py
@@ -8,12 +8,15 @@
 Classes provided by this module:
 * Acceptor           -- base class for all acceptors
 * ValueMatchAcceptor -- base class for acceptors that compare a value
-* _AcceptorCompound  -- base class combines one more more acceptors
+* _AcceptorCompound  -- base class combines one or more acceptors
                          and represents a boolean term
                          IOW, they realize a function "[Acceptor] -> Bool"
+* _SelfConsumingAcceptorCompound
+                     -- extended _AcceptorCompound that is able to consume
+                        sub-acceptors of the same type (class)
 * Acceptor_<type>    -- specific _AcceptorCompound classes
--> Acceptor_AND
--> Acceptor_OR
+-> Acceptor_AND (self-consuming)
+-> Acceptor_OR  (self-consuming)
 -> Acceptor_XOR1
 -> Acceptor_NOR
 
@@ -55,6 +58,15 @@ class Acceptor ( object ):
       self.logger = logger.getChild ( self.__class__.__name__ )
    # --- end of logger (...) ---
 
+   def merge_sub_compounds ( self ):
+      """Recursively consumes sub compounds of the same type (class),
+      without preserving their priority.
+
+      Must be called manually before prepare().
+      """
+      pass
+   # --- end of merge_sub_compounds (...) ---
+
    def prepare ( self ):
       """Prepare the Acceptor for usage (typically used after loading
       it from a file).
@@ -121,7 +133,7 @@ class _AcceptorCompound ( Acceptor ):
 
       Raises: EmptyAcceptorError
       """
-      if len ( self._acceptors ) > 0:
+      if self._acceptors:
          for acceptor in self._acceptors:
             acceptor.prepare()
          self._acceptors = roverlay.util.priosort ( self._acceptors )
@@ -165,7 +177,43 @@ class _AcceptorCompound ( Acceptor ):
 # --- end of _AcceptorCompound ---
 
 
-class Acceptor_OR ( _AcceptorCompound ):
+class _SelfConsumingAcceptorCompound ( _AcceptorCompound ):
+
+   def merge_sub_compounds ( self ):
+      """Recursively consumes sub compounds of the same type (class),
+      without preserving their priority.
+
+      Must be called manually before prepare().
+      """
+      if not self._acceptors:
+         return
+
+      acceptors         = []
+      append_acceptor   = acceptors.append
+      my_cls            = self.__class__
+      anything_to_merge = False
+
+      for acceptor in self._acceptors:
+         acceptor.merge_sub_compounds()
+
+         if acceptor.__class__ == my_cls:
+            # ^ must exactly match, no hasattr() etc
+            for acceptor_to_merge in acceptor._acceptors:
+               anything_to_merge = True
+               append_acceptor ( acceptor_to_merge )
+            # --
+         else:
+            append_acceptor ( acceptor )
+      # --
+
+      if anything_to_merge:
+         self._acceptors = acceptors
+   # --- end of merge_sub_compounds (...) ---
+
+# --- end of _SelfConsumingAcceptorCompound ---
+
+
+class Acceptor_OR ( _SelfConsumingAcceptorCompound ):
    """OR( <Acceptors> )"""
 
    def accepts ( self, p_info ):
@@ -183,7 +231,7 @@ class Acceptor_OR ( _AcceptorCompound ):
 # --- end of Acceptor_OR ---
 
 
-class Acceptor_AND ( _AcceptorCompound ):
+class Acceptor_AND ( _SelfConsumingAcceptorCompound ):
    """AND( <Acceptors> )"""
 
    def accepts ( self, p_info ):

Reply via email to