this repo has no description
at trunk 202 lines 6.6 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include "Python.h" 3#include "gtest/gtest.h" 4 5#include "capi-fixture.h" 6#include "capi-testing.h" 7 8namespace py { 9namespace testing { 10 11using SliceExtensionApiTest = ExtensionApi; 12 13TEST_F(SliceExtensionApiTest, NewReturnsSlice) { 14 PyObjectPtr slice(PySlice_New(nullptr, nullptr, nullptr)); 15 EXPECT_TRUE(PySlice_Check(slice)); 16} 17 18TEST_F(SliceExtensionApiTest, AdjustIndicesReturnsSliceLength) { 19 Py_ssize_t length = 10; 20 Py_ssize_t start = 2; 21 Py_ssize_t stop = -1; 22 Py_ssize_t step = 3; 23 Py_ssize_t slice_length = PySlice_AdjustIndices(length, &start, &stop, step); 24 EXPECT_EQ(slice_length, 3); 25 EXPECT_EQ(start, 2); 26 EXPECT_EQ(stop, 9); 27} 28 29TEST_F(SliceExtensionApiTest, AdjustIndicesWithNegativeShifts) { 30 Py_ssize_t length = 5; 31 Py_ssize_t start = -4; 32 Py_ssize_t stop = -1; 33 Py_ssize_t step = 1; 34 Py_ssize_t slice_length = PySlice_AdjustIndices(length, &start, &stop, step); 35 EXPECT_EQ(slice_length, 3); 36 EXPECT_EQ(start, 1); 37 EXPECT_EQ(stop, 4); 38} 39 40TEST_F(SliceExtensionApiTest, 41 AdjustIndicesWithLargeNegativesAndPositiveStepSetsZero) { 42 Py_ssize_t length = 5; 43 Py_ssize_t start = -40; 44 Py_ssize_t stop = -10; 45 Py_ssize_t step = 2; 46 Py_ssize_t slice_length = PySlice_AdjustIndices(length, &start, &stop, step); 47 EXPECT_EQ(slice_length, 0); 48 EXPECT_EQ(start, 0); 49 EXPECT_EQ(stop, 0); 50} 51 52TEST_F(SliceExtensionApiTest, 53 AdjustIndicesWithLargeNegativesAndNegativeStepSetsNegativeOne) { 54 Py_ssize_t length = 5; 55 Py_ssize_t start = -40; 56 Py_ssize_t stop = -100; 57 Py_ssize_t step = -2; 58 Py_ssize_t slice_length = PySlice_AdjustIndices(length, &start, &stop, step); 59 EXPECT_EQ(slice_length, 0); 60 EXPECT_EQ(start, -1); 61 EXPECT_EQ(stop, -1); 62} 63 64TEST_F(SliceExtensionApiTest, AdjustIndicesWithLargeIndicesSetsLength) { 65 Py_ssize_t length = 5; 66 Py_ssize_t start = 8; 67 Py_ssize_t stop = 10; 68 Py_ssize_t step = 1; 69 Py_ssize_t slice_length = PySlice_AdjustIndices(length, &start, &stop, step); 70 EXPECT_EQ(slice_length, 0); 71 EXPECT_EQ(start, 5); 72 EXPECT_EQ(stop, 5); 73} 74 75TEST_F(SliceExtensionApiTest, 76 AdjustIndicesWithLargeIndicesAndNegativeStepSetsOffsetLength) { 77 Py_ssize_t length = 5; 78 Py_ssize_t start = 8; 79 Py_ssize_t stop = 10; 80 Py_ssize_t step = -1; 81 Py_ssize_t slice_length = PySlice_AdjustIndices(length, &start, &stop, step); 82 EXPECT_EQ(slice_length, 0); 83 EXPECT_EQ(start, 4); 84 EXPECT_EQ(stop, 4); 85} 86 87TEST_F(SliceExtensionApiTest, GetIndicesExWithUnpackErrorRaisesValueError) { 88 PyObjectPtr zero(PyLong_FromLong(0)); 89 PyObjectPtr slice(PySlice_New(nullptr, nullptr, zero)); 90 Py_ssize_t length = 0; 91 Py_ssize_t start, stop, step, slicelength; 92 int result = 93 PySlice_GetIndicesEx(slice, length, &start, &stop, &step, &slicelength); 94 ASSERT_EQ(result, -1); 95 ASSERT_NE(PyErr_Occurred(), nullptr); 96 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_ValueError)); 97} 98 99TEST_F(SliceExtensionApiTest, GetIndicesExWithUnpackSuccessSetsValues) { 100 PyObjectPtr two(PyLong_FromLong(2)); 101 PyObjectPtr slice(PySlice_New(nullptr, nullptr, two)); 102 Py_ssize_t length = 10; 103 Py_ssize_t start, stop, step, slicelength; 104 int result = 105 PySlice_GetIndicesEx(slice, length, &start, &stop, &step, &slicelength); 106 ASSERT_EQ(result, 0); 107 ASSERT_EQ(PyErr_Occurred(), nullptr); 108 EXPECT_EQ(start, 0); 109 EXPECT_EQ(stop, 10); 110 EXPECT_EQ(step, 2); 111 EXPECT_EQ(slicelength, 5); 112} 113 114TEST_F(SliceExtensionApiTest, UnpackWithNonSliceRaisesSystemErrorPyro) { 115 PyObjectPtr num(PyLong_FromLong(0)); 116 Py_ssize_t start, stop, step; 117 ASSERT_EQ(PySlice_Unpack(num, &start, &stop, &step), -1); 118 ASSERT_NE(PyErr_Occurred(), nullptr); 119 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 120} 121 122TEST_F(SliceExtensionApiTest, UnpackWithNonIndexStartRaisesTypeError) { 123 PyObjectPtr list(PyList_New(0)); 124 PyObjectPtr slice(PySlice_New(list, nullptr, nullptr)); 125 Py_ssize_t start, stop, step; 126 ASSERT_EQ(PySlice_Unpack(slice, &start, &stop, &step), -1); 127 ASSERT_NE(PyErr_Occurred(), nullptr); 128 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 129} 130 131TEST_F(SliceExtensionApiTest, UnpackWithNonIndexStopRaisesTypeError) { 132 PyObjectPtr list(PyList_New(0)); 133 PyObjectPtr slice(PySlice_New(nullptr, list, nullptr)); 134 Py_ssize_t start, stop, step; 135 ASSERT_EQ(PySlice_Unpack(slice, &start, &stop, &step), -1); 136 ASSERT_NE(PyErr_Occurred(), nullptr); 137 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 138} 139 140TEST_F(SliceExtensionApiTest, UnpackWithNonIndexStepRaisesTypeError) { 141 PyObjectPtr list(PyList_New(0)); 142 PyObjectPtr slice(PySlice_New(nullptr, nullptr, list)); 143 Py_ssize_t start, stop, step; 144 ASSERT_EQ(PySlice_Unpack(slice, &start, &stop, &step), -1); 145 ASSERT_NE(PyErr_Occurred(), nullptr); 146 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 147} 148 149TEST_F(SliceExtensionApiTest, UnpackWithZeroStepRaisesTypeError) { 150 PyObjectPtr zero(PyLong_FromLong(0)); 151 PyObjectPtr slice(PySlice_New(nullptr, nullptr, zero)); 152 Py_ssize_t start, stop, step; 153 ASSERT_EQ(PySlice_Unpack(slice, &start, &stop, &step), -1); 154 ASSERT_NE(PyErr_Occurred(), nullptr); 155 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_ValueError)); 156} 157 158TEST_F(SliceExtensionApiTest, UnpackWithNoneSetsDefaults) { 159 PyObjectPtr slice(PySlice_New(nullptr, nullptr, nullptr)); 160 Py_ssize_t start, stop, step; 161 ASSERT_EQ(PySlice_Unpack(slice, &start, &stop, &step), 0); 162 ASSERT_EQ(PyErr_Occurred(), nullptr); 163 EXPECT_EQ(start, 0); 164 EXPECT_GT(stop, 1 << 30); // Arbitrary large value less than 165 // PY_SSIZE_T_MAX and SmallInt::kMaxValue 166 EXPECT_EQ(step, 1); 167} 168 169TEST_F(SliceExtensionApiTest, UnpackWithNonIntCallsDunderIndex) { 170 PyRun_SimpleString(R"( 171class Foo: 172 def __init__(self): self.bar = 0 173 def __index__(self): 174 self.bar += 1 175 return self.bar 176foo = Foo() 177)"); 178 PyObjectPtr foo(mainModuleGet("foo")); 179 PyObjectPtr slice(PySlice_New(foo, foo, foo)); 180 Py_ssize_t start, stop, step; 181 ASSERT_EQ(PySlice_Unpack(slice, &start, &stop, &step), 0); 182 ASSERT_EQ(PyErr_Occurred(), nullptr); 183 EXPECT_EQ(start, 2); 184 EXPECT_EQ(stop, 3); 185 EXPECT_EQ(step, 1); 186} 187 188TEST_F(SliceExtensionApiTest, UnpackWithIndicesSetsValues) { 189 PyObjectPtr idx1(PyLong_FromLong(1024)); 190 PyObjectPtr idx2(PyLong_FromLong(-42)); 191 PyObjectPtr idx3(PyLong_FromLong(10)); 192 PyObjectPtr slice(PySlice_New(idx1, idx2, idx3)); 193 Py_ssize_t start, stop, step; 194 ASSERT_EQ(PySlice_Unpack(slice, &start, &stop, &step), 0); 195 ASSERT_EQ(PyErr_Occurred(), nullptr); 196 EXPECT_EQ(start, 1024); 197 EXPECT_GE(stop, -42); 198 EXPECT_EQ(step, 10); 199} 200 201} // namespace testing 202} // namespace py