@@ -143,21 +143,37 @@ def bitmap_sample(bitmap: AbstractBitMap, size: int) -> list[int]:
143143 return [bitmap [i ] for i in indices ]
144144
145145 def assert_is_not (self , bitmap1 : AbstractBitMap , bitmap2 : AbstractBitMap ) -> None :
146+ add1 = remove1 = add2 = remove2 = - 1
146147 if isinstance (bitmap1 , BitMap ):
147148 if bitmap1 :
148- bitmap1 .remove (bitmap1 [0 ])
149+ remove1 = bitmap1 [0 ]
150+ bitmap1 .remove (remove1 )
149151 else :
150- bitmap1 .add (27 )
152+ add1 = 27
153+ bitmap1 .add (add1 )
151154 elif isinstance (bitmap2 , BitMap ):
152155 if bitmap2 :
153- bitmap2 .remove (bitmap1 [0 ])
156+ remove2 = bitmap2 [0 ]
157+ bitmap2 .remove (remove2 )
154158 else :
155- bitmap2 .add (27 )
159+ add2 = 27
160+ bitmap2 .add (add2 )
156161 else : # The two are non-mutable, cannot do anything...
157162 return
158163 if bitmap1 == bitmap2 :
159164 pytest .fail (
160165 'The two bitmaps are identical (modifying one also modifies the other).' )
166+ # Restore the bitmaps to their original point
167+ else :
168+ if add1 >= 0 :
169+ bitmap1 .remove (add1 )
170+ if remove1 >= 0 :
171+ bitmap1 .add (remove1 )
172+ if add2 >= 0 :
173+ bitmap2 .remove (add2 )
174+ if remove2 >= 0 :
175+ bitmap2 .add (remove2 )
176+
161177
162178
163179class TestBasic (Util ):
@@ -874,6 +890,34 @@ def test_serialization(
874890 assert isinstance (new_bm , cls2 )
875891 self .assert_is_not (old_bm , new_bm )
876892
893+ @given (bitmap_cls , bitmap_cls , hyp_many_collections )
894+ def test_deserialization_from_memoryview (
895+ self ,
896+ cls1 : type [EitherBitMap ],
897+ cls2 : type [EitherBitMap ],
898+ values : list [HypCollection ]
899+ ) -> None :
900+ old_bms = [cls1 (vals ) for vals in values ]
901+
902+ # Create a memoryview with all of the items concatenated into a single bytes
903+ # object.
904+ serialized = [bm .serialize () for bm in old_bms ]
905+ sizes = [len (ser ) for ser in serialized ]
906+ starts = [0 ]
907+ for s in sizes :
908+ starts .append (s + starts [- 1 ])
909+
910+ combined = b'' .join (serialized )
911+ mutable_combined = bytearray (combined )
912+
913+ for source in (combined , mutable_combined ):
914+ with memoryview (source ) as mv :
915+ new_bms = [cls2 .deserialize (mv [start : start + size ])for start , size in zip (starts , sizes )]
916+ for old_bm , new_bm in zip (old_bms , new_bms ):
917+ assert old_bm == new_bm
918+ assert isinstance (new_bm , cls2 )
919+ self .assert_is_not (old_bm , new_bm )
920+
877921 @given (bitmap_cls , hyp_collection , st .integers (min_value = 2 , max_value = pickle .HIGHEST_PROTOCOL ))
878922 def test_pickle_protocol (
879923 self ,
0 commit comments