def visit_Attribute(self, node): """Get attribute with fallback to dictionary lookup. Note: Variables starting with an underscore are exempt (reserved for internal use); as are the default system symbols. """ if isinstance(node.value, ast.Name) and \ (node.value.id.startswith('_') or node.value.id in SYMBOLS): return ASTTransformer.visit_Attribute(self, node) ## This should be spellable as ## return ast.Call( ## ast.Name(config.SYMBOLS.lookup_attr, ast.Load()), ## [self.visit(node.value), ast.Str(node.attr)], ## [], None, None) ## .. except Python 2.5 doesn't allow it. call = ast.Call() name = ast.Name() name.id = config.SYMBOLS.lookup_attr name.ctx = ast.Load() call.func = name string = ast.Str() string.s = node.attr args = [self.visit(node.value), string] call.args = args call.keywords = [] call.starargs = None call.kwargs = None return call