%PDF- %PDF-
Direktori : /lib/python3/dist-packages/pythran/analyses/ |
Current File : //lib/python3/dist-packages/pythran/analyses/dependencies.py |
""" Dependencies lists the functions and types required by a function """ from pythran.passmanager import ModuleAnalysis from pythran.conversion import demangle import gast as ast import math class Dependencies(ModuleAnalysis): OpMap = { # binop ast.Add: ('operator', 'add'), ast.Sub: ('operator', 'sub'), ast.Mult: ('operator', 'mul'), ast.Div: ('operator', 'div'), ast.Mod: ('operator', 'mod'), ast.Pow: ('operator', 'pow'), ast.LShift: ('operator', 'lshift'), ast.RShift: ('operator', 'rshift'), ast.BitOr: ('operator', 'or_'), ast.BitXor: ('operator', 'xor_'), ast.BitAnd: ('operator', 'and_'), ast.MatMult: ('operator', 'matmul'), ast.FloorDiv: ('operator', 'floordiv'), # unaryop ast.Invert: ('operator', 'invert'), ast.Not: ('operator', 'not_'), ast.UAdd: ('operator', 'pos'), ast.USub: ('operator', 'neg'), # cmpop ast.Eq: ('operator', 'eq'), ast.NotEq: ('operator', 'ne'), ast.Lt: ('operator', 'lt'), ast.LtE: ('operator', 'le'), ast.Gt: ('operator', 'gt'), ast.GtE: ('operator', 'ge'), ast.Is: ('operator', 'is_'), ast.IsNot: ('operator', 'is_not'), ast.In: ('operator', 'contains'), ast.NotIn: ('operator', 'contains'), } IOpMap = { ast.Add: ('operator', 'iadd'), ast.Sub: ('operator', 'isub'), ast.Mult: ('operator', 'imul'), ast.Div: ('operator', 'idiv'), ast.Mod: ('operator', 'imod'), ast.Pow: ('operator', 'ipow'), ast.LShift: ('operator', 'ilshift'), ast.RShift: ('operator', 'irshift'), ast.BitOr: ('operator', 'ior'), ast.BitXor: ('operator', 'ixor'), ast.BitAnd: ('operator', 'iand'), ast.MatMult: ('operator', 'imatmul'), ast.FloorDiv: ('operator', 'ifloordiv'), } def __init__(self): self.result = set() super(Dependencies, self).__init__() def visit_List(self, node): self.result.add(('builtins', 'list')) self.generic_visit(node) def visit_Tuple(self, node): self.result.add(('builtins', 'tuple')) self.generic_visit(node) def visit_Set(self, node): self.result.add(('builtins', 'set')) self.generic_visit(node) def visit_Dict(self, node): self.result.add(('builtins', 'dict')) self.generic_visit(node) def visit_Slice(self, node): self.result.add(('types', 'slice')) self.generic_visit(node) def visit_And(self, node): self.result.add(('builtins', 'pythran', 'and')) self.generic_visit(node) def visit_Or(self, node): self.result.add(('builtins', 'pythran', 'or')) self.generic_visit(node) def visit_BinOp(self, node): self.visit(node.left) self.result.add(Dependencies.OpMap[type(node.op)]) self.visit(node.right) def visit_UnaryOp(self, node): self.result.add(Dependencies.OpMap[type(node.op)]) self.visit(node.operand) def visit_Compare(self, node): self.visit(node.left) for op in node.ops: self.result.add(Dependencies.OpMap[type(op)]) for comparator in node.comparators: self.visit(comparator) def visit_AugAssign(self, node): self.visit(node.target) # because of the way type inference turns augassign into assign self.result.add(Dependencies.OpMap[type(node.op)]) self.result.add(Dependencies.IOpMap[type(node.op)]) self.visit(node.value) def visit_Print(self, node): self.result.add(('builtins', 'print')) self.generic_visit(node) def visit_Assert(self, node): self.result.add(('builtins', 'assert')) self.generic_visit(node) def visit_Yield(self, node): self.result.add(('utils', 'yield')) self.generic_visit(node) def visit_Constant(self, node): if node.value is None: self.result.add(('builtins', 'None')) elif isinstance(node.value, str): self.result.add(('types', 'str')) elif isinstance(node.value, complex): self.result.add(('types', 'complex')) elif math.isnan(node.value): self.result.add(('numpy', 'nan')) elif math.isinf(node.value): self.result.add(('numpy', 'inf')) def visit_Attribute(self, node): def rec(n): if isinstance(n, ast.Name): return demangle(n.id), elif isinstance(n, ast.Attribute): return rec(n.value) + (n.attr,) attr = rec(node) attr and self.result.add(attr)