| Server IP : 93.86.61.54 / Your IP : 216.73.216.206 Web Server : Apache/2.4.62 (Ubuntu) System : Linux rasin.ddns.net 6.8.0-124-generic #124~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue May 26 21:05:19 UTC x86_64 User : www-data ( 33) PHP Version : 8.4.22 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /lib/python3/dist-packages/pythran/optimizations/ |
Upload File : |
""" ListToTuple transforms some List node into more Efficient Tuple nodes. """
from pythran.analyses import Aliases, FixedSizeList
from pythran.tables import MODULES
from pythran.passmanager import Transformation
from pythran.utils import path_to_attr
import gast as ast
patterns = (MODULES['numpy']['full'],
MODULES['numpy']['ones'],
MODULES['numpy']['zeros'],
MODULES['numpy']['empty'],
MODULES['numpy']['concatenate'],
MODULES['builtins']['tuple'],
)
def islist(node):
return isinstance(node, ast.List)
def totuple(node):
return ast.Tuple(node.elts, node.ctx)
class ListToTuple(Transformation):
"""
Replace list nodes by tuple nodes when possible
>>> import gast as ast
>>> from pythran import passmanager, backend
>>> node = ast.parse("def foo(n): import numpy; return numpy.ones([n,n])")
>>> pm = passmanager.PassManager("test")
>>> _, node = pm.apply(ListToTuple, node)
>>> print(pm.dump(backend.Python, node))
def foo(n):
import numpy
return numpy.ones((n, n))
"""
def __init__(self):
self.update = False
super(ListToTuple, self).__init__(Aliases, FixedSizeList)
def visit_AugAssign(self, node):
if not islist(node.value):
return self.generic_visit(node)
node.value = totuple(node.value)
self.update = True
return self.generic_visit(node)
def visit_Call(self, node):
func_aliases = self.aliases.get(node.func, set())
if func_aliases.issubset(patterns):
if islist(node.args[0]):
self.update = True
node.args[0] = totuple(node.args[0])
return self.generic_visit(node)
def visit_List(self, node):
self.generic_visit(node)
if node in self.fixed_size_list:
return self.convert(node)
else:
return node
def visit_Assign(self, node):
"""
Replace list calls by static_list calls when possible
>>> import gast as ast
>>> from pythran import passmanager, backend
>>> node = ast.parse("def foo(n):\\n"
... " x = builtins.list(n)\\n"
... " x[0] = 0\\n"
... " return builtins.tuple(x)")
>>> pm = passmanager.PassManager("test")
>>> _, node = pm.apply(ListToTuple, node)
>>> print(pm.dump(backend.Python, node))
def foo(n):
x = builtins.pythran.static_list(n)
x[0] = 0
return builtins.tuple(x)
>>> node = ast.parse("def foo(n):\\n"
... " x = builtins.list(n)\\n"
... " x[0] = 0\\n"
... " return x")
>>> pm = passmanager.PassManager("test")
>>> _, node = pm.apply(ListToTuple, node)
>>> print(pm.dump(backend.Python, node))
def foo(n):
x = builtins.list(n)
x[0] = 0
return x
"""
self.generic_visit(node)
if node.value not in self.fixed_size_list:
return node
node.value = self.convert(node.value)
return node
def convert(self, node):
self.update = True
if isinstance(node, ast.Call):
if not node.args:
node = ast.Tuple([])
else:
node = node.args[0]
elif isinstance(node, ast.List):
node = ast.Tuple(node.elts, ast.Load())
return ast.Call(path_to_attr(('builtins', 'pythran', 'static_list')),
[node], [])