Commit 25432a57 authored by Stefan Behnel's avatar Stefan Behnel

implement tuple(genexp) as tuple(list(genexp))

parent ee2d4178
...@@ -1186,6 +1186,21 @@ class EarlyReplaceBuiltinCalls(Visitor.EnvTransform): ...@@ -1186,6 +1186,21 @@ class EarlyReplaceBuiltinCalls(Visitor.EnvTransform):
gen_expr_node.pos, loop = exec_code, result_node = result_ref, gen_expr_node.pos, loop = exec_code, result_node = result_ref,
expr_scope = gen_expr_node.expr_scope, orig_func = 'sum') expr_scope = gen_expr_node.expr_scope, orig_func = 'sum')
def _handle_simple_function_tuple(self, node, pos_args):
if len(pos_args) == 0:
return ExprNodes.TupleNode(node.pos, args=[], constant_result=())
# This is a bit special - for iterables (including genexps),
# Python actually overallocates and resizes a newly created
# tuple incrementally while reading items, which we can't
# easily do without explicit node support. Instead, we read
# the items into a list and then copy them into a tuple of the
# final size. This takes up to twice as much memory, but will
# have to do until we have real support for genexps.
result = self._transform_list_set_genexpr(node, pos_args, ExprNodes.ListNode)
if result is not node:
return ExprNodes.AsTupleNode(node.pos, arg=result)
return node
def _handle_simple_function_list(self, node, pos_args): def _handle_simple_function_list(self, node, pos_args):
if len(pos_args) == 0: if len(pos_args) == 0:
return ExprNodes.ListNode(node.pos, args=[], constant_result=[]) return ExprNodes.ListNode(node.pos, args=[], constant_result=[])
......
cimport cython cimport cython
def range_tuple_genexp(int N):
"""
>>> range_tuple_genexp(5)
(0, 1, 2, 3, 4)
"""
return tuple(i for i in range(N))
@cython.test_assert_path_exists('//ForFromStatNode', @cython.test_assert_path_exists('//ForFromStatNode',
"//InlinedGeneratorExpressionNode") "//InlinedGeneratorExpressionNode")
@cython.test_fail_if_path_exists('//SimpleCallNode', @cython.test_fail_if_path_exists('//SimpleCallNode',
...@@ -15,6 +23,7 @@ def range_sum(int N): ...@@ -15,6 +23,7 @@ def range_sum(int N):
result = sum(i for i in range(N)) result = sum(i for i in range(N))
return result return result
@cython.test_assert_path_exists('//ForFromStatNode', @cython.test_assert_path_exists('//ForFromStatNode',
"//InlinedGeneratorExpressionNode") "//InlinedGeneratorExpressionNode")
@cython.test_fail_if_path_exists('//SimpleCallNode', @cython.test_fail_if_path_exists('//SimpleCallNode',
...@@ -30,6 +39,7 @@ def range_sum_typed(int N): ...@@ -30,6 +39,7 @@ def range_sum_typed(int N):
cdef int result = sum(i for i in range(N)) cdef int result = sum(i for i in range(N))
return result return result
@cython.test_assert_path_exists('//ForFromStatNode', @cython.test_assert_path_exists('//ForFromStatNode',
"//InlinedGeneratorExpressionNode", "//InlinedGeneratorExpressionNode",
"//ReturnStatNode//InlinedGeneratorExpressionNode", "//ReturnStatNode//InlinedGeneratorExpressionNode",
...@@ -47,6 +57,7 @@ def return_range_sum_cast(int N): ...@@ -47,6 +57,7 @@ def return_range_sum_cast(int N):
""" """
return <int>sum(i for i in range(N)) return <int>sum(i for i in range(N))
@cython.test_assert_path_exists('//ForFromStatNode', @cython.test_assert_path_exists('//ForFromStatNode',
"//InlinedGeneratorExpressionNode") "//InlinedGeneratorExpressionNode")
@cython.test_fail_if_path_exists('//SimpleCallNode', @cython.test_fail_if_path_exists('//SimpleCallNode',
...@@ -60,6 +71,7 @@ def return_range_sum(int N): ...@@ -60,6 +71,7 @@ def return_range_sum(int N):
""" """
return sum(i for i in range(N)) return sum(i for i in range(N))
@cython.test_assert_path_exists('//ForFromStatNode', @cython.test_assert_path_exists('//ForFromStatNode',
"//InlinedGeneratorExpressionNode") "//InlinedGeneratorExpressionNode")
@cython.test_fail_if_path_exists('//SimpleCallNode', @cython.test_fail_if_path_exists('//SimpleCallNode',
...@@ -78,6 +90,7 @@ def return_range_sum_squares(int N): ...@@ -78,6 +90,7 @@ def return_range_sum_squares(int N):
""" """
return sum(i*i for i in range(N)) return sum(i*i for i in range(N))
@cython.test_assert_path_exists('//ForInStatNode', @cython.test_assert_path_exists('//ForInStatNode',
"//InlinedGeneratorExpressionNode") "//InlinedGeneratorExpressionNode")
@cython.test_fail_if_path_exists('//SimpleCallNode') @cython.test_fail_if_path_exists('//SimpleCallNode')
...@@ -95,6 +108,7 @@ def return_sum_squares(seq): ...@@ -95,6 +108,7 @@ def return_sum_squares(seq):
""" """
return sum(i*i for i in seq) return sum(i*i for i in seq)
@cython.test_assert_path_exists('//ForInStatNode', @cython.test_assert_path_exists('//ForInStatNode',
"//InlinedGeneratorExpressionNode") "//InlinedGeneratorExpressionNode")
@cython.test_fail_if_path_exists('//SimpleCallNode') @cython.test_fail_if_path_exists('//SimpleCallNode')
......
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