Changeset 6

Show
Ignore:
Timestamp:
12/08/04 11:41:46 (4 years ago)
Author:
steve
Message:

make loop var available inside foreach

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/airspeed.py

    r5 r6  
    6161 
    6262 
    63 class BlockEvaluator: 
     63 
     64class Evaluator: 
     65    def eval_expression(self, expression, namespace_dict): 
     66        o = namespace_dict 
     67        for part in expression.split('.'): 
     68            if part.endswith('()'):  ## FIXME 
     69                part = part[:-2] 
     70                try: o = getattr(o, part) 
     71                except AttributeError: pass 
     72                else: o = o() 
     73            else: 
     74                try: o = getattr(o, part) 
     75                except AttributeError: 
     76                    try: o = o[part] 
     77                    except KeyError: pass 
     78            if o in (None, namespace_dict): return None 
     79        return o 
     80 
     81 
     82class BlockEvaluator(Evaluator): 
     83    class LocalNamespace(dict): 
     84        def __init__(self, parent_namespace): 
     85            self.parent_namespace = parent_namespace 
     86        def __getitem__(self, key): 
     87            try: return dict.__getitem__(self, key) 
     88            except KeyError: return self.parent_namespace[key] 
     89 
    6490    def __init__(self): 
    6591        self.children = [] 
    6692        self.delegate = None 
    6793 
    68     def evaluate(self, output_stream, expression_lookup): 
     94    def evaluate(self, output_stream, namespace): 
    6995        for child in self.children: 
    70             child.evaluate(output_stream, expression_lookup
     96            child.evaluate(output_stream, namespace
    7197 
    7298    def add_evaluator(self, evaluator): 
     
    94120 
    95121 
    96 class PlainTextEvaluator
     122class PlainTextEvaluator(Evaluator)
    97123    def __init__(self, text): 
    98124        self.text = text 
    99125 
    100     def evaluate(self, output_stream, expression_lookup): 
     126    def evaluate(self, output_stream, namespace): 
    101127        output_stream.write(self.text) 
    102128 
    103129 
    104 class PlaceholderEvaluator
     130class PlaceholderEvaluator(Evaluator)
    105131    def __init__(self, token_value): 
    106132        self.expression, self.silent, self.original_text = token_value 
    107133 
    108     def evaluate(self, output_stream, expression_lookup): 
    109         value = expression_lookup(self.expression
     134    def evaluate(self, output_stream, namespace): 
     135        value = self.eval_expression(self.expression, namespace
    110136        if value is None: 
    111137            if self.silent: expression_value = '' 
     
    121147        self.condition_expression = token_value 
    122148 
    123     def evaluate(self, output_stream, expression_lookup): 
    124         value = expression_lookup(self.condition_expression
     149    def evaluate(self, output_stream, namespace): 
     150        value = self.eval_expression(self.condition_expression, namespace
    125151        if value: 
    126             BlockEvaluator.evaluate(self, output_stream, expression_lookup
     152            BlockEvaluator.evaluate(self, output_stream, namespace
    127153 
    128154 
     
    132158        self.expression, self.iter_var = token_value 
    133159 
    134     def evaluate(self, output_stream, expression_lookup): 
    135         values = expression_lookup(self.expression
     160    def evaluate(self, output_stream, namespace): 
     161        values = self.eval_expression(self.expression, namespace
    136162        for value in values: 
    137             BlockEvaluator.evaluate(self, output_stream, expression_lookup) 
     163            local_namespace = BlockEvaluator.LocalNamespace(namespace) 
     164            local_namespace[self.iter_var] = value 
     165            BlockEvaluator.evaluate(self, output_stream, local_namespace) 
    138166 
    139167 
     
    148176            evaluator.feed(token_type, token_value) 
    149177        output = StringIO.StringIO() 
    150         evaluator.evaluate(output, self.find
     178        evaluator.evaluate(output, self.data
    151179        return output.getvalue() 
    152  
    153     def find(self, expression): 
    154         o = self.data 
    155         for part in expression.split('.'): 
    156             if part.endswith('()'):  ## FIXME 
    157                 part = part[:-2] 
    158                 try: o = getattr(o, part) 
    159                 except AttributeError: pass 
    160                 else: o = o() 
    161             else: 
    162                 try: o = getattr(o, part) 
    163                 except AttributeError: 
    164                     try: o = o[part] 
    165                     except KeyError: pass 
    166             if o in (None, self.data): return None 
    167         return o 
    168  
    169180 
    170181    def __setitem__(self, name, value): 
  • trunk/airspeed_test.py

    r4 r6  
    123123        self.assertEquals("", parser.merge(template)) 
    124124 
     125    def test_foreach_with_expression_content_loops_correctly(self): 
     126        parser = airspeed.Parser() 
     127        template = airspeed.Template("#foreach ($name in $names)Hello $you. #end") 
     128        parser["you"] = "You" 
     129        parser["names"] = ["Chris", "Steve"] 
     130        self.assertEquals("Hello You. Hello You. ", parser.merge(template)) 
     131 
     132    def test_foreach_makes_loop_variable_accessible(self): 
     133        parser = airspeed.Parser() 
     134        template = airspeed.Template("#foreach ($name in $names)Hello $name. #end") 
     135        parser["names"] = ["Chris", "Steve"] 
     136        self.assertEquals("Hello Chris. Hello Steve. ", parser.merge(template)) 
     137 
     138 
     139 
    125140if __name__ == '__main__': 
    126141    reload(airspeed)