Changeset 467

Show
Ignore:
Timestamp:
11/26/07 22:44:03 (1 year ago)
Author:
athomas
Message:

cly: Add Set class, used to apply settings to all child nodes.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • cly/trunk/cly/builder.py

    r455 r467  
    1616 
    1717 
    18 __all__ = ['Node', 'Alias', 'Group', 'Action', 'Variable', 'Grammar', 'Help', 
    19            'LazyHelp', 'Word', 'String', 'URI', 'LDAPDN', 'Integer', 'Float', 
    20            'IP', 'Hostname', 'Host', 'EMail', 'File'] 
     18__all__ = ['Node', 'Alias', 'Set', 'Action', 'Variable', 'Grammar', 'Help', 
     19           'LazyHelp', 'Word', 'String', 'URI', 'LDAPDN', 'Integer', 'Float', 'IP', 
     20           'Hostname', 'Host', 'EMail', 'File'] 
    2121__docformat__ = 'restructuredtext en' 
    2222 
     
    225225        return key in self._children 
    226226 
    227     def walk(self): 
     227    def walk(self, predicate=None): 
    228228        """Perform a recursive walk of the grammar tree. 
    229229 
     
    233233        [<Node:/>, <Node:/two>, <Node:/two/four>, <Node:/two/three>] 
    234234        """ 
     235        if predicate is None: 
     236            predicate = lambda node: True 
     237 
    235238        def walk(root): 
     239            if not predicate(root): 
     240                return 
    236241            yield root 
    237242            for node in root._children.itervalues(): 
     
    380385        """Is this node valid in the given context?""" 
    381386        # Node is invalid if traversed more than self.traversals times 
    382         return not self.traversals or context.traversed(self) < self.traversals 
     387        return not self.traversals or \ 
     388            context.traversed(self) < self.traversals 
    383389 
    384390    def _get_anonymous(self): 
     
    392398 
    393399 
    394 class Group(Node): 
    395     """Group all children together at this location. 
    396  
    397     >>> import sys 
    398     >>> from cly.parser import HelpParser, Context 
    399     >>> group = Group(1) 
    400     >>> top = Node('Top', group(name='top', one=Node('One'), two=Node('Two')), three=Node('Three')) 
    401     >>> context = Context(None, None) 
    402     >>> list(HelpParser(context, top)) 
    403     [(0, 'three', 'Three'), (1, 'one', 'One'), (1, 'two', 'Two')] 
    404     """ 
    405  
     400class Set(Node): 
     401    """Apply settings to all ancestor nodes. 
     402 
     403    Terminates application of settings on any deeper Set node. 
     404 
     405    Before applying settings: 
     406 
     407    >>> top = Node('Top')(one=Node('One'), 
     408    ...                   two=Node('Two', three=Node('Three'))) 
     409    >>> [node.traversals for node in top.walk()] 
     410    [1, 1, 1, 1] 
     411 
     412    And after applying settings: 
     413 
     414    >>> apply = Set(traversals=0)(top) 
     415    >>> [node.traversals for node in top.walk()] 
     416    [0, 0, 0, 0] 
     417    """ 
    406418    pattern = '' 
    407419 
    408     def __init__(self, group, *args, **kwargs): 
    409         Node.__init__(self, object.__repr__(self), *args, **kwargs) 
    410         self.group = group 
     420    def __init__(self, **apply): 
     421        self._apply = apply 
     422        Node.__init__(self, object.__repr__(self)) 
    411423 
    412424    def __call__(self, *args, **kwargs): 
    413         Node.__call__(self, *args, **kwargs) 
    414         for child in self: 
    415             child.group = self.group 
    416         return self 
     425        result = Node.__call__(self, *args, **kwargs) 
     426 
     427        def stop_on_ancestors(node): 
     428            return node is self or not isinstance(node, Set) 
     429 
     430        for child in self.walk(predicate=stop_on_ancestors): 
     431            if child is self: 
     432                Node.__call__(self, **self._apply) 
     433            else: 
     434                child(**self._apply) 
     435 
     436        return result 
    417437 
    418438    def valid(self, context):