datahold 4.0.0.dev40__tar.gz → 4.0.0.dev42__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. {datahold-4.0.0.dev40 → datahold-4.0.0.dev42}/PKG-INFO +1 -1
  2. {datahold-4.0.0.dev40 → datahold-4.0.0.dev42}/pyproject.toml +1 -1
  3. {datahold-4.0.0.dev40 → datahold-4.0.0.dev42}/src/datahold/__init__.py +32 -14
  4. {datahold-4.0.0.dev40 → datahold-4.0.0.dev42}/src/datahold.egg-info/PKG-INFO +1 -1
  5. {datahold-4.0.0.dev40 → datahold-4.0.0.dev42}/tests/test_MutableListSlot.py +243 -124
  6. {datahold-4.0.0.dev40 → datahold-4.0.0.dev42}/LICENSE.txt +0 -0
  7. {datahold-4.0.0.dev40 → datahold-4.0.0.dev42}/MANIFEST.in +0 -0
  8. {datahold-4.0.0.dev40 → datahold-4.0.0.dev42}/README.rst +0 -0
  9. {datahold-4.0.0.dev40 → datahold-4.0.0.dev42}/docs/v1.1.rst +0 -0
  10. {datahold-4.0.0.dev40 → datahold-4.0.0.dev42}/docs/v1.2.rst +0 -0
  11. {datahold-4.0.0.dev40 → datahold-4.0.0.dev42}/docs/v2.0.rst +0 -0
  12. {datahold-4.0.0.dev40 → datahold-4.0.0.dev42}/docs/v2.1.rst +0 -0
  13. {datahold-4.0.0.dev40 → datahold-4.0.0.dev42}/docs/v2.2.rst +0 -0
  14. {datahold-4.0.0.dev40 → datahold-4.0.0.dev42}/docs/v2.3.rst +0 -0
  15. {datahold-4.0.0.dev40 → datahold-4.0.0.dev42}/docs/v3.0.rst +0 -0
  16. {datahold-4.0.0.dev40 → datahold-4.0.0.dev42}/run_tests.py +0 -0
  17. {datahold-4.0.0.dev40 → datahold-4.0.0.dev42}/setup.cfg +0 -0
  18. {datahold-4.0.0.dev40 → datahold-4.0.0.dev42}/src/datahold/py.typed +0 -0
  19. {datahold-4.0.0.dev40 → datahold-4.0.0.dev42}/src/datahold.egg-info/SOURCES.txt +0 -0
  20. {datahold-4.0.0.dev40 → datahold-4.0.0.dev42}/src/datahold.egg-info/dependency_links.txt +0 -0
  21. {datahold-4.0.0.dev40 → datahold-4.0.0.dev42}/src/datahold.egg-info/requires.txt +0 -0
  22. {datahold-4.0.0.dev40 → datahold-4.0.0.dev42}/src/datahold.egg-info/top_level.txt +0 -0
  23. {datahold-4.0.0.dev40 → datahold-4.0.0.dev42}/tests/testdata.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datahold
3
- Version: 4.0.0.dev40
3
+ Version: 4.0.0.dev42
4
4
  Summary: This project wraps common mutable datastructures for inheritance with modification.
5
5
  Author-email: Johannes <johannes.programming@gmail.com>
6
6
  License-Expression: MIT
@@ -34,7 +34,7 @@ license-files = [
34
34
  name = "datahold"
35
35
  readme = "README.rst"
36
36
  requires-python = ">=3.12"
37
- version = "4.0.0.dev40"
37
+ version = "4.0.0.dev42"
38
38
 
39
39
  [project.urls]
40
40
  Download = "https://pypi.org/project/datahold/#files"
@@ -30,10 +30,28 @@ class SupportsDunderLT[Other](Protocol):
30
30
  type Slice[Index] = slice[Index | None, Index | None, Index | None]
31
31
  type Sort = SupportsDunderGT[Self] | SupportsDunderGT[Self] # type: ignore[misc]
32
32
 
33
+
34
+ ### HELPER ###
35
+
36
+
37
+ def reverse_sequence[Item](
38
+ sequence: MutableListSlot[Item],
39
+ length: int,
40
+ ) -> abc.Generator[Item, None, None]:
41
+ frozen: tuple[Item, ...]
42
+ while True:
43
+ frozen = sequence.__frozen__()
44
+ length -= 1
45
+ if 0 <= length < len(frozen):
46
+ yield frozen[length]
47
+ else:
48
+ break
49
+
50
+
33
51
  ### LIST-SLOT ###
34
52
 
35
53
 
36
- class MutableListSlot[Item]:
54
+ class MutableListSlot[Item](abc.Sequence[Item]):
37
55
  """Provide easily customized, slotted, mutable list-like."""
38
56
 
39
57
  __slots__ = ("_slot",)
@@ -140,15 +158,16 @@ class MutableListSlot[Item]:
140
158
  def __iter__(
141
159
  self: MutableListSlot[Item], /
142
160
  ) -> abc.Generator[Item, None, None]:
161
+ frozen: tuple[Item, ...]
143
162
  i: int
144
163
  i = 0
145
164
  while True:
146
- try:
147
- v = self[i]
148
- except IndexError:
149
- return
150
- yield v
151
- i += 1
165
+ frozen = self.__frozen__()
166
+ if i < len(frozen):
167
+ yield frozen[i]
168
+ i += 1
169
+ else:
170
+ break
152
171
 
153
172
  def __le__(
154
173
  self: MutableListSlot[Item],
@@ -186,12 +205,11 @@ class MutableListSlot[Item]:
186
205
  def __repr__(self: MutableListSlot[Item], /) -> str:
187
206
  return f"{type(self).__name__}({list(self.__frozen__())})"
188
207
 
189
- def __reversed__(
190
- self: MutableListSlot[Item], /
191
- ) -> abc.Generator[Item, None, None]:
192
- i: int
193
- for i in reversed(range(len(self))):
194
- yield self[i]
208
+ def __reversed__(self: MutableListSlot[Item], /) -> abc.Iterator[Item]:
209
+ return reverse_sequence(
210
+ sequence=self,
211
+ length=len(self.__frozen__()),
212
+ )
195
213
 
196
214
  @overload
197
215
  def __setitem__(
@@ -301,4 +319,4 @@ class MutableListSlot[Item]:
301
319
 
302
320
  setdoc.Basics(
303
321
  excepts=(AttributeError, TypeError),
304
- )(*MutableListSlot.__dict__)
322
+ )(*MutableListSlot.__dict__.values())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datahold
3
- Version: 4.0.0.dev40
3
+ Version: 4.0.0.dev42
4
4
  Summary: This project wraps common mutable datastructures for inheritance with modification.
5
5
  Author-email: Johannes <johannes.programming@gmail.com>
6
6
  License-Expression: MIT
@@ -16,20 +16,22 @@ __all__: list[str] = [
16
16
  "TestMethodReverse",
17
17
  "TestMethodSort",
18
18
  "TestOperatorAdd",
19
+ "TestOperatorContains",
20
+ "TestOperatorDelItem",
21
+ "TestOperatorEqual",
22
+ "TestOperatorGetItem",
23
+ "TestOperatorGreaterThan",
24
+ "TestOperatorGreaterThanOrEqual",
19
25
  "TestOperatorIAdd",
20
- "TestOperatorMul",
21
- "TestOperatorRMul",
22
26
  "TestOperatorIMul",
23
- "TestOperatorEqual",
24
- "TestOperatorNotEqual",
27
+ "TestOperatorIterSequence",
25
28
  "TestOperatorLessThan",
26
29
  "TestOperatorLessThanOrEqual",
27
- "TestOperatorGreaterThan",
28
- "TestOperatorGreaterThanOrEqual",
29
- "TestOperatorContains",
30
- "TestOperatorGetItem",
30
+ "TestOperatorMul",
31
+ "TestOperatorNotEqual",
32
+ "TestOperatorRMul",
33
+ "TestOperatorReversedSequence",
31
34
  "TestOperatorSetItem",
32
- "TestOperatorDelItem",
33
35
  ]
34
36
 
35
37
 
@@ -293,6 +295,103 @@ class TestOperatorAdd(unittest.TestCase):
293
295
  self.assertEqual(list(value), [1, 2])
294
296
 
295
297
 
298
+ class TestOperatorContains(unittest.TestCase):
299
+ def test_contains_first_element(self: Self, /) -> None:
300
+ self.assertTrue(1 in MutableListSlot([1, 2, 3]))
301
+
302
+ def test_contains_last_element(self: Self, /) -> None:
303
+ self.assertTrue(3 in MutableListSlot([1, 2, 3]))
304
+
305
+ def test_does_not_contain_missing_element(self: Self, /) -> None:
306
+ self.assertFalse(4 in MutableListSlot([1, 2, 3]))
307
+
308
+ def test_empty_slot_contains_nothing(self: Self, /) -> None:
309
+ self.assertFalse(1 in MutableListSlot([]))
310
+
311
+
312
+ class TestOperatorDelItem(unittest.TestCase):
313
+ def test_delete_first_item(self: Self, /) -> None:
314
+ value = MutableListSlot([1, 2, 3])
315
+ del value[0]
316
+ self.assertEqual(list(value), [2, 3])
317
+
318
+ def test_delete_last_item(self: Self, /) -> None:
319
+ value = MutableListSlot([1, 2, 3])
320
+ del value[-1]
321
+ self.assertEqual(list(value), [1, 2])
322
+
323
+ def test_delete_slice(self: Self, /) -> None:
324
+ value = MutableListSlot([1, 2, 3, 4])
325
+ del value[1:3]
326
+ self.assertEqual(list(value), [1, 4])
327
+
328
+ def test_delete_out_of_range_raises(self: Self, /) -> None:
329
+ value = MutableListSlot([1, 2])
330
+ with self.assertRaises(IndexError):
331
+ del value[5]
332
+
333
+
334
+ class TestOperatorEqual(unittest.TestCase):
335
+ def test_equal_same_contents(self: Self, /) -> None:
336
+ self.assertTrue(MutableListSlot([1, 2]) == MutableListSlot([1, 2]))
337
+
338
+ def test_equal_empty_lists(self: Self, /) -> None:
339
+ self.assertTrue(MutableListSlot([]) == MutableListSlot([]))
340
+
341
+ def test_not_equal_different_values(self: Self, /) -> None:
342
+ self.assertFalse(MutableListSlot([1, 2]) == MutableListSlot([1, 3]))
343
+
344
+ def test_not_equal_different_lengths(self: Self, /) -> None:
345
+ self.assertFalse(MutableListSlot([1, 2]) == MutableListSlot([1, 2, 3]))
346
+
347
+
348
+ class TestOperatorGetItem(unittest.TestCase):
349
+ def test_get_first_item(self: Self, /) -> None:
350
+ value = MutableListSlot([10, 20, 30])
351
+ self.assertEqual(value[0], 10)
352
+
353
+ def test_get_last_item_with_negative_index(self: Self, /) -> None:
354
+ value = MutableListSlot([10, 20, 30])
355
+ self.assertEqual(value[-1], 30)
356
+
357
+ def test_get_slice(self: Self, /) -> None:
358
+ value = MutableListSlot([1, 2, 3, 4])
359
+ self.assertEqual(value[1:3], MutableListSlot([2, 3]))
360
+
361
+ def test_out_of_range_index_raises(self: Self, /) -> None:
362
+ value = MutableListSlot([1, 2])
363
+ with self.assertRaises(IndexError):
364
+ value[5]
365
+
366
+
367
+ class TestOperatorGreaterThan(unittest.TestCase):
368
+ def test_greater_than_by_first_element(self: Self, /) -> None:
369
+ self.assertTrue(MutableListSlot([2, 0]) > MutableListSlot([1, 9]))
370
+
371
+ def test_greater_than_by_later_element(self: Self, /) -> None:
372
+ self.assertTrue(MutableListSlot([1, 3]) > MutableListSlot([1, 2]))
373
+
374
+ def test_longer_list_is_greater_than_prefix(self: Self, /) -> None:
375
+ self.assertTrue(MutableListSlot([1, 2, 3]) > MutableListSlot([1, 2]))
376
+
377
+ def test_equal_list_is_not_greater_than(self: Self, /) -> None:
378
+ self.assertFalse(MutableListSlot([1, 2]) > MutableListSlot([1, 2]))
379
+
380
+
381
+ class TestOperatorGreaterThanOrEqual(unittest.TestCase):
382
+ def test_greater_value_is_greater_or_equal(self: Self, /) -> None:
383
+ self.assertTrue(MutableListSlot([2]) >= MutableListSlot([1]))
384
+
385
+ def test_equal_value_is_greater_or_equal(self: Self, /) -> None:
386
+ self.assertTrue(MutableListSlot([1, 2]) >= MutableListSlot([1, 2]))
387
+
388
+ def test_longer_list_is_greater_or_equal_to_prefix(self: Self, /) -> None:
389
+ self.assertTrue(MutableListSlot([1, 2]) >= MutableListSlot([1]))
390
+
391
+ def test_smaller_value_is_not_greater_or_equal(self: Self, /) -> None:
392
+ self.assertFalse(MutableListSlot([1]) >= MutableListSlot([2]))
393
+
394
+
296
395
  class TestOperatorIAdd(unittest.TestCase):
297
396
  def test_iadd_nonempty_list(self: Self, /) -> None:
298
397
  value = MutableListSlot([1, 2])
@@ -316,6 +415,34 @@ class TestOperatorIAdd(unittest.TestCase):
316
415
  self.assertEqual(list(value), [1, 2, 3])
317
416
 
318
417
 
418
+ class TestOperatorLessThan(unittest.TestCase):
419
+ def test_less_than_by_first_element(self: Self, /) -> None:
420
+ self.assertTrue(MutableListSlot([1, 9]) < MutableListSlot([2, 0]))
421
+
422
+ def test_less_than_by_later_element(self: Self, /) -> None:
423
+ self.assertTrue(MutableListSlot([1, 2]) < MutableListSlot([1, 3]))
424
+
425
+ def test_prefix_is_less_than_longer_list(self: Self, /) -> None:
426
+ self.assertTrue(MutableListSlot([1, 2]) < MutableListSlot([1, 2, 3]))
427
+
428
+ def test_equal_list_is_not_less_than(self: Self, /) -> None:
429
+ self.assertFalse(MutableListSlot([1, 2]) < MutableListSlot([1, 2]))
430
+
431
+
432
+ class TestOperatorLessThanOrEqual(unittest.TestCase):
433
+ def test_less_value_is_less_or_equal(self: Self, /) -> None:
434
+ self.assertTrue(MutableListSlot([1]) <= MutableListSlot([2]))
435
+
436
+ def test_equal_value_is_less_or_equal(self: Self, /) -> None:
437
+ self.assertTrue(MutableListSlot([1, 2]) <= MutableListSlot([1, 2]))
438
+
439
+ def test_prefix_is_less_or_equal(self: Self, /) -> None:
440
+ self.assertTrue(MutableListSlot([1]) <= MutableListSlot([1, 2]))
441
+
442
+ def test_greater_value_is_not_less_or_equal(self: Self, /) -> None:
443
+ self.assertFalse(MutableListSlot([2]) <= MutableListSlot([1]))
444
+
445
+
319
446
  class TestOperatorMul(unittest.TestCase):
320
447
  def test_multiply_by_positive_integer(self: Self, /) -> None:
321
448
  result = MutableListSlot([1, 2]) * 3
@@ -334,24 +461,6 @@ class TestOperatorMul(unittest.TestCase):
334
461
  self.assertEqual(list(result), [])
335
462
 
336
463
 
337
- class TestOperatorRMul(unittest.TestCase):
338
- def test_rmul_by_positive_integer(self: Self, /) -> None:
339
- result = 3 * MutableListSlot([1, 2])
340
- self.assertEqual(list(result), [1, 2, 1, 2, 1, 2])
341
-
342
- def test_rmul_by_one(self: Self, /) -> None:
343
- result = 1 * MutableListSlot([1, 2])
344
- self.assertEqual(list(result), [1, 2])
345
-
346
- def test_rmul_by_zero(self: Self, /) -> None:
347
- result = 0 * MutableListSlot([1, 2])
348
- self.assertEqual(list(result), [])
349
-
350
- def test_rmul_by_negative_integer(self: Self, /) -> None:
351
- result = -3 * MutableListSlot([1, 2])
352
- self.assertEqual(list(result), [])
353
-
354
-
355
464
  class TestOperatorIMul(unittest.TestCase):
356
465
  def test_imul_by_positive_integer(self: Self, /) -> None:
357
466
  value = MutableListSlot([1, 2])
@@ -374,18 +483,63 @@ class TestOperatorIMul(unittest.TestCase):
374
483
  self.assertEqual(list(value), [])
375
484
 
376
485
 
377
- class TestOperatorEqual(unittest.TestCase):
378
- def test_equal_same_contents(self: Self, /) -> None:
379
- self.assertTrue(MutableListSlot([1, 2]) == MutableListSlot([1, 2]))
486
+ class TestOperatorIterSequence(unittest.TestCase):
487
+ def test_shrinking_makes_next_index_out_of_range(self: Self, /) -> None:
488
+ values = MutableListSlot([0, 1, 2, 3, 4])
489
+ iterator = iter(values)
380
490
 
381
- def test_equal_empty_lists(self: Self, /) -> None:
382
- self.assertTrue(MutableListSlot([]) == MutableListSlot([]))
491
+ self.assertEqual(next(iterator), 0)
492
+ del values[1:]
383
493
 
384
- def test_not_equal_different_values(self: Self, /) -> None:
385
- self.assertFalse(MutableListSlot([1, 2]) == MutableListSlot([1, 3]))
494
+ with self.assertRaises(StopIteration):
495
+ next(iterator)
386
496
 
387
- def test_not_equal_different_lengths(self: Self, /) -> None:
388
- self.assertFalse(MutableListSlot([1, 2]) == MutableListSlot([1, 2, 3]))
497
+ def test_exhaustion_remains_after_regrowth(self: Self, /) -> None:
498
+ values = MutableListSlot([0, 1, 2, 3, 4])
499
+ iterator = iter(values)
500
+
501
+ self.assertEqual(next(iterator), 0)
502
+ del values[1:]
503
+
504
+ with self.assertRaises(StopIteration):
505
+ next(iterator)
506
+
507
+ values.extend([10, 11, 12, 13])
508
+
509
+ with self.assertRaises(StopIteration):
510
+ next(iterator)
511
+
512
+ def test_regrowth_before_next_restores_valid_index(self: Self, /) -> None:
513
+ values = MutableListSlot([0, 1, 2, 3, 4])
514
+ iterator = iter(values)
515
+
516
+ self.assertEqual(next(iterator), 0)
517
+ del values[1:]
518
+ values.extend([10, 11, 12])
519
+
520
+ self.assertEqual(next(iterator), 10)
521
+
522
+ def test_deletion_before_cursor_does_not_repair_index(
523
+ self: Self, /
524
+ ) -> None:
525
+ values = MutableListSlot([0, 1, 2, 3, 4])
526
+ iterator = iter(values)
527
+
528
+ self.assertEqual(next(iterator), 0)
529
+ del values[0]
530
+
531
+ self.assertEqual(next(iterator), 2)
532
+
533
+ def test_growth_before_exhaustion_is_seen(self: Self, /) -> None:
534
+ values = MutableListSlot([0, 1])
535
+ iterator = iter(values)
536
+
537
+ self.assertEqual(next(iterator), 0)
538
+ self.assertEqual(next(iterator), 1)
539
+
540
+ values.append(2)
541
+
542
+ self.assertEqual(next(iterator), 2)
389
543
 
390
544
 
391
545
  class TestOperatorNotEqual(unittest.TestCase):
@@ -402,93 +556,80 @@ class TestOperatorNotEqual(unittest.TestCase):
402
556
  self.assertFalse(MutableListSlot([]) != MutableListSlot([]))
403
557
 
404
558
 
405
- class TestOperatorLessThan(unittest.TestCase):
406
- def test_less_than_by_first_element(self: Self, /) -> None:
407
- self.assertTrue(MutableListSlot([1, 9]) < MutableListSlot([2, 0]))
408
-
409
- def test_less_than_by_later_element(self: Self, /) -> None:
410
- self.assertTrue(MutableListSlot([1, 2]) < MutableListSlot([1, 3]))
411
-
412
- def test_prefix_is_less_than_longer_list(self: Self, /) -> None:
413
- self.assertTrue(MutableListSlot([1, 2]) < MutableListSlot([1, 2, 3]))
414
-
415
- def test_equal_list_is_not_less_than(self: Self, /) -> None:
416
- self.assertFalse(MutableListSlot([1, 2]) < MutableListSlot([1, 2]))
417
-
418
-
419
- class TestOperatorLessThanOrEqual(unittest.TestCase):
420
- def test_less_value_is_less_or_equal(self: Self, /) -> None:
421
- self.assertTrue(MutableListSlot([1]) <= MutableListSlot([2]))
422
-
423
- def test_equal_value_is_less_or_equal(self: Self, /) -> None:
424
- self.assertTrue(MutableListSlot([1, 2]) <= MutableListSlot([1, 2]))
425
-
426
- def test_prefix_is_less_or_equal(self: Self, /) -> None:
427
- self.assertTrue(MutableListSlot([1]) <= MutableListSlot([1, 2]))
559
+ class TestOperatorRMul(unittest.TestCase):
560
+ def test_rmul_by_positive_integer(self: Self, /) -> None:
561
+ result = 3 * MutableListSlot([1, 2])
562
+ self.assertEqual(list(result), [1, 2, 1, 2, 1, 2])
428
563
 
429
- def test_greater_value_is_not_less_or_equal(self: Self, /) -> None:
430
- self.assertFalse(MutableListSlot([2]) <= MutableListSlot([1]))
564
+ def test_rmul_by_one(self: Self, /) -> None:
565
+ result = 1 * MutableListSlot([1, 2])
566
+ self.assertEqual(list(result), [1, 2])
431
567
 
568
+ def test_rmul_by_zero(self: Self, /) -> None:
569
+ result = 0 * MutableListSlot([1, 2])
570
+ self.assertEqual(list(result), [])
432
571
 
433
- class TestOperatorGreaterThan(unittest.TestCase):
434
- def test_greater_than_by_first_element(self: Self, /) -> None:
435
- self.assertTrue(MutableListSlot([2, 0]) > MutableListSlot([1, 9]))
572
+ def test_rmul_by_negative_integer(self: Self, /) -> None:
573
+ result = -3 * MutableListSlot([1, 2])
574
+ self.assertEqual(list(result), [])
436
575
 
437
- def test_greater_than_by_later_element(self: Self, /) -> None:
438
- self.assertTrue(MutableListSlot([1, 3]) > MutableListSlot([1, 2]))
439
576
 
440
- def test_longer_list_is_greater_than_prefix(self: Self, /) -> None:
441
- self.assertTrue(MutableListSlot([1, 2, 3]) > MutableListSlot([1, 2]))
577
+ class TestOperatorReversedSequence(unittest.TestCase):
578
+ def test_shrinking_makes_next_index_out_of_range(self: Self, /) -> None:
579
+ values = MutableListSlot([0, 1, 2, 3, 4])
580
+ iterator = reversed(values)
442
581
 
443
- def test_equal_list_is_not_greater_than(self: Self, /) -> None:
444
- self.assertFalse(MutableListSlot([1, 2]) > MutableListSlot([1, 2]))
582
+ self.assertEqual(next(iterator), 4)
583
+ del values[1:]
445
584
 
585
+ with self.assertRaises(StopIteration):
586
+ next(iterator)
446
587
 
447
- class TestOperatorGreaterThanOrEqual(unittest.TestCase):
448
- def test_greater_value_is_greater_or_equal(self: Self, /) -> None:
449
- self.assertTrue(MutableListSlot([2]) >= MutableListSlot([1]))
588
+ def test_exhaustion_remains_after_regrowth(self: Self, /) -> None:
589
+ values = MutableListSlot([0, 1, 2, 3, 4])
590
+ iterator = reversed(values)
450
591
 
451
- def test_equal_value_is_greater_or_equal(self: Self, /) -> None:
452
- self.assertTrue(MutableListSlot([1, 2]) >= MutableListSlot([1, 2]))
592
+ self.assertEqual(next(iterator), 4)
593
+ del values[1:]
453
594
 
454
- def test_longer_list_is_greater_or_equal_to_prefix(self: Self, /) -> None:
455
- self.assertTrue(MutableListSlot([1, 2]) >= MutableListSlot([1]))
595
+ with self.assertRaises(StopIteration):
596
+ next(iterator)
456
597
 
457
- def test_smaller_value_is_not_greater_or_equal(self: Self, /) -> None:
458
- self.assertFalse(MutableListSlot([1]) >= MutableListSlot([2]))
598
+ values.extend([10, 11, 12, 13])
459
599
 
600
+ with self.assertRaises(StopIteration):
601
+ next(iterator)
460
602
 
461
- class TestOperatorContains(unittest.TestCase):
462
- def test_contains_first_element(self: Self, /) -> None:
463
- self.assertTrue(1 in MutableListSlot([1, 2, 3]))
603
+ def test_regrowth_before_next_restores_valid_index(self: Self, /) -> None:
604
+ values = MutableListSlot([0, 1, 2, 3, 4])
605
+ iterator = reversed(values)
464
606
 
465
- def test_contains_last_element(self: Self, /) -> None:
466
- self.assertTrue(3 in MutableListSlot([1, 2, 3]))
607
+ self.assertEqual(next(iterator), 4)
608
+ del values[1:]
609
+ values.extend([10, 11, 12, 13])
467
610
 
468
- def test_does_not_contain_missing_element(self: Self, /) -> None:
469
- self.assertFalse(4 in MutableListSlot([1, 2, 3]))
611
+ self.assertEqual(next(iterator), 12)
470
612
 
471
- def test_empty_slot_contains_nothing(self: Self, /) -> None:
472
- self.assertFalse(1 in MutableListSlot([]))
613
+ def test_deletion_before_cursor_does_not_repair_index(
614
+ self: Self, /
615
+ ) -> None:
616
+ values = MutableListSlot([0, 1, 2, 3, 4])
617
+ iterator = reversed(values)
473
618
 
619
+ self.assertEqual(next(iterator), 4)
620
+ del values[0]
474
621
 
475
- class TestOperatorGetItem(unittest.TestCase):
476
- def test_get_first_item(self: Self, /) -> None:
477
- value = MutableListSlot([10, 20, 30])
478
- self.assertEqual(value[0], 10)
622
+ self.assertEqual(next(iterator), 4)
479
623
 
480
- def test_get_last_item_with_negative_index(self: Self, /) -> None:
481
- value = MutableListSlot([10, 20, 30])
482
- self.assertEqual(value[-1], 30)
624
+ def test_growth_beyond_initial_reverse_range_is_not_seen(
625
+ self: Self, /
626
+ ) -> None:
627
+ values = MutableListSlot([0, 1, 2])
628
+ iterator = reversed(values)
483
629
 
484
- def test_get_slice(self: Self, /) -> None:
485
- value = MutableListSlot([1, 2, 3, 4])
486
- self.assertEqual(value[1:3], MutableListSlot([2, 3]))
630
+ values.append(3)
487
631
 
488
- def test_out_of_range_index_raises(self: Self, /) -> None:
489
- value = MutableListSlot([1, 2])
490
- with self.assertRaises(IndexError):
491
- value[5]
632
+ self.assertEqual(list(iterator), [2, 1, 0])
492
633
 
493
634
 
494
635
  class TestOperatorSetItem(unittest.TestCase):
@@ -513,27 +654,5 @@ class TestOperatorSetItem(unittest.TestCase):
513
654
  self.assertEqual(list(value), [1, 10, 20, 30, 3])
514
655
 
515
656
 
516
- class TestOperatorDelItem(unittest.TestCase):
517
- def test_delete_first_item(self: Self, /) -> None:
518
- value = MutableListSlot([1, 2, 3])
519
- del value[0]
520
- self.assertEqual(list(value), [2, 3])
521
-
522
- def test_delete_last_item(self: Self, /) -> None:
523
- value = MutableListSlot([1, 2, 3])
524
- del value[-1]
525
- self.assertEqual(list(value), [1, 2])
526
-
527
- def test_delete_slice(self: Self, /) -> None:
528
- value = MutableListSlot([1, 2, 3, 4])
529
- del value[1:3]
530
- self.assertEqual(list(value), [1, 4])
531
-
532
- def test_delete_out_of_range_raises(self: Self, /) -> None:
533
- value = MutableListSlot([1, 2])
534
- with self.assertRaises(IndexError):
535
- del value[5]
536
-
537
-
538
657
  if __name__ == "__main__":
539
658
  unittest.main()
File without changes