Commit 66ffb55c authored by Stefan Behnel's avatar Stefan Behnel

use a straight call to PyList_Tuple() on code like tuple([...])

parent 41064a84
......@@ -426,6 +426,16 @@ class FlattenInListTransform(Visitor.VisitorTransform, SkipDeclarations):
class FlattenBuiltinTypeCreation(Visitor.VisitorTransform):
"""Optimise some common instantiation patterns for builtin types.
"""
PyList_AsTuple_func_type = PyrexTypes.CFuncType(
PyrexTypes.py_object_type, [
PyrexTypes.CFuncTypeArg("list", Builtin.list_type, None)
])
PyList_AsTuple_name = EncodedString("PyList_AsTuple")
PyList_AsTuple_entry = Symtab.Entry(
PyList_AsTuple_name, PyList_AsTuple_name, PyList_AsTuple_func_type)
def visit_GeneralCallNode(self, node):
self.visitchildren(node)
handler = self._find_handler('general', node.function)
......@@ -486,6 +496,32 @@ class FlattenBuiltinTypeCreation(Visitor.VisitorTransform):
else:
return node
def _handle_simple_tuple(self, node, pos_args, kwargs):
"""Replace tuple([...]) by a call to PyList_AsTuple.
"""
if not isinstance(pos_args, ExprNodes.TupleNode):
return node
if len(pos_args.args) != 1:
return node
list_arg = pos_args.args[0]
if list_arg.type is not Builtin.list_type:
return node
if not isinstance(list_arg, (ExprNodes.ComprehensionNode,
ExprNodes.ListNode)):
# everything else may be None => take the safe path
return node
node.args = pos_args.args
node.arg_tuple = None
node.type = Builtin.tuple_type
node.result_ctype = Builtin.tuple_type
node.function = ExprNodes.NameNode(
pos = node.pos,
name = self.PyList_AsTuple_name,
type = self.PyList_AsTuple_func_type,
entry = self.PyList_AsTuple_entry)
return node
def visit_PyTypeTestNode(self, node):
"""Flatten redundant type checks after tree changes.
"""
......
......@@ -11,6 +11,12 @@ __doc__ = u"""
(2, 3, 4)
>>> l(1,2,3,4,5)
(17, 42, 88)
>>> tuple_none()
Traceback (most recent call last):
TypeError: 'NoneType' object is not iterable
>>> tuple_none_list()
Traceback (most recent call last):
TypeError: 'NoneType' object is not iterable
"""
def f(obj1, obj2, obj3, obj4, obj5):
......@@ -51,3 +57,10 @@ def l(obj1, obj2, obj3, obj4, obj5):
obj1 = (obj2, obj3, obj4,)
obj1 = 17, 42, 88
return obj1
def tuple_none():
return tuple(None)
def tuple_none_list():
cdef list none = None
return tuple(none)
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