Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
""" ParallelMaps detects parallel map(...). """
from __future__ import print_function
from pythran.analyses.aliases import Aliases
from pythran.analyses.pure_expressions import PureExpressions
from pythran.passmanager import ModuleAnalysis
from pythran.tables import MODULES
class ParallelMaps(ModuleAnalysis):
"""Yields the est of maps that could be parallel."""
def __init__(self):
self.result = set()
super(ParallelMaps, self).__init__(PureExpressions, Aliases)
def visit_Call(self, node):
if all(alias == MODULES['__builtin__']['map']
for alias in self.aliases[node.func]):
if all(f in self.pure_expressions
for f in self.aliases[node.args[0]]):
self.result.add(node)
def display(self, data):
for node in data:
""" Inlinable list function that may be inlined. """
from pythran.passmanager import ModuleAnalysis
from pythran.analyses import Identifiers
import gast as ast
import copy
class Inlinable(ModuleAnalysis):
""" Determine set of inlinable function.
A function can be inlined if it has only one statement and doesn't
recurse on itself.
"""
def __init__(self):
self.result = dict()
super(Inlinable, self).__init__()
def visit_FunctionDef(self, node):
""" Determine this function definition can be inlined. """
if (len(node.body) == 1 and
isinstance(node.body[0], (ast.Call, ast.Return))):
ids = self.gather(Identifiers, node.body[0])
""" GlobalEffects computes function effect on global state. """
from __future__ import print_function
from pythran.analyses.aliases import Aliases
from pythran.analyses.global_declarations import GlobalDeclarations
from pythran.passmanager import ModuleAnalysis
from pythran.tables import MODULES
import pythran.intrinsic as intrinsic
import gast as ast
import networkx as nx
from functools import reduce
class GlobalEffects(ModuleAnalysis):
"""Add a flag on each function that updates a global variable."""
class FunctionEffect(object):
def __init__(self, node):
self.func = node
if isinstance(node, ast.FunctionDef):
self.global_effect = False
elif isinstance(node, intrinsic.Intrinsic):
self.global_effect = node.global_effects
elif isinstance(node, ast.alias):
self.global_effect = False
elif isinstance(node, str):
self.global_effect = False
elif isinstance(node, intrinsic.Class):
self.global_effect = False
""" Globals computes the value of globals(). """
from pythran.analyses.global_declarations import GlobalDeclarations
from pythran.passmanager import ModuleAnalysis
class Globals(ModuleAnalysis):
def __init__(self):
self.result = set()
super(Globals, self).__init__(GlobalDeclarations)
def visit_Module(self, node):
self.result = {'__builtin__',
'__dispatch__'}.union(self.global_declarations.keys())
def run(self, node):
if not isinstance(node, ast.Module):
if self.ctx.module is None:
raise ValueError("{} called in an uninitialized context".format(type(self).__name__))
node = self.ctx.module
return super(ModuleAnalysis, self).run(node)
def __init__(self):
""" Create empty result graph and gather global declarations. """
self.result = nx.DiGraph()
self.current_function = None
self.naming = dict() # variable to dependencies for current function.
# variable to dependencies for current conditional statement
self.in_cond = dict()
ModuleAnalysis.__init__(self, GlobalDeclarations)
elif t in PYTYPE_TO_CTYPE_TABLE:
return {'{}.hpp'.format(t.__name__)}
else:
raise NotImplementedError("{0}:{1}".format(type(t), t))
def pytype_to_deps(t):
""" python -> pythonic type header full path. """
res = set()
for hpp_dep in pytype_to_deps_hpp(t):
res.add(os.path.join('pythonic', 'types', hpp_dep))
res.add(os.path.join('pythonic', 'include', 'types', hpp_dep))
return res
class TypeDependencies(ModuleAnalysis):
"""
Gathers the callees of each function required for type inference.
This analyse produces a directed graph with functions as nodes and edges
between nodes when a function might call another.
Check usual behavior.
>>> import gast as ast
>>> from pythran import passmanager
>>> pm = passmanager.PassManager("test")
>>> node = ast.parse('''
... def foo(n):
... return 1 if copy(n) else copy(n)
... def copy(n):
... return n == 2''')
extract_constructed_types(tkey) +
extract_constructed_types(tvalue))
elif isinstance(t, tuple):
return ([pytype_to_ctype(t)] +
sum((extract_constructed_types(v) for v in t), []))
elif t == str:
return [pytype_to_ctype(t)]
else:
return []
class UnboundableRValue(Exception):
pass
class Types(ModuleAnalysis):
""" Infer symbolic type for all AST node. """
def __init__(self):
class TypeResult(dict):
def __init__(self):
self.builder = TypeBuilder()
def copy(self):
other = TypeResult()
other.update(self.items())
other.builder = self.builder
return other
self.result = TypeResult()
""" ArgumentReadOnce counts the usages of each argument of each function. """
from pythran.analyses.aliases import Aliases
from pythran.analyses.global_declarations import GlobalDeclarations
from pythran.passmanager import ModuleAnalysis
from pythran.tables import MODULES
import pythran.intrinsic as intrinsic
import gast as ast
from functools import reduce
class ArgumentReadOnce(ModuleAnalysis):
"""
Counts the usages of each argument of each function.
Attributes
----------
result : {FunctionEffects}
Number of use for each argument of each function.
node_to_functioneffect : {???: ???}
FunctionDef ast node to function effect binding.
"""
class FunctionEffects(object):
def __init__(self, node):
self.func = node
self.dependencies = lambda ctx: 0
"""
ExtendedSyntaxCheck performs various syntax checks on the pythran AST.
"""
from pythran.passmanager import ModuleAnalysis
from pythran.analyses import StrictAliases, ArgumentEffects
from pythran.syntax import PythranSyntaxError
from pythran import metadata
import gast as ast
class ExtendedSyntaxCheck(ModuleAnalysis):
"""
Perform advanced syntax checking, based on strict aliases analysis:
- is there a function redefinition?
- is there a function call that does not match the called expression arity?
- is there an operation that updates a global variable?
"""
def __init__(self):
self.result = None
self.update = False
self.functions = set()
ModuleAnalysis.__init__(self, StrictAliases, ArgumentEffects)
def check_global(self, node, arg):
if not isinstance(arg, ast.Call):
return