1""" ExpandBuiltins replaces builtins by their full paths. """
2
3from pythran.analyses import Globals, Locals
4from pythran.passmanager import Transformation
5from pythran.syntax import PythranSyntaxError
6from pythran.tables import MODULES
7
8import gast as ast
9
10
11class ExpandBuiltins(Transformation):
12
13    """
14    Expands all builtins into full paths.
15
16    >>> import gast as ast
17    >>> from pythran import passmanager, backend
18    >>> node = ast.parse("def foo(): return list()")
19    >>> pm = passmanager.PassManager("test")
20    >>> _, node = pm.apply(ExpandBuiltins, node)
21    >>> print(pm.dump(backend.Python, node))
22    def foo():
23        return builtins.list()
24    """
25
26    def __init__(self):
27        Transformation.__init__(self, Locals, Globals)
28
29    def visit_NameConstant(self, node):
30        self.update = True
31        return ast.Attribute(
32            ast.Name('builtins', ast.Load(), None, None),
33            str(node.value),
34            ast.Load())
35
36    def visit_Name(self, node):
37        s = node.id
38        if(isinstance(node.ctx, ast.Load) and
39           s not in self.locals[node] and
40           s not in self.globals and
41           s in MODULES['builtins']):
42            if s == 'getattr':
43                raise PythranSyntaxError("You fool! Trying a getattr?", node)
44            self.update = True
45            return ast.Attribute(
46                ast.Name('builtins', ast.Load(), None, None),
47                s,
48                node.ctx)
49        else:
50            return node
51