Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
self.cant_return = False
def visit_Try(self, node):
self.cant_return = True
self.generic_visit(node)
self.cant_return = False
def visit_Return(self, node):
if self.cant_return:
raise ValueError(
'`return` statements are not supported in loops. '
'Try assigning to a variable in the while loop, and returning '
'outside of the loop')
class DetectReturnInConditional(gast.NodeVisitor):
"""Assert that no return statements are present in conditionals."""
def __init__(self):
self.cant_return = False
super(DetectReturnInConditional, self).__init__()
def visit_If(self, node):
self.cant_return = True
self.generic_visit(node)
self.cant_return = False
def visit_Return(self, node):
if self.cant_return:
raise ValueError(
'After transforms, a conditional contained a `return `statement, '
'which is not allowed. This is a bug, and should not happen.')
# ==============================================================================
"""Copy an AST tree, discarding annotations."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import ast
import gast
from tensorflow.contrib.autograph.pyct import anno
from tensorflow.contrib.autograph.pyct import parser
class CleanCopier(gast.NodeVisitor):
"""Copies AST nodes.
The copied nodes will ignore almost all fields that are prefixed by '__'.
Exceptions make some annotations.
"""
# TODO(mdan): Parametrize which annotations get carried over.
def generic_visit(self, node):
new_fields = {}
for f in node._fields:
if f.startswith('__'):
continue
if not hasattr(node, f):
continue
v = getattr(node, f)
self.cant_return = False
def visit_Try(self, node):
self.cant_return = True
self.generic_visit(node)
self.cant_return = False
def visit_Return(self, node):
if self.cant_return:
raise ValueError(
'`return` statements are not supported in loops. '
'Try assigning to a variable in the while loop, and returning '
'outside of the loop')
class DetectReturnInConditional(gast.NodeVisitor):
"""Assert that no return statements are present in conditionals."""
def __init__(self):
self.cant_return = False
super(DetectReturnInConditional, self).__init__()
def visit_If(self, node):
self.cant_return = True
self.generic_visit(node)
self.cant_return = False
def visit_Return(self, node):
if self.cant_return:
raise ValueError(
'After transforms, a conditional contained a `return `statement, '
'which is not allowed. This is a bug, and should not happen.')
self.cant_return = False
super(DetectReturnInConditional, self).__init__()
def visit_If(self, node):
self.cant_return = True
self.generic_visit(node)
self.cant_return = False
def visit_Return(self, node):
if self.cant_return:
raise ValueError(
'After transforms, a conditional contained a `return `statement, '
'which is not allowed. This is a bug, and should not happen.')
class DetectReturnInFunctionDef(gast.NodeVisitor):
def visit_FunctionDef(self, node):
self.generic_visit(node)
if not contains_return(node):
raise ValueError(
'Each function definition should contain at least one return.')
def transform(node, context):
"""Ensure a function has only a single return.
This transforms an AST node with multiple returns successively into containing
only a single return node.
There are a few restrictions on what we can handle:
- An AST being transformed must contain at least one return.
- No returns allowed in loops. We have to know the type of the return value,
"""Capture the external nodes used in functions
===============================================
"""
import gast as ast
from transonic.analyses import beniget
from transonic.analyses import extast
class CaptureX(ast.NodeVisitor):
"""Capture the external nodes used in functions, classes and blocks"""
def __init__(
self,
functions,
module_node,
ancestors=None,
defuse_chains=None,
usedef_chains=None,
consider_annotations=True,
blocks=None,
):
if defuse_chains is None:
self.du_chains = du = beniget.DefUseChains()
du.visit(module_node)
}
class Py2JSSyntaxError(SyntaxError):
def __init__(self, message):
error_msg = message + ', note that only a subset of Python is supported'
super(Py2JSSyntaxError, self).__init__(error_msg)
class Py2JSNameError(NameError):
def __init__(self, message):
error_msg = message + ', note that only a subset of Python is supported'
super(Py2JSNameError, self).__init__(error_msg)
class Py2JSVisitor(ast.NodeVisitor):
"""Visitor that turns a Node into JavaScript code."""
def generic_visit(self, node):
"""Throwing an error by default."""
raise Py2JSSyntaxError('Unsupported {} node'.format(node.__class__.__name__))
def visit_Expr(self, node):
"""Turn a Python expression into JavaScript code."""
return self.visit(node.value)
def visit_NameConstant(self, node):
"""Turn a Python nameconstant expression into JavaScript code."""
if node.value is False:
return 'false'
if node.value is True:
return 'true'
return [renamer.visit(n) for n in node]
elif isinstance(node, tuple):
return tuple(renamer.visit(n) for n in node)
return renamer.visit(node)
def keywords_to_dict(keywords):
keys = []
values = []
for kw in keywords:
keys.append(gast.Str(kw.arg))
values.append(kw.value)
return gast.Dict(keys=keys, values=values)
class PatternMatcher(gast.NodeVisitor):
"""Matches a node against a pattern represented by a node.
The pattern may contain wildcards represented by the symbol '_'.
"""
def __init__(self, pattern):
self.pattern = pattern
self.pattern_stack = []
self.matches = True
def compare_and_visit(self, node, pattern):
self.pattern_stack.append(self.pattern)
self.pattern = pattern
self.generic_visit(node)
self.pattern = self.pattern_stack.pop()
def joint_name(func, wrt):
"""Name for a function in joint mode."""
return _adjoint_name(func, wrt, JOINT_NAME)
def adjoint_name(func, wrt):
"""Name for the adjoint of a function."""
return _adjoint_name(func, wrt, ADJOINT_NAME)
def tangent_name(func, wrt):
"""Name for a function in forward mode."""
return _adjoint_name(func, wrt, TANGENT_NAME)
class Names(gast.NodeVisitor):
def __init__(self):
self.names = set()
def visit_Name(self, node):
if isinstance(node.ctx, (gast.Store, gast.Param)):
self.names.add(node.id)
def get_names(node):
"""Find the arguments and variables assigned to in a certain node."""
names = Names()
names.visit(node)
return names.names
import sys
import gast as ast
import numpy as np
class PythranSyntaxError(SyntaxError):
def __init__(self, msg, node=None):
SyntaxError.__init__(self, msg)
if node:
self.filename = getattr(node, 'filename', None)
self.lineno = node.lineno
self.offset = node.col_offset
class SyntaxChecker(ast.NodeVisitor):
"""
Visit an AST and raise a PythranSyntaxError upon unsupported construct.
Attributes
----------
attributes : {str}
Possible attributes from Pythonic modules/submodules.
"""
def __init__(self):
""" Gather attributes from MODULES content. """
self.attributes = set()
def save_attribute(module):
""" Recursively save Pythonic keywords as possible attributes. """
from tangent import ast as ast_
from tangent import grammar
from tangent import utils
class Node(object):
"""A node in the CFG."""
__slots__ = ['next', 'value', 'prev']
def __init__(self, value):
self.next = set()
self.prev = set()
self.value = value
class CFG(gast.NodeVisitor):
"""Construct a control flow graph.
Each statement is represented as a node. For control flow statements such
as conditionals and loops the conditional itself is a node which either
branches or cycles, respectively.
Attributes:
entry: The entry node, which contains the `gast.arguments` node of the
function definition.
exit: The exit node. This node is special because it has no value (i.e. no
corresponding AST node). This is because Python functions can have
multiple return statements.
"""
def __init__(self):
# The current leaves of the CFG