Commit 34714637 authored by Stefan Behnel's avatar Stefan Behnel Committed by GitHub

Avoid calling PySequence_List() in some cases if the argument is a new list already. (GH-3494)

parent 98319229
......@@ -7797,8 +7797,11 @@ class SequenceNode(ExprNode):
starred_target.allocate(code)
target_list = starred_target.result()
code.putln("%s = PySequence_List(%s); %s" % (
code.putln("%s = %s(%s); %s" % (
target_list,
"__Pyx_PySequence_ListKeepNew" if (
not iterator_temp and rhs.is_temp and rhs.type in (py_object_type, list_type))
else "PySequence_List",
iterator_temp or rhs.py_result(),
code.error_goto_if_null(target_list, self.pos)))
starred_target.generate_gotref(code)
......@@ -8531,7 +8534,9 @@ class MergedSequenceNode(ExprNode):
else:
code.putln("%s = %s(%s); %s" % (
self.result(),
'PySet_New' if is_set else 'PySequence_List',
'PySet_New' if is_set
else "__Pyx_PySequence_ListKeepNew" if item.is_temp and item.type in (py_object_type, list_type)
else "PySequence_List",
item.py_result(),
code.error_goto_if_null(self.result(), self.pos)))
self.generate_gotref(code)
......
......@@ -1753,7 +1753,11 @@ class EarlyReplaceBuiltinCalls(Visitor.EnvTransform):
# Interestingly, PySequence_List works on a lot of non-sequence
# things as well.
list_node = loop_node = ExprNodes.PythonCapiCallNode(
node.pos, "PySequence_List", self.PySequence_List_func_type,
node.pos,
"__Pyx_PySequence_ListKeepNew"
if arg.is_temp and arg.type in (PyrexTypes.py_object_type, Builtin.list_type)
else "PySequence_List",
self.PySequence_List_func_type,
args=pos_args, is_temp=True)
result_node = UtilNodes.ResultRefNode(
......@@ -2415,8 +2419,14 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
return node
arg = pos_args[0]
return ExprNodes.PythonCapiCallNode(
node.pos, "PySequence_List", self.PySequence_List_func_type,
args=pos_args, is_temp=node.is_temp)
node.pos,
"__Pyx_PySequence_ListKeepNew"
if node.is_temp and arg.is_temp and arg.type in (PyrexTypes.py_object_type, Builtin.list_type)
else "PySequence_List",
self.PySequence_List_func_type,
args=pos_args,
is_temp=node.is_temp,
)
PyList_AsTuple_func_type = PyrexTypes.CFuncType(
Builtin.tuple_type, [
......
......@@ -760,6 +760,13 @@ static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStrWithError(PyObject *dict,
#define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj))
#endif
#if CYTHON_COMPILING_IN_CPYTHON
#define __Pyx_PySequence_ListKeepNew(obj) \
(likely(PyList_CheckExact(obj) && Py_REFCNT(obj) == 1) ? __Pyx_NewRef(obj) : PySequence_List(obj))
#else
#define __Pyx_PySequence_ListKeepNew(obj) PySequence_List(obj)
#endif
#ifndef PySet_CheckExact
#define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type)
#endif
......
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