Package dap :: Package util :: Module filter
[hide private]
[frames] | no frames]

Source Code for Module dap.util.filter

  1  import sys 
  2  import inspect 
  3  import compiler 
  4  from urllib import quote 
  5   
  6  from dap.lib import encode_atom 
  7   
  8   
9 -class ASTVisitor(compiler.visitor.ASTVisitor):
10 - def __init__(self, scope, seq):
11 compiler.visitor.ASTVisitor.__init__(self) 12 self.scope = scope 13 self.seq = seq 14 15 self.filters = []
16
17 - def visitGenExprFor(self, node):
18 # Check if we're iterating over the sequence. 19 if self.eval(node.iter) == self.seq: 20 # Add sequence with assigned name to the scope. 21 self.scope[node.assign.name] = self.seq 22 23 # Carry on. 24 self.visit(node.assign) 25 self.visit(node.iter) 26 for if_ in node.ifs: 27 self.visit(if_)
28
29 - def visitListCompFor(self, node):
30 # Check if we're iterating over the sequence. 31 if self.eval(node.list) == self.seq: 32 # Add sequence with assigned name to the scope. 33 self.scope[node.assign.name] = self.seq 34 35 # Carry on. 36 self.visit(node.assign) 37 self.visit(node.list) 38 for if_ in node.ifs: 39 self.visit(if_)
40
41 - def visitCompare(self, node):
42 # Convert multiple comparisons like 1 < a < 2 to 43 # (1 < a) and (a < 2). 44 if len(node.ops) > 1: 45 left = node.expr 46 out = [] 47 for op in node.ops: 48 out.append(compiler.ast.Compare(left, [op])) 49 left = op[1] 50 new_node = compiler.ast.And(out) 51 self.visit(new_node) 52 53 else: 54 # Simple comparison. 55 a, op, b = node.getChildren() 56 ops = ['<', '>', '==', '!=', '<=', '>='] 57 if op in ops: 58 a = self.eval(a) 59 b = self.eval(b) 60 61 # If the objects have an 'id' attribute we use it 62 # instead. 63 if hasattr(a, 'id'): a = a.id 64 else: a = quote(encode_atom(a)) 65 66 if hasattr(b, 'id'): b = b.id 67 else: b = quote(encode_atom(b)) 68 69 # Build filter. 70 if op == '==': op = '=' 71 filter_ = '%s%s%s' % (a, op, b) 72 self.filters.append(filter_)
73
74 - def visitOr(self, node):
75 raise Exception('OR not supported by the DAP spec!')
76
77 - def eval(self, node):
78 """ 79 Eval node. 80 81 This is done by converting the node to bytecode and 82 eval()ing the bytecode in the instance scope. 83 """ 84 ast = compiler.ast.Expression(node) 85 ast.filename = 'dummy' 86 c = compiler.pycodegen.ExpressionCodeGenerator(ast) 87 obj = eval(c.getCode(), self.scope) 88 89 return obj
90 91
92 -def get_filters(seq):
93 # We need to get the stack where the sequence is being iterated. 94 # This is called from genexp --> __iter__ --> get_filters, so 95 # we go up 2 frames in the stack. 96 frame = sys._getframe(2) 97 98 # Inspect frame. 99 fname, lineno, func, src, index = inspect.getframeinfo(frame) 100 scope = frame.f_globals 101 102 # Fix source. 103 if src: 104 src = src[0].strip() 105 if src.endswith(':'): src = '%s pass' % src 106 107 # Build and walk AST to parse filters. 108 visitor = ASTVisitor(scope, seq) 109 try: 110 ast = compiler.parse(src) 111 compiler.walk(ast, visitor) 112 except: 113 pass 114 115 return visitor.filters
116