Commit 1dead804 authored by Lars Buitinck's avatar Lars Buitinck

optimize: tuple(ob) -> PySequence_Tuple(ob)

parent ec5df1e0
...@@ -2026,24 +2026,29 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin, ...@@ -2026,24 +2026,29 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
PyrexTypes.CFuncTypeArg("list", Builtin.list_type, None) PyrexTypes.CFuncTypeArg("list", Builtin.list_type, None)
]) ])
PySequence_Tuple_func_type = PyrexTypes.CFuncType(
Builtin.tuple_type,
[PyrexTypes.CFuncTypeArg("it", PyrexTypes.py_object_type, None)])
def _handle_simple_function_tuple(self, node, function, pos_args): def _handle_simple_function_tuple(self, node, function, pos_args):
"""Replace tuple([...]) by a call to PyList_AsTuple. """Replace tuple([...]) by PyList_AsTuple or PySequence_Tuple.
""" """
if len(pos_args) != 1: if len(pos_args) != 1:
return node return node
arg = pos_args[0] arg = pos_args[0]
if arg.type is Builtin.tuple_type and not arg.may_be_none(): if arg.type is Builtin.tuple_type and not arg.may_be_none():
return arg return arg
if arg.type is not Builtin.list_type: if arg.type is Builtin.list_type:
return node
pos_args[0] = arg.as_none_safe_node( pos_args[0] = arg.as_none_safe_node(
"'NoneType' object is not iterable") "'NoneType' object is not iterable")
return ExprNodes.PythonCapiCallNode( return ExprNodes.PythonCapiCallNode(
node.pos, "PyList_AsTuple", self.PyList_AsTuple_func_type, node.pos, "PyList_AsTuple", self.PyList_AsTuple_func_type,
args = pos_args, args=pos_args, is_temp=node.is_temp)
is_temp = node.is_temp else:
) return ExprNodes.PythonCapiCallNode(
node.pos, "PySequence_Tuple", self.PySequence_Tuple_func_type,
args=pos_args, is_temp=node.is_temp)
PySet_New_func_type = PyrexTypes.CFuncType( PySet_New_func_type = PyrexTypes.CFuncType(
Builtin.set_type, [ Builtin.set_type, [
......
...@@ -114,9 +114,21 @@ def tuple_of_args_tuple(*args): ...@@ -114,9 +114,21 @@ def tuple_of_args_tuple(*args):
return tuple(tuple(tuple(args))) return tuple(tuple(tuple(args)))
@cython.test_fail_if_path_exists('//SimpleCallNode//SimpleCallNode')
def tuple_of_object(ob):
"""
>>> tuple(type(1))
Traceback (most recent call last):
TypeError: 'type' object is not iterable
>>> sorted(tuple(set([1, 2, 3])))
[1, 2, 3]
"""
return tuple(ob)
@cython.test_fail_if_path_exists( @cython.test_fail_if_path_exists(
'//SimpleCallNode//SimpleCallNode', '//SimpleCallNode',
'//PythonCapiCallNode' '//PythonCapiCallNode//PythonCapiCallNode'
) )
def tuple_of_tuple_or_none(tuple x): def tuple_of_tuple_or_none(tuple x):
""" """
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment