| Server IP : 217.160.0.135 / Your IP : 216.73.217.85 Web Server : Apache System : Linux www 6.18.52-i1-ampere #1203 SMP Mon Sep 14 18:29:59 CEST 2026 aarch64 User : sws1074145052 ( 1074145052) PHP Version : 8.3.32 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /lib/python3/dist-packages/pythran/types/ |
Upload File : |
from pythran.typing import List, Dict, Set, Fun, TypeVar
from pythran.typing import Union, Iterable
def type_dependencies(t):
if isinstance(t, TypeVar):
return {t}
else:
return set().union(*[type_dependencies(arg)
for arg in getattr(t, '__args__', [])])
def dep_builder(type_var, ppal_index, index, t, self, node):
if isinstance(t, TypeVar):
if t is type_var:
# FIXME: this is the second part of the hack below,
# FIXME: there's no reason why self.result[node.args[index]]
# FIXME: would still be valid in translated context
return lambda arg: (arg
if index == ppal_index
else self.result[node.args[index]])
elif isinstance(t, (List, Set, Iterable, Dict)):
return lambda arg: self.builder.IteratorContentType(
dep_builder(type_var,
ppal_index,
index,
t.__args__[0],
self, node)(arg))
assert False, t
class InfeasibleCombiner(Exception):
pass
def path_to(self, t, deps_builders, node):
if isinstance(t, TypeVar):
if t in deps_builders:
return deps_builders[t]
else:
raise InfeasibleCombiner()
if isinstance(t, List):
return lambda arg: self.builder.ListType(
path_to(self, t.__args__[0], deps_builders, node)(arg))
if isinstance(t, Set):
return lambda arg: self.builder.SetType(
path_to(self, t.__args__[0], deps_builders, node)(arg))
if isinstance(t, Dict):
return lambda arg: self.builder.DictType(
path_to(self, t.__args__[0], deps_builders, node)(arg),
path_to(self, t.__args__[1], deps_builders, node)(arg),
)
if isinstance(t, Fun):
raise InfeasibleCombiner()
if isinstance(t, Iterable): # FIXME?
raise InfeasibleCombiner()
assert False, (t, t.mro())
def build_unary_op(deps, args, self, node):
# FIXME: this is a hack, because only the fist dep gets translated
# FIXME: in case of interprocedural translation
# FIXME: this was the original behavior...
ppal_index = sorted(deps.values())[0][0][0]
deps_builders = {dep: dep_builder(dep,
ppal_index,
*src[0],
self=self,
node=node)
for dep, src in deps.items()}
return path_to(self, args[0], deps_builders, node), ppal_index
def build_combiner(signature, deps):
sig_args = signature.__args__[:-1]
def combiner(self, node):
if deps and len(node.args) == len(sig_args):
try:
unary_op, main_index = build_unary_op(deps,
sig_args,
self, node)
self.combine(
node.args[0],
node.args[main_index],
unary_op=unary_op,
register=True,
aliasing_type=True)
except InfeasibleCombiner:
pass
return combiner
def extract_combiner(signature):
if not isinstance(signature, (Fun, Union)):
return None
if type(signature) is Union:
combiners = [extract_combiner(up)
for up in signature.__args__]
combiners = [cb for cb in combiners if cb]
def combiner(self, node):
for cb in combiners:
cb(self, node)
return combiner
args = signature.__args__[:-1]
if not args:
return None
deps = type_dependencies(args[0])
if not deps:
return None
deps_src = dict()
for i, arg in enumerate(args[1:]):
arg_deps = type_dependencies(arg)
common_deps = deps.intersection(arg_deps)
for common_dep in common_deps:
deps_src.setdefault(common_dep, []).append((i + 1, arg))
return build_combiner(signature, deps_src)