%PDF- %PDF-
| Direktori : /lib/python3/dist-packages/pythran/ |
| Current File : //lib/python3/dist-packages/pythran/utils.py |
""" Common function use for AST manipulation. """
import gast as ast
from pythran.tables import MODULES
from pythran.conversion import mangle, demangle
from functools import reduce
from contextlib import contextmanager
def isstr(node):
return isinstance(node, ast.Constant) and isinstance(node.value, str)
def isintegral(node):
return isinstance(node, ast.Constant) and isinstance(node.value, (int,
bool))
def isnum(node):
return isinstance(node, ast.Constant) and isinstance(node.value, (int,
float,
bool))
def isextslice(node):
if not isinstance(node, ast.Tuple):
return False
return any(isinstance(elt, ast.Slice) for elt in node.elts)
def ispowi(node):
if not isinstance(node.op, ast.Pow):
return False
if not isintegral(node.right):
return False
return node.right.value >= 0
def attr_to_path(node):
""" Compute path and final object for an attribute node """
def get_intrinsic_path(modules, attr):
""" Get function path and intrinsic from an ast.Attribute. """
if isinstance(attr, ast.Name):
return modules[demangle(attr.id)], (demangle(attr.id),)
elif isinstance(attr, ast.Attribute):
module, path = get_intrinsic_path(modules, attr.value)
return module[attr.attr], path + (attr.attr,)
obj, path = get_intrinsic_path(MODULES, node)
if not obj.isliteral():
path = path[:-1] + ('functor', path[-1])
return obj, ('pythonic', ) + path
def path_to_attr(path):
"""
Transform path to ast.Attribute.
>>> import gast as ast
>>> path = ('builtins', 'my', 'constant')
>>> value = path_to_attr(path)
>>> ref = ast.Attribute(
... value=ast.Attribute(value=ast.Name(id="builtins",
... ctx=ast.Load(),
... annotation=None,
... type_comment=None),
... attr="my", ctx=ast.Load()),
... attr="constant", ctx=ast.Load())
>>> ast.dump(ref) == ast.dump(value)
True
"""
return reduce(lambda hpath, last: ast.Attribute(hpath, last, ast.Load()),
path[1:], ast.Name(mangle(path[0]), ast.Load(), None, None))
def path_to_node(path):
"""
Retrieve a symbol in MODULES based on its path
>>> path = ('math', 'pi')
>>> path_to_node(path) #doctest: +ELLIPSIS
<pythran.intrinsic.ConstantIntr object at 0x...>
"""
if len(path) == 1:
return MODULES[path[0]]
else:
return path_to_node(path[:-1])[path[-1]]
def isattr(node):
return (isinstance(node, ast.Call) and
getattr(node.func, 'attr', None) == 'getattr')
def get_variable(assignable):
"""
Return modified variable name.
>>> import gast as ast
>>> ref = ast.Subscript(
... value=ast.Subscript(
... value=ast.Name('a', ast.Load(), None, None),
... slice=ast.Name('i', ast.Load(), None, None),
... ctx=ast.Load()),
... slice=ast.Name('j', ast.Load(), None, None),
... ctx=ast.Load())
>>> ast.dump(get_variable(ref))
"Name(id='a', ctx=Load(), annotation=None, type_comment=None)"
"""
msg = "Only name and subscript can be assigned."
assert isinstance(assignable, (ast.Name, ast.Subscript)), msg
while isinstance(assignable, ast.Subscript) or isattr(assignable):
if isattr(assignable):
assignable = assignable.args[0]
else:
assignable = assignable.value
return assignable
def pythran_builtin(name):
return MODULES['builtins']['pythran'][name]
def pythran_builtin_path(name):
assert name in MODULES['builtins']['pythran']
return ('builtins', 'pythran', name)
def pythran_builtin_attr(name):
return path_to_attr(pythran_builtin_path(name))
def cxxid(name):
from pythran.tables import cxx_keywords
return name + '_' * (name in cxx_keywords)
@contextmanager
def pushpop(l, v):
l.append(v)
yield
l.pop()