Commit c6177dfd authored by scoder's avatar scoder Committed by GitHub

Merge pull request #2583 from cjgibson/2508-slicing-fixes

Support two-element slicing with literal None
parents b1960185 459e108f
......@@ -4794,10 +4794,50 @@ class SliceIndexNode(ExprNode):
step=none_node
).analyse_types(env)
else:
from .UtilNodes import EvalWithTempExprNode, ResultRefNode
c_int = PyrexTypes.c_py_ssize_t_type
if self.start:
if self.start.type.is_pyobject:
start_ref = ResultRefNode(self.start)
start_expr = CondExprNode(
self.start.pos,
true_val = IntNode(
self.start.pos,
value = '0',
constant_result = 0
),
false_val = start_ref,
test = PrimaryCmpNode(
self.start.pos,
operand1 = start_ref,
operator = 'is',
operand2 = NoneNode(self.start.pos),
)
)
start_expr = start_expr.analyse_types(env)
start_expr = start_expr.coerce_to(c_int, env)
self.start = EvalWithTempExprNode(start_ref, start_expr)
self.start = self.start.coerce_to(c_int, env)
if self.stop:
if self.stop.type.is_pyobject:
stop_ref = ResultRefNode(self.stop)
stop_expr = CondExprNode(
self.stop.pos,
true_val = IntNode(
self.stop.pos,
value = 'PY_SSIZE_T_MAX'
),
false_val = stop_ref,
test = PrimaryCmpNode(
self.stop.pos,
operand1 = stop_ref,
operator = 'is',
operand2 = NoneNode(self.stop.pos),
)
)
stop_expr = stop_expr.analyse_types(env)
stop_expr = stop_expr.coerce_to(c_int, env)
self.stop = EvalWithTempExprNode(stop_ref, stop_expr)
self.stop = self.stop.coerce_to(c_int, env)
self.is_temp = 1
return self
......
# mode: run
# tag: slicing
# tag: list, slice, slicing
def test_full(seq):
"""
......@@ -18,21 +18,24 @@ def test_full(seq):
def test_start(seq, start):
"""
>>> test_start([1,2,3,4], 2)
>>> l = [1,2,3,4]
>>> test_start(l, 2)
[3, 4]
>>> test_start([1,2,3,4], 3)
>>> test_start(l, 3)
[4]
>>> test_start([1,2,3,4], 4)
>>> test_start(l, 4)
[]
>>> test_start([1,2,3,4], 8)
>>> test_start(l, 8)
[]
>>> test_start([1,2,3,4], -3)
>>> test_start(l, -3)
[2, 3, 4]
>>> test_start([1,2,3,4], -4)
>>> test_start(l, -4)
[1, 2, 3, 4]
>>> test_start(l, -8)
[1, 2, 3, 4]
>>> test_start([1,2,3,4], -8)
>>> test_start(l, 0)
[1, 2, 3, 4]
>>> test_start([1,2,3,4], 0)
>>> test_start(l, None)
[1, 2, 3, 4]
>>> try: test_start(42, 2, 3)
... except TypeError: pass
......@@ -42,24 +45,52 @@ def test_start(seq, start):
def test_stop(seq, stop):
"""
>>> test_stop([1,2,3,4], 3)
>>> l = [1,2,3,4]
>>> test_stop(l, 3)
[1, 2, 3]
>>> test_stop([1,2,3,4], -1)
>>> test_stop(l, -1)
[1, 2, 3]
>>> test_stop([1,2,3,4], -3)
>>> test_stop(l, -3)
[1]
>>> test_stop([1,2,3,4], -4)
>>> test_stop(l, -4)
[]
>>> test_stop([1,2,3,4], -8)
>>> test_stop(l, -8)
[]
>>> test_stop([1,2,3,4], 0)
>>> test_stop(l, 0)
[]
>>> test_stop(l, None)
[1, 2, 3, 4]
>>> try: test_stop(42, 3)
... except TypeError: pass
"""
obj = seq[:stop]
return obj
def test_step(seq, step):
"""
>>> l = [1,2,3,4]
>>> test_step(l, -1)
[4, 3, 2, 1]
>>> test_step(l, 1)
[1, 2, 3, 4]
>>> test_step(l, 2)
[1, 3]
>>> test_step(l, 3)
[1, 4]
>>> test_step(l, -3)
[4, 1]
>>> test_step(l, None)
[1, 2, 3, 4]
>>> try: test_step(l, 0)
... except ValueError: pass
...
>>> try: test_step(42, 0)
... except TypeError: pass
...
"""
obj = seq[::step]
return obj
def test_start_and_stop(seq, start, stop):
"""
>>> l = [1,2,3,4]
......@@ -67,12 +98,38 @@ def test_start_and_stop(seq, start, stop):
[3]
>>> test_start_and_stop(l, -3, -1)
[2, 3]
>>> test_start_and_stop(l, None, None)
[1, 2, 3, 4]
>>> try: test_start_and_stop(42, 2, 3)
... except TypeError: pass
"""
obj = seq[start:stop]
return obj
def test_start_stop_and_step(seq, start, stop, step):
"""
>>> l = [1,2,3,4,5]
>>> test_start_stop_and_step(l, 0, 5, 1)
[1, 2, 3, 4, 5]
>>> test_start_stop_and_step(l, 5, -1, -1)
[]
>>> test_start_stop_and_step(l, 5, None, -1)
[5, 4, 3, 2, 1]
>>> test_start_stop_and_step(l, 2, 5, 2)
[3, 5]
>>> test_start_stop_and_step(l, -100, 100, 1)
[1, 2, 3, 4, 5]
>>> test_start_stop_and_step(l, None, None, None)
[1, 2, 3, 4, 5]
>>> try: test_start_stop_and_step(l, None, None, 0)
... except ValueError: pass
...
>>> try: test_start_stop_and_step(42, 1, 2, 3)
... except TypeError: pass
"""
obj = seq[start:stop:step]
return obj
class A(object):
pass
......
This diff is collapsed.
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