From 067af347f226172fd1728938d102a28e7355a317 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Wed, 24 Feb 2010 14:23:58 +0100 Subject: [PATCH] support for builtin iter(x, sentinel) --- Cython/Compiler/Builtin.py | 2 +- Cython/Compiler/Optimize.py | 26 ++++++++++++++++++++++++++ tests/run/iter.pyx | 27 +++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 tests/run/iter.pyx diff --git a/Cython/Compiler/Builtin.py b/Cython/Compiler/Builtin.py index b0ad215e..61bc1786 100644 --- a/Cython/Compiler/Builtin.py +++ b/Cython/Compiler/Builtin.py @@ -31,7 +31,7 @@ builtin_function_table = [ ('intern', "O", "O", "__Pyx_Intern"), ('isinstance', "OO", "b", "PyObject_IsInstance"), ('issubclass', "OO", "b", "PyObject_IsSubclass"), - ('iter', "O", "O", "PyObject_GetIter"), + #('iter', "O", "O", "PyObject_GetIter"), # optimised later on ('len', "O", "Z", "PyObject_Length"), ('locals', "", "O", "__pyx_locals"), #('map', "", "", ""), diff --git a/Cython/Compiler/Optimize.py b/Cython/Compiler/Optimize.py index a3ef0966..c3730cbe 100644 --- a/Cython/Compiler/Optimize.py +++ b/Cython/Compiler/Optimize.py @@ -1173,6 +1173,32 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform): self._error_wrong_arg_count('getattr', node, pos_args, '2 or 3') return node + PyObject_GetIter_func_type = PyrexTypes.CFuncType( + PyrexTypes.py_object_type, [ + PyrexTypes.CFuncTypeArg("object", PyrexTypes.py_object_type, None), + ]) + + PyCallIter_New_func_type = PyrexTypes.CFuncType( + PyrexTypes.py_object_type, [ + PyrexTypes.CFuncTypeArg("object", PyrexTypes.py_object_type, None), + PyrexTypes.CFuncTypeArg("sentinel", PyrexTypes.py_object_type, None), + ]) + + def _handle_simple_function_iter(self, node, pos_args): + if len(pos_args) == 1: + return ExprNodes.PythonCapiCallNode( + node.pos, "PyObject_GetIter", self.PyObject_GetIter_func_type, + args = pos_args, + is_temp = node.is_temp) + elif len(pos_args) == 2: + return ExprNodes.PythonCapiCallNode( + node.pos, "PyCallIter_New", self.PyCallIter_New_func_type, + args = pos_args, + is_temp = node.is_temp) + else: + self._error_wrong_arg_count('iter', node, pos_args, '1 or 2') + return node + Pyx_strlen_func_type = PyrexTypes.CFuncType( PyrexTypes.c_size_t_type, [ PyrexTypes.CFuncTypeArg("bytes", PyrexTypes.c_char_ptr_type, None) diff --git a/tests/run/iter.pyx b/tests/run/iter.pyx new file mode 100644 index 00000000..2748fdd9 --- /dev/null +++ b/tests/run/iter.pyx @@ -0,0 +1,27 @@ + +def call_iter1(x): + """ + >>> [ i for i in iter([1,2,3]) ] + [1, 2, 3] + >>> [ i for i in call_iter1([1,2,3]) ] + [1, 2, 3] + """ + return iter(x) + +class Ints(object): + def __init__(self): + self.i = 0 + def __call__(self): + self.i += 1 + if self.i > 10: + raise ValueError + return self.i + +def call_iter2(x, sentinel): + """ + >>> [ i for i in iter(Ints(), 3) ] + [1, 2] + >>> [ i for i in call_iter2(Ints(), 3) ] + [1, 2] + """ + return iter(x, sentinel) -- 2.26.2