From f3cc686d20f328968f91d6192ce913a487adbcb0 Mon Sep 17 00:00:00 2001 From: Tom Cornebize Date: Sat, 10 Feb 2024 23:34:30 +0100 Subject: [PATCH] Fix in-place operations with self (#115) --- pyroaring/bitmap.pxi | 10 ++++++++++ test.py | 15 +++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/pyroaring/bitmap.pxi b/pyroaring/bitmap.pxi index 81ac0fe..860c665 100644 --- a/pyroaring/bitmap.pxi +++ b/pyroaring/bitmap.pxi @@ -112,18 +112,28 @@ cdef class BitMap(AbstractBitMap): def __ior__(self, other): self._check_compatibility(other) + if self._c_bitmap == (other)._c_bitmap: + return self return (self).binary_iop(other, croaring.roaring_bitmap_or_inplace) def __iand__(self, other): self._check_compatibility(other) + if self._c_bitmap == (other)._c_bitmap: + return self return (self).binary_iop(other, croaring.roaring_bitmap_and_inplace) def __ixor__(self, other): self._check_compatibility(other) + if self._c_bitmap == (other)._c_bitmap: + self.clear() + return self return (self).binary_iop(other, croaring.roaring_bitmap_xor_inplace) def __isub__(self, other): self._check_compatibility(other) + if self._c_bitmap == (other)._c_bitmap: + self.clear() + return self return (self).binary_iop(other, croaring.roaring_bitmap_andnot_inplace) def intersection_update(self, *all_values): # FIXME could be more efficient diff --git a/test.py b/test.py index 96b5425..ebb1e1c 100755 --- a/test.py +++ b/test.py @@ -491,6 +491,21 @@ def test_binary_op_inplace( assert self.bitmap2 == old_bitmap2 self.compare_with_set(self.bitmap1, self.set1) + @given(hyp_collection, st.booleans()) + def test_binary_op_inplace_self( + self, + values: HypCollection, + cow: bool, + ) -> None: + for op in [operator.ior, operator.iand, operator.ixor, operator.isub]: + self.set = set(values) + self.bitmap = BitMap(values, cow) + original = self.bitmap + op(self.set, self.set) + op(self.bitmap, self.bitmap) + assert original is self.bitmap + self.compare_with_set(self.bitmap, self.set) + @given(bitmap_cls, hyp_collection, hyp_collection, st.booleans()) def test_binary_op_inplace_frozen( self,