文件操作 - pattern_transform.py
返回文件管理
返回主菜单
删除本文件
文件: /usr/lib/python3/dist-packages/pythran/optimizations/pattern_transform.py
编辑文件内容
""" Optimization for Python costly pattern. """ from pythran.conversion import mangle from pythran.analyses import Check, Placeholder from pythran.passmanager import Transformation from copy import deepcopy import gast as ast class Pattern(object): def match(self, node): self.check = Check(node, dict()) return self.check.visit(self.pattern) def replace(self): return PlaceholderReplace(self.check.placeholders).visit(self.sub()) def imports(self): return deepcopy(getattr(self, 'extra_imports', [])) class LenSetPattern(Pattern): # builtins.len(builtins.set(X)) => builtins.pythran.len_set(X) pattern = ast.Call(func=ast.Attribute(value=ast.Name('builtins', ast.Load(), None, None), attr="len", ctx=ast.Load()), args=[ast.Call( func=ast.Attribute( value=ast.Name('builtins', ast.Load(), None, None), attr="set", ctx=ast.Load()), args=[Placeholder(0)], keywords=[])], keywords=[]) @staticmethod def sub(): return ast.Call( func=ast.Attribute( value=ast.Attribute(value=ast.Name('builtins', ast.Load(), None, None), attr="pythran", ctx=ast.Load()), attr="len_set", ctx=ast.Load()), args=[Placeholder(0)], keywords=[]) class LenRangePattern(Pattern): # builtins.len(builtins.range(X)) => max(0, X) pattern = ast.Call(func=ast.Attribute(value=ast.Name('builtins', ast.Load(), None, None), attr="len", ctx=ast.Load()), args=[ast.Call( func=ast.Attribute( value=ast.Name('builtins', ast.Load(), None, None), attr="range", ctx=ast.Load()), args=[Placeholder(0)], keywords=[])], keywords=[]) @staticmethod def sub(): return ast.Call( func=ast.Attribute(value=ast.Name('builtins', ast.Load(), None, None), attr="max", ctx=ast.Load()), args=[ast.Constant(0, None), Placeholder(0)], keywords=[]) class TupleListPattern(Pattern): # builtins.tuple(builtins.list(X)) => builtins.tuple(X) pattern = ast.Call(func=ast.Attribute(value=ast.Name('builtins', ast.Load(), None, None), attr="tuple", ctx=ast.Load()), args=[ast.Call( func=ast.Attribute( value=ast.Name('builtins', ast.Load(), None, None), attr="list", ctx=ast.Load()), args=[Placeholder(0)], keywords=[])], keywords=[]) @staticmethod def sub(): return ast.Call( func=ast.Attribute(value=ast.Name(id='builtins', ctx=ast.Load(), annotation=None, type_comment=None), attr="tuple", ctx=ast.Load()), args=[Placeholder(0)], keywords=[]) class AbsSqrPattern(Pattern): # builtins.abs(X) ** 2 => builtins.pythran.abssqr(X) pattern = ast.Call(func=ast.Attribute(value=ast.Name(id=mangle('numpy'), ctx=ast.Load(), annotation=None, type_comment=None), attr="square", ctx=ast.Load()), args=[ast.Call(func=ast.Attribute( value=ast.Name(id='builtins', ctx=ast.Load(), annotation=None, type_comment=None), attr="abs", ctx=ast.Load()), args=[Placeholder(0)], keywords=[])], keywords=[]) @staticmethod def sub(): return ast.Call( func=ast.Attribute( value=ast.Attribute(value=ast.Name(id='builtins', ctx=ast.Load(), annotation=None, type_comment=None), attr="pythran", ctx=ast.Load()), attr="abssqr", ctx=ast.Load()), args=[Placeholder(0)], keywords=[]) class AbsSqrPatternNumpy(AbsSqrPattern): # numpy.abs(X) ** 2 => builtins.pythran.abssqr(X) pattern = ast.Call(func=ast.Attribute(value=ast.Name(id=mangle('numpy'), ctx=ast.Load(), annotation=None, type_comment=None), attr="square", ctx=ast.Load()), args=[ast.Call(func=ast.Attribute( value=ast.Name(id=mangle('numpy'), ctx=ast.Load(), annotation=None, type_comment=None), attr="abs", ctx=ast.Load()), args=[Placeholder(0)], keywords=[])], keywords=[]) class PowFuncPattern(Pattern): # builtins.pow(X, Y) => X ** Y pattern = ast.Call(func=ast.Attribute( value=ast.Name(id=mangle('builtins'), ctx=ast.Load(), annotation=None, type_comment=None), attr='pow', ctx=ast.Load()), args=[Placeholder(0), Placeholder(1)], keywords=[]) @staticmethod def sub(): return ast.BinOp(Placeholder(0), ast.Pow(), Placeholder(1)) class SqrtPattern(Pattern): # X ** .5 => numpy.sqrt(X) pattern = ast.BinOp(Placeholder(0), ast.Pow(), ast.Constant(0.5, None)) @staticmethod def sub(): return ast.Call( func=ast.Attribute(value=ast.Name(id=mangle('numpy'), ctx=ast.Load(), annotation=None, type_comment=None), attr="sqrt", ctx=ast.Load()), args=[Placeholder(0)], keywords=[]) extra_imports = [ast.Import([ast.alias('numpy', mangle('numpy'))])] class CbrtPattern(Pattern): # X ** .33333 => numpy.cbrt(X) pattern = ast.BinOp(Placeholder(0), ast.Pow(), ast.Constant(1./3., None)) @staticmethod def sub(): return ast.Call( func=ast.Attribute(value=ast.Name(id=mangle('numpy'), ctx=ast.Load(), annotation=None, type_comment=None), attr="cbrt", ctx=ast.Load()), args=[Placeholder(0)], keywords=[]) extra_imports = [ast.Import([ast.alias('numpy', mangle('numpy'))])] class TuplePattern(Pattern): # builtins.tuple([X, ..., Z]) => (X, ..., Z) pattern = ast.Call(func=ast.Attribute(value=ast.Name(id='builtins', ctx=ast.Load(), annotation=None, type_comment=None), attr="tuple", ctx=ast.Load()), args=[ast.List(Placeholder(0), ast.Load())], keywords=[]) @staticmethod def sub(): return ast.Tuple(Placeholder(0), ast.Load()) class ReversedRangePattern(Pattern): # builtins.reversed(builtins.range(X)) => # builtins.range(X-1, -1, -1) # FIXME : We should do it even when begin/end/step are given pattern = ast.Call(func=ast.Attribute(value=ast.Name(id='builtins', ctx=ast.Load(), annotation=None, type_comment=None), attr="reversed", ctx=ast.Load()), args=[ast.Call( func=ast.Attribute( value=ast.Name(id='builtins', ctx=ast.Load(), annotation=None, type_comment=None), attr='range', ctx=ast.Load()), args=[Placeholder(0)], keywords=[])], keywords=[]) @staticmethod def sub(): return ast.Call( func=ast.Attribute(value=ast.Name(id='builtins', ctx=ast.Load(), annotation=None, type_comment=None), attr='range', ctx=ast.Load()), args=[ast.BinOp(left=Placeholder(0), op=ast.Sub(), right=ast.Constant(1, None)), ast.Constant(-1, None), ast.Constant(-1, None)], keywords=[]) class SqrPattern(Pattern): # X * X => X ** 2 pattern = ast.BinOp(left=Placeholder(0), op=ast.Mult(), right=Placeholder(0)) @staticmethod def sub(): return ast.BinOp(left=Placeholder(0), op=ast.Pow(), right=ast.Constant(2, None)) class StrJoinPattern(Pattern): # a + "..." + b => "...".join((a, b)) pattern = ast.BinOp(left=ast.BinOp(left=Placeholder(0), op=ast.Add(), right=ast.Constant(Placeholder(1, str), None)), op=ast.Add(), right=Placeholder(2)) @staticmethod def sub(): return ast.Call(func=ast.Attribute( ast.Attribute( ast.Name('builtins', ast.Load(), None, None), 'str', ast.Load()), 'join', ast.Load()), args=[ast.Constant(Placeholder(1), None), ast.Tuple([Placeholder(0), Placeholder(2)], ast.Load())], keywords=[]) know_pattern = [x for x in globals().values() if hasattr(x, "pattern")] class PlaceholderReplace(Transformation): """ Helper class to replace the placeholder once value is collected. """ def __init__(self, placeholders): """ Store placeholders value collected. """ self.placeholders = placeholders super(PlaceholderReplace, self).__init__() def visit(self, node): """ Replace the placeholder if it is one or continue. """ if isinstance(node, Placeholder): return self.placeholders[node.id] else: return super(PlaceholderReplace, self).visit(node) class PatternTransform(Transformation): """ Replace all known pattern by pythran function call. Based on BaseMatcher to search correct pattern. """ def __init__(self): """ Initialize the Basematcher to search for placeholders. """ super(PatternTransform, self).__init__() def visit_Module(self, node): self.extra_imports = [] self.generic_visit(node) node.body = self.extra_imports + node.body return node def visit(self, node): """ Try to replace if node match the given pattern or keep going. """ for pattern in know_pattern: matcher = pattern() if matcher.match(node): self.extra_imports.extend(matcher.imports()) node = matcher.replace() self.update = True return super(PatternTransform, self).visit(node)
修改文件时间
将文件时间修改为当前时间的前一年
删除文件