From 4592bc0a05fb7cb23d6d647c979931c176656efa Mon Sep 17 00:00:00 2001 From: Tino Wagner Date: Wed, 9 Nov 2022 01:14:22 +0100 Subject: [PATCH] Fix support of sequence protocol for returned lists (#730) * Fix support of sequence protocol for returned lists Add the `sequence` option to PyO3's `pyclass`, so that the `sq_length` slot is implemented [1]. Implementing this method is required for sequence types, or Python C API functions like `PySequence_Size` will fail with an error. The `reversed` built-in method relies on `PySequence_*` methods. A test reversing `NodeIndices` is added to guard against future violations of the sequence protocol. Fixes #696. [1]: https://github.com/PyO3/pyo3/pull/2567 * Add release note Co-authored-by: Matthew Treinish --- .../notes/fix-sequence-protocol-e95246e864cc850a.yaml | 10 ++++++++++ src/iterators.rs | 2 +- tests/rustworkx_tests/test_custom_return_types.py | 6 ++++++ 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/fix-sequence-protocol-e95246e864cc850a.yaml diff --git a/releasenotes/notes/fix-sequence-protocol-e95246e864cc850a.yaml b/releasenotes/notes/fix-sequence-protocol-e95246e864cc850a.yaml new file mode 100644 index 000000000..4bfb6fe37 --- /dev/null +++ b/releasenotes/notes/fix-sequence-protocol-e95246e864cc850a.yaml @@ -0,0 +1,10 @@ +--- +fixes: + - | + Fixed an issue with the custom sequence return types, + :class:`~.BFSSuccessors`, :class:`~.NodeIndices`, :class:`~.EdgeList`, + :class:`~.WeightedEdgeList`, :class:`~.EdgeIndices`, and :class:`~.Chains` + where they previosuly were missing certain attributes that prevented them + being used as a sequence for certain built-in functions such as + ``reversed()``. + Fixed `#696 `__. diff --git a/src/iterators.rs b/src/iterators.rs index 3a403d492..b6e496cc5 100644 --- a/src/iterators.rs +++ b/src/iterators.rs @@ -475,7 +475,7 @@ impl PyConvertToPyArray for Vec<(usize, usize, PyObject)> { macro_rules! custom_vec_iter_impl { ($name:ident, $data:ident, $T:ty, $doc:literal) => { #[doc = $doc] - #[pyclass(module = "rustworkx")] + #[pyclass(module = "rustworkx", sequence)] #[derive(Clone)] pub struct $name { pub $data: Vec<$T>, diff --git a/tests/rustworkx_tests/test_custom_return_types.py b/tests/rustworkx_tests/test_custom_return_types.py index 8abf87ae2..2362f125b 100644 --- a/tests/rustworkx_tests/test_custom_return_types.py +++ b/tests/rustworkx_tests/test_custom_return_types.py @@ -174,6 +174,12 @@ def test_slices_negatives(self): self.assertEqual([2, 3], slice_return) self.assertEqual([], indices[-1:-2]) + def test_reversed(self): + indices = self.dag.node_indices() + reversed_slice = indices[::-1] + reversed_elems = list(reversed(indices)) + self.assertEqual(reversed_slice, reversed_elems) + def test_numpy_conversion(self): res = self.dag.node_indexes() np.testing.assert_array_equal(np.asarray(res, dtype=np.uintp), np.array([0, 1]))