From 9fd1dd05b81eed486e1eacfa44743a91c1ed24f0 Mon Sep 17 00:00:00 2001 From: hong <43953930+phlrain@users.noreply.github.com> Date: Tue, 9 Jun 2020 10:12:36 +0800 Subject: [PATCH] Fix get item out of range error (#24339) (#24943) * raise index error when slice out of range; test=develop * add uni test; test=develop * fix format error; test=develop * add comment for py::index_error; test=develop * polish error message; test=develop * polish error message; test=develop --- paddle/fluid/pybind/imperative.cc | 11 +++++++++++ python/paddle/fluid/tests/unittests/test_var_base.py | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/paddle/fluid/pybind/imperative.cc b/paddle/fluid/pybind/imperative.cc index 509a727ade..cc25e0fda1 100644 --- a/paddle/fluid/pybind/imperative.cc +++ b/paddle/fluid/pybind/imperative.cc @@ -322,7 +322,18 @@ static void ParseIndexingSlice(framework::LoDTensor *tensor, PyObject *_index, if (PyCheckInteger(slice_item)) { // integer, PyLong_AsLong supports both int and long int start = static_cast(PyLong_AsLong(slice_item)); + auto s_t = start; start = start < 0 ? start + dim_len : start; + if (start >= dim_len) { + std::string str_error_message = + "The starting index " + std::to_string(s_t) + + " of slice is out of bounds in tensor " + std::to_string(dim) + + "-th axis, it shound be in the range of [" + + std::to_string(-dim_len) + ", " + std::to_string(dim_len) + ")"; + // py::index_error is corresponding to IndexError in Python + // Used to indicate out of bounds access in __getitem__, __setitem__ + throw py::index_error(str_error_message); + } slice_axes->push_back(dim); slice_starts->push_back(start); slice_ends->push_back(start + 1); diff --git a/python/paddle/fluid/tests/unittests/test_var_base.py b/python/paddle/fluid/tests/unittests/test_var_base.py index 4dd41a1eb7..617970182a 100644 --- a/python/paddle/fluid/tests/unittests/test_var_base.py +++ b/python/paddle/fluid/tests/unittests/test_var_base.py @@ -181,14 +181,25 @@ class TestVarBase(unittest.TestCase): self.assertTrue( np.array_equal(local_out[15], tensor_array[::-1, ::-1, ::-1])) + def _test_for_var(self): + np_value = np.random.random((30, 100, 100)).astype('float32') + w = fluid.dygraph.to_variable(np_value) + + for i, e in enumerate(w): + self.assertTrue(np.array_equal(e.numpy(), np_value[i])) + def test_slice(self): with fluid.dygraph.guard(): self._test_slice() + self._test_for_var() var = fluid.dygraph.to_variable(self.array) self.assertTrue(np.array_equal(var[1, :].numpy(), self.array[1, :])) self.assertTrue(np.array_equal(var[::-1].numpy(), self.array[::-1])) + with self.assertRaises(IndexError): + y = var[self.shape[0]] + def test_var_base_to_np(self): with fluid.dygraph.guard(): var = fluid.dygraph.to_variable(self.array) -- GitLab