diff --git a/tests/transformer/test_slice.py b/tests/transformer/test_slice.py new file mode 100644 index 0000000..36c6f5c --- /dev/null +++ b/tests/transformer/test_slice.py @@ -0,0 +1,23 @@ +from tests import e_eval + +import pytest + + +@pytest.mark.parametrize(*e_eval) +def test_slice(e_eval): + low = 1 + high = 4 + stride = 3 + + from operator import getitem + rgbl = dict(_getitem_=getitem) # restricted globals + + assert e_eval('[1, 2, 3, 4, 5]', rgbl) == [1, 2, 3, 4, 5] + assert e_eval('[1, 2, 3, 4, 5][:]', rgbl) == [1, 2, 3, 4, 5] + assert e_eval('[1, 2, 3, 4, 5][%d:]' % low, rgbl) == [2, 3, 4, 5] + assert e_eval('[1, 2, 3, 4, 5][:%d]' % high, rgbl) == [1, 2, 3, 4] + assert e_eval('[1, 2, 3, 4, 5][%d:%d]' % (low, high), rgbl) == [2, 3, 4] + assert e_eval('[1, 2, 3, 4, 5][::%d]' % stride, rgbl) == [1, 4] + assert e_eval('[1, 2, 3, 4, 5][%d::%d]' % (low, stride), rgbl) == [2, 5] + assert e_eval('[1, 2, 3, 4, 5][:%d:%d]' % (high, stride), rgbl) == [1, 4] + assert e_eval('[1, 2, 3, 4, 5][%d:%d:%d]' % (low, high, stride), rgbl) == [2] # NOQA: E501 diff --git a/tests/transformer/test_subscript.py b/tests/transformer/test_subscript.py new file mode 100644 index 0000000..6a74fc1 --- /dev/null +++ b/tests/transformer/test_subscript.py @@ -0,0 +1,172 @@ +from tests import e_exec + +import pytest + + +SIMPLE_SUBSCRIPTS = """ +def simple_subscript(a): + return a['b'] +""" + + +@pytest.mark.parametrize(*e_exec) +def test_read_simple_subscript(e_exec, mocker): + value = None + _getitem_ = mocker.stub() + _getitem_.side_effect = lambda ob, index: (ob, index) + glb = {'_getitem_': _getitem_} + e_exec(SIMPLE_SUBSCRIPTS, glb) + + assert (value, 'b') == glb['simple_subscript'](value) + + +TUPLE_SUBSCRIPTS = """ +def tuple_subscript(a): + return a[1, 2] +""" + + +@pytest.mark.parametrize(*e_exec) +def test_tuple_subscript(e_exec, mocker): + value = None + _getitem_ = mocker.stub() + _getitem_.side_effect = lambda ob, index: (ob, index) + glb = {'_getitem_': _getitem_} + e_exec(TUPLE_SUBSCRIPTS, glb) + + assert (value, (1, 2)) == glb['tuple_subscript'](value) + + +SLICE_SUBSCRIPT_NO_UPPER_BOUND = """ +def slice_subscript_no_upper_bound(a): + return a[1:] +""" + + +@pytest.mark.parametrize(*e_exec) +def test_read_slice_subscript_no_upper_bound(e_exec, mocker): + value = None + _getitem_ = mocker.stub() + _getitem_.side_effect = lambda ob, index: (ob, index) + glb = {'_getitem_': _getitem_} + e_exec(SLICE_SUBSCRIPT_NO_UPPER_BOUND, glb) + + assert (value, slice(1, None, None)) == glb['slice_subscript_no_upper_bound'](value) # NOQA: E501 + + +SLICE_SUBSCRIPT_NO_LOWER_BOUND = """ +def slice_subscript_no_lower_bound(a): + return a[:1] +""" + + +@pytest.mark.parametrize(*e_exec) +def test_read_slice_subscript_no_lower_bound(e_exec, mocker): + value = None + _getitem_ = mocker.stub() + _getitem_.side_effect = lambda ob, index: (ob, index) + glb = {'_getitem_': _getitem_} + e_exec(SLICE_SUBSCRIPT_NO_LOWER_BOUND, glb) + + assert (value, slice(None, 1, None)) == glb['slice_subscript_no_lower_bound'](value) # NOQA: E501 + + +SLICE_SUBSCRIPT_NO_STEP = """ +def slice_subscript_no_step(a): + return a[1:2] +""" + + +@pytest.mark.parametrize(*e_exec) +def test_read_slice_subscript_no_step(e_exec, mocker): + value = None + _getitem_ = mocker.stub() + _getitem_.side_effect = lambda ob, index: (ob, index) + glb = {'_getitem_': _getitem_} + e_exec(SLICE_SUBSCRIPT_NO_STEP, glb) + + assert (value, slice(1, 2, None)) == glb['slice_subscript_no_step'](value) + + +SLICE_SUBSCRIPT_WITH_STEP = """ +def slice_subscript_with_step(a): + return a[1:2:3] +""" + + +@pytest.mark.parametrize(*e_exec) +def test_read_slice_subscript_with_step(e_exec, mocker): + value = None + _getitem_ = mocker.stub() + _getitem_.side_effect = lambda ob, index: (ob, index) + glb = {'_getitem_': _getitem_} + e_exec(SLICE_SUBSCRIPT_WITH_STEP, glb) + + assert (value, slice(1, 2, 3)) == glb['slice_subscript_with_step'](value) + + +EXTENDED_SLICE_SUBSCRIPT = """ + +def extended_slice_subscript(a): + return a[0, :1, 1:, 1:2, 1:2:3] +""" + + +@pytest.mark.parametrize(*e_exec) +def test_read_extended_slice_subscript(e_exec, mocker): + value = None + _getitem_ = mocker.stub() + _getitem_.side_effect = lambda ob, index: (ob, index) + glb = {'_getitem_': _getitem_} + e_exec(EXTENDED_SLICE_SUBSCRIPT, glb) + ret = glb['extended_slice_subscript'](value) + ref = ( + value, + ( + 0, + slice(None, 1, None), + slice(1, None, None), + slice(1, 2, None), + slice(1, 2, 3) + ) + ) + + assert ref == ret + + +WRITE_SUBSCRIPTS = """ +def assign_subscript(a): + a['b'] = 1 +""" + + +@pytest.mark.parametrize(*e_exec) +def test_write_subscripts( + e_exec, mocker): + value = {'b': None} + _write_ = mocker.stub() + _write_.side_effect = lambda ob: ob + glb = {'_write_': _write_} + e_exec(WRITE_SUBSCRIPTS, glb) + + glb['assign_subscript'](value) + assert value['b'] == 1 + + +DEL_SUBSCRIPT = """ +def del_subscript(a): + del a['b'] +""" + + +@pytest.mark.parametrize(*e_exec) +def test_del_subscripts( + e_exec, mocker): + value = {'b': None} + _write_ = mocker.stub() + _write_.side_effect = lambda ob: ob + glb = {'_write_': _write_} + e_exec(DEL_SUBSCRIPT, glb) + glb['del_subscript'](value) + + assert value == {} diff --git a/tests/transformer/test_transformer.py b/tests/transformer/test_transformer.py index 521fd4c..19ff4fa 100644 --- a/tests/transformer/test_transformer.py +++ b/tests/transformer/test_transformer.py @@ -565,121 +565,6 @@ def test_transformer__RestrictingNodeTransformer__guard_iter2(e_exec, mocker): _getiter_.reset_mock() -GET_SUBSCRIPTS = """ -def simple_subscript(a): - return a['b'] - -def tuple_subscript(a): - return a[1, 2] - -def slice_subscript_no_upper_bound(a): - return a[1:] - -def slice_subscript_no_lower_bound(a): - return a[:1] - -def slice_subscript_no_step(a): - return a[1:2] - -def slice_subscript_with_step(a): - return a[1:2:3] - -def extended_slice_subscript(a): - return a[0, :1, 1:, 1:2, 1:2:3] -""" - - -@pytest.mark.parametrize(*e_exec) -def test_transformer__RestrictingNodeTransformer__visit_Subscript_1( - e_exec, mocker): - value = None - _getitem_ = mocker.stub() - _getitem_.side_effect = lambda ob, index: (ob, index) - glb = {'_getitem_': _getitem_} - e_exec(GET_SUBSCRIPTS, glb) - - ret = glb['simple_subscript'](value) - ref = (value, 'b') - assert ref == ret - _getitem_.assert_called_once_with(*ref) - _getitem_.reset_mock() - - ret = glb['tuple_subscript'](value) - ref = (value, (1, 2)) - assert ref == ret - _getitem_.assert_called_once_with(*ref) - _getitem_.reset_mock() - - ret = glb['slice_subscript_no_upper_bound'](value) - ref = (value, slice(1, None, None)) - assert ref == ret - _getitem_.assert_called_once_with(*ref) - _getitem_.reset_mock() - - ret = glb['slice_subscript_no_lower_bound'](value) - ref = (value, slice(None, 1, None)) - assert ref == ret - _getitem_.assert_called_once_with(*ref) - _getitem_.reset_mock() - - ret = glb['slice_subscript_no_step'](value) - ref = (value, slice(1, 2, None)) - assert ref == ret - _getitem_.assert_called_once_with(*ref) - _getitem_.reset_mock() - - ret = glb['slice_subscript_with_step'](value) - ref = (value, slice(1, 2, 3)) - assert ref == ret - _getitem_.assert_called_once_with(*ref) - _getitem_.reset_mock() - - ret = glb['extended_slice_subscript'](value) - ref = ( - value, - ( - 0, - slice(None, 1, None), - slice(1, None, None), - slice(1, 2, None), - slice(1, 2, 3) - ) - ) - - assert ref == ret - _getitem_.assert_called_once_with(*ref) - _getitem_.reset_mock() - - -WRITE_SUBSCRIPTS = """ -def assign_subscript(a): - a['b'] = 1 - -def del_subscript(a): - del a['b'] -""" - - -@pytest.mark.parametrize(*e_exec) -def test_transformer__RestrictingNodeTransformer__visit_Subscript_2( - e_exec, mocker): - value = {'b': None} - _write_ = mocker.stub() - _write_.side_effect = lambda ob: ob - glb = {'_write_': _write_} - e_exec(WRITE_SUBSCRIPTS, glb) - - glb['assign_subscript'](value) - assert value['b'] == 1 - _write_.assert_called_once_with(value) - _write_.reset_mock() - - glb['del_subscript'](value) - assert value == {} - _write_.assert_called_once_with(value) - _write_.reset_mock() - - @pytest.mark.parametrize(*e_exec) def test_transformer__RestrictingNodeTransformer__visit_AugAssign__1( e_exec, mocker):