datahold 4.0.0.dev27__tar.gz → 4.0.0.dev28__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 (40) hide show
  1. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/PKG-INFO +1 -1
  2. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/pyproject.toml +1 -1
  3. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/src/datahold/__init__.py +140 -112
  4. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/src/datahold.egg-info/PKG-INFO +1 -1
  5. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/src/datahold.egg-info/SOURCES.txt +2 -1
  6. datahold-4.0.0.dev28/tests/test_FrozenSetSlot.py +233 -0
  7. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/tests/test_abstractmethods.py +3 -1
  8. datahold-4.0.0.dev28/tests/test_metaclass.py +25 -0
  9. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/tests/test_name.py +6 -5
  10. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/tests/testdata.toml +35 -11
  11. datahold-4.0.0.dev27/tests/test_internal_comparison.py +0 -50
  12. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/LICENSE.txt +0 -0
  13. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/MANIFEST.in +0 -0
  14. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/README.rst +0 -0
  15. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/docs/v1.1.rst +0 -0
  16. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/docs/v1.2.rst +0 -0
  17. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/docs/v2.0.rst +0 -0
  18. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/docs/v2.1.rst +0 -0
  19. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/docs/v2.2.rst +0 -0
  20. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/docs/v2.3.rst +0 -0
  21. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/docs/v3.0.rst +0 -0
  22. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/docs/v4.0.rst +0 -0
  23. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/run_tests.py +0 -0
  24. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/setup.cfg +0 -0
  25. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/src/datahold/py.typed +0 -0
  26. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/src/datahold.egg-info/dependency_links.txt +0 -0
  27. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/src/datahold.egg-info/requires.txt +0 -0
  28. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/src/datahold.egg-info/top_level.txt +0 -0
  29. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/tests/test_FrozenListSlot.py +0 -0
  30. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/tests/test_MutableDictSlot.py +0 -0
  31. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/tests/test_MutableListSlot.py +0 -0
  32. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/tests/test_MutableSetSlot.py +0 -0
  33. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/tests/test_all.py +0 -0
  34. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/tests/test_attributes.py +0 -0
  35. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/tests/test_docs.py +0 -0
  36. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/tests/test_generic.py +0 -0
  37. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/tests/test_issubclass.py +0 -0
  38. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/tests/test_nested.py +0 -0
  39. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/tests/test_sorted.py +0 -0
  40. {datahold-4.0.0.dev27 → datahold-4.0.0.dev28}/tests/test_variance.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datahold
3
- Version: 4.0.0.dev27
3
+ Version: 4.0.0.dev28
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
@@ -31,7 +31,7 @@ license-files = [
31
31
  name = "datahold"
32
32
  readme = "README.rst"
33
33
  requires-python = ">=3.11"
34
- version = "4.0.0.dev27"
34
+ version = "4.0.0.dev28"
35
35
 
36
36
  [project.urls]
37
37
  Download = "https://pypi.org/project/datahold/#files"
@@ -9,6 +9,7 @@ __all__: list[str] = [
9
9
  "FrozenDictSlot",
10
10
  "FrozenListLike",
11
11
  "FrozenListSlot",
12
+ "FrozenObjectSlot",
12
13
  "FrozenSetLike",
13
14
  "FrozenSetSlot",
14
15
  "ListLike",
@@ -18,16 +19,20 @@ __all__: list[str] = [
18
19
  "MutableListLike",
19
20
  "MutableListSlot",
20
21
  "MutableMapping",
22
+ "MutableObject",
23
+ "MutableObjectLike",
21
24
  "MutableSequence",
22
25
  "MutableSet",
23
26
  "MutableSetLike",
24
27
  "MutableSetSlot",
28
+ "Object",
29
+ "ObjectSlot",
25
30
  "Sequence",
26
31
  "Set",
27
32
  "SetLike",
28
33
  ]
29
34
 
30
- from abc import abstractmethod
35
+ from abc import ABCMeta, abstractmethod
31
36
  from collections import abc
32
37
  from contextlib import contextmanager
33
38
  from types import NotImplementedType, TracebackType
@@ -164,15 +169,82 @@ class MutableSequence_Mutable[Item](Protocol):
164
169
 
165
170
  ### TYPE ALIASES ###
166
171
 
172
+ type Dict[Key, Value] = dict[Key | str, Optional[Value]]
167
173
 
168
174
  type DictInit[Key, Value] = (
169
175
  SupportsKeysAndGetitem[Key | str, Optional[Value]]
170
176
  | abc.Iterable[tuple[Key | str, Optional[Value]]]
171
177
  )
172
178
 
179
+ type FrozenDict[Key, Value] = frozendict[Key | str, Optional[Value]]
180
+
173
181
  type Slice[Index] = slice[Optional[Index], Optional[Index], Optional[Index]]
174
182
 
175
183
 
184
+ ### OBJECT ###
185
+ class Object[Frozen](metaclass=ABCMeta):
186
+ """Provide abc for custom object."""
187
+
188
+ __slots__ = ()
189
+
190
+ @abstractmethod
191
+ @setdoc.basic
192
+ def __frozen__(self: Self, /) -> Frozen: ...
193
+
194
+
195
+ class MutableObject[Frozen, Mutable](Object[Frozen]):
196
+ """Provide abc for custom mutable object."""
197
+
198
+ __slots__ = ()
199
+
200
+ @abstractmethod
201
+ @setdoc.basic
202
+ def __mutate__(self: Self, /) -> ContextManager[Mutable]: ...
203
+
204
+
205
+ ### OBJECT-LIKE ###
206
+
207
+
208
+ class MutableObjectLike[Frozen, Mutable](
209
+ MutableObject[Frozen, Mutable],
210
+ ):
211
+ """Provide abc for custom mutable object-like."""
212
+
213
+ __slots__ = ()
214
+
215
+ @abstractmethod
216
+ @setdoc.basic
217
+ def __init__(self: Self, other: Self, /) -> None: ...
218
+ @setdoc.basic
219
+ def copy(self: Self, /) -> Self:
220
+ return type(self)(self)
221
+
222
+
223
+ ### OBJECT-HOLD ###
224
+
225
+
226
+ class ObjectSlot[Frozen](
227
+ Object[Frozen],
228
+ ):
229
+ """Provide slotted abc for custom object-like."""
230
+
231
+ __slots__ = ("_slot",)
232
+ _slot: Frozen
233
+
234
+
235
+ class FrozenObjectSlot[Frozen](
236
+ ObjectSlot[Frozen],
237
+ ):
238
+ """Provide slotted abc for custom frozen object-like."""
239
+
240
+ __slots__ = ()
241
+ _slot: Frozen
242
+
243
+ @setdoc.basic
244
+ def __frozen__(self: Self, /) -> Frozen:
245
+ return self._slot
246
+
247
+
176
248
  ### COLLECTION ###
177
249
 
178
250
 
@@ -180,11 +252,10 @@ class Collection[Item](
180
252
  abc.Sized,
181
253
  abc.Iterable[Item],
182
254
  abc.Container[object],
255
+ Object[Collection_Frozen[Item]],
183
256
  ):
184
257
  """Provide abc for custom collection."""
185
258
 
186
- type __Frozen__[Item_] = Collection_Frozen[Item_]
187
-
188
259
  @setdoc.basic
189
260
  def __contains__(self: Self, other: object, /) -> bool:
190
261
  try:
@@ -192,10 +263,6 @@ class Collection[Item](
192
263
  except TypeError:
193
264
  return other in (x for x in self) # type: ignore[operator]
194
265
 
195
- @abstractmethod
196
- @setdoc.basic
197
- def __frozen__(self: Self, /) -> Collection_Frozen[Item]: ...
198
-
199
266
  @setdoc.basic
200
267
  def __iter__(self: Self, /) -> abc.Iterator[Item]:
201
268
  return iter(self.__frozen__())
@@ -214,15 +281,15 @@ class Set[Item: abc.Hashable](Collection[Item], abc.Set[Item]):
214
281
  __slots__ = ()
215
282
 
216
283
 
217
- class MutableSet[Item: abc.Hashable](Set[Item], abc.MutableSet[Item]):
284
+ class MutableSet[Item: abc.Hashable](
285
+ Set[Item],
286
+ abc.MutableSet[Item],
287
+ MutableObject[Collection_Frozen[Item], MutableSet_Mutable[Item]],
288
+ ):
218
289
  """Provide abc for custom mutable set."""
219
290
 
220
291
  __slots__ = ()
221
- type __Mutable__[Item_] = MutableSet_Mutable[Item_]
222
292
 
223
- @abstractmethod
224
- @setdoc.basic
225
- def __mutate__(self: Self) -> ContextManager[MutableSet_Mutable[Item]]: ...
226
293
  @setdoc.basic
227
294
  def add(self: Self, item: Item, /) -> None:
228
295
  with self.__mutate__() as mutable:
@@ -241,11 +308,10 @@ class SetLike[Item: abc.Hashable](Set[Item]):
241
308
  """Provide abc for custom set-like."""
242
309
 
243
310
  __slots__ = ()
244
- type __Frozen__[Item_] = frozenset[Item_]
245
311
 
246
312
  @abstractmethod
247
313
  @setdoc.basic
248
- def __frozen__(self: Self, /) -> __Frozen__[Item]: ...
314
+ def __frozen__(self: Self, /) -> frozenset[Item]: ...
249
315
  @abstractmethod
250
316
  @setdoc.basic
251
317
  def __init__(self: Self, data: abc.Iterable[Item] = (), /) -> None: ...
@@ -286,14 +352,17 @@ class FrozenSetLike[Item: abc.Hashable](SetLike[Item], abc.Hashable):
286
352
  return hash(self.__frozen__())
287
353
 
288
354
 
289
- class MutableSetLike[Item: abc.Hashable](SetLike[Item], MutableSet[Item]):
355
+ class MutableSetLike[Item: abc.Hashable](
356
+ SetLike[Item],
357
+ MutableObjectLike[frozenset[Item], set[Item]],
358
+ MutableSet[Item],
359
+ ):
290
360
  """Provide abc for custom mutable set-like."""
291
361
 
292
362
  __slots__ = ()
293
- type __Mutable__[Item_] = set[Item_]
294
363
 
295
364
  @setdoc.basic
296
- def __frozen__(self: Self, /) -> MutableSetLike.__Frozen__[Item]:
365
+ def __frozen__(self: Self, /) -> frozenset[Item]:
297
366
  with self.__mutate__() as mutable:
298
367
  return frozenset(mutable)
299
368
 
@@ -302,14 +371,6 @@ class MutableSetLike[Item: abc.Hashable](SetLike[Item], MutableSet[Item]):
302
371
  with self.__mutate__() as mutable:
303
372
  mutable.update(data)
304
373
 
305
- @abstractmethod
306
- @setdoc.basic
307
- def __mutate__(self: Self) -> ContextManager[__Mutable__[Item]]: ...
308
-
309
- @setdoc.basic
310
- def copy(self: Self, /) -> Self:
311
- return type(self)(self)
312
-
313
374
  @setdoc.basic
314
375
  def difference_update(
315
376
  self: Self, /, *others: abc.Iterable[abc.Hashable]
@@ -340,36 +401,34 @@ class MutableSetLike[Item: abc.Hashable](SetLike[Item], MutableSet[Item]):
340
401
  ### SET-SLOT ###
341
402
 
342
403
 
343
- class FrozenSetSlot[Item](FrozenSetLike[Item]):
404
+ class FrozenSetSlot[Item](
405
+ FrozenObjectSlot[frozenset[Item]],
406
+ FrozenSetLike[Item],
407
+ ):
344
408
  """Provide slotted frozen set-like."""
345
409
 
346
- __slots__ = ("_slot",)
347
-
348
- _slot: FrozenSetSlot.__Frozen__[Item]
349
-
350
- @setdoc.basic
351
- def __frozen__(self: Self, /) -> FrozenSetSlot.__Frozen__[Item]:
352
- return self._slot
410
+ __slots__ = ()
353
411
 
354
412
  @setdoc.basic
355
413
  def __init__(self: Self, data: abc.Iterable[Item] = (), /) -> None:
356
414
  self._slot = frozenset(data)
357
415
 
358
416
 
359
- class MutableSetSlot[Item](MutableSetLike[Item]):
417
+ class MutableSetSlot[Item](
418
+ MutableSetLike[Item],
419
+ ObjectSlot[frozenset[Item]],
420
+ ):
360
421
  """Provide slotted mutable set-like."""
361
422
 
362
- __slots__ = ("_slot",)
363
-
364
- _slot: FrozenSetSlot.__Frozen__[Item]
423
+ __slots__ = ()
365
424
 
366
425
  @contextmanager
367
426
  @setdoc.basic
368
427
  def __mutate__(
369
428
  self: Self,
370
429
  /,
371
- ) -> abc.Generator[MutableSetSlot.__Mutable__[Item], None, None]:
372
- slot: MutableSetSlot.__Mutable__[Item]
430
+ ) -> abc.Generator[set[Item], None, None]:
431
+ slot: set[Item]
373
432
  slot = set(getattr(self, "_slot", ()))
374
433
  yield slot
375
434
  self._slot = frozenset(slot)
@@ -386,11 +445,9 @@ class Mapping[Key: abc.Hashable, Value](
386
445
 
387
446
  __slots__ = ()
388
447
 
389
- type __Frozen__[Key_, Value_] = Mapping_Frozen[Key_, Value_]
390
-
391
448
  @abstractmethod
392
449
  @setdoc.basic
393
- def __frozen__(self: Self, /) -> __Frozen__[Key, Value]: ...
450
+ def __frozen__(self: Self, /) -> Mapping_Frozen[Key, Value]: ...
394
451
  @setdoc.basic
395
452
  def __getitem__(self: Self, key: abc.Hashable, /) -> Value:
396
453
  return self.__frozen__()[key]
@@ -399,21 +456,17 @@ class Mapping[Key: abc.Hashable, Value](
399
456
  class MutableMapping[Key: abc.Hashable, Value](
400
457
  Mapping[Key, Value],
401
458
  abc.MutableMapping[Key | str, Optional[Value]],
459
+ MutableObject[FrozenDict[Key, Value], Dict[Key, Value]],
402
460
  ):
403
461
  """Provide abc for custom mutable mapping."""
404
462
 
405
463
  __slots__ = ()
406
464
 
407
- type __Mutable__[Key_, Value_] = MutableMapping_Mutable[Key_, Value_]
408
-
409
465
  @setdoc.basic
410
466
  def __delitem__(self: Self, key: Key | str, /) -> None:
411
467
  with self.__mutate__() as mutable:
412
468
  del mutable[key]
413
469
 
414
- @abstractmethod
415
- @setdoc.basic
416
- def __mutate__(self: Self) -> ContextManager[__Mutable__[Key, Value]]: ...
417
470
  @setdoc.basic
418
471
  def __setitem__(
419
472
  self: Self, key: Key | str, value: Optional[Value], /
@@ -431,11 +484,12 @@ class DictLike[Key: abc.Hashable, Value](
431
484
  """Provide abc for custom dict-like."""
432
485
 
433
486
  __slots__ = ()
434
- type __Frozen__[Key_, Value_] = frozendict[Key_ | str, Optional[Value_]]
435
487
 
436
488
  @abstractmethod
437
489
  @setdoc.basic
438
- def __frozen__(self: Self, /) -> __Frozen__[Key, Value]: ... # type: ignore[override]
490
+ def __frozen__(self: Self, /) -> FrozenDict[Key, Value]: # type: ignore[override]
491
+ ...
492
+
439
493
  @abstractmethod
440
494
  @setdoc.basic
441
495
  def __init__(
@@ -450,13 +504,13 @@ class DictLike[Key: abc.Hashable, Value](
450
504
  other: DictInit[Key_, Value_],
451
505
  /,
452
506
  ) -> DictLike[Key | Key_, Value | Value_]:
453
- data: DictLike.__Frozen__[Key_, Value_]
507
+ data: FrozenDict[Key, Value]
454
508
  try:
455
509
  data = frozendict(other) # type: ignore[arg-type]
456
510
  except TypeError:
457
511
  return NotImplemented
458
512
  return type(self)( # type: ignore[return-value]
459
- self.__frozen__() | data # type: ignore[operator]
513
+ self.__frozen__() | data
460
514
  )
461
515
 
462
516
  @classmethod
@@ -485,20 +539,18 @@ class FrozenDictLike[Key: abc.Hashable, Value](
485
539
 
486
540
  class MutableDictLike[Key: abc.Hashable, Value](
487
541
  DictLike[Key, Value],
542
+ MutableObjectLike[FrozenDict[Key, Value], Dict[Key, Value]],
488
543
  MutableMapping[Key, Value],
489
544
  ):
490
545
  """Provide abc for custom mutable dict-like."""
491
546
 
492
547
  __slots__ = ()
493
- type __Mutable__[Key_: abc.Hashable, Value_] = dict[
494
- Key_ | str, Optional[Value_]
495
- ]
496
548
 
497
549
  @setdoc.basic
498
550
  def __frozen__( # type: ignore[override]
499
551
  self: Self,
500
552
  /,
501
- ) -> MutableDictLike.__Frozen__[Key, Value]:
553
+ ) -> FrozenDict[Key, Value]:
502
554
  with self.__mutate__() as mutable:
503
555
  return frozendict(mutable)
504
556
 
@@ -521,15 +573,6 @@ class MutableDictLike[Key: abc.Hashable, Value](
521
573
  mutable |= other
522
574
  return self
523
575
 
524
- @abstractmethod
525
- @setdoc.basic
526
- def __mutate__(
527
- self: Self, /
528
- ) -> ContextManager[__Mutable__[Key, Value]]: ...
529
- @setdoc.basic
530
- def copy(self: Self, /) -> Self:
531
- return type(self)(self)
532
-
533
576
  @setdoc.basic
534
577
  def popitem(self: Self, /) -> tuple[Key | str, Optional[Value]]:
535
578
  # for most dict d
@@ -542,19 +585,13 @@ class MutableDictLike[Key: abc.Hashable, Value](
542
585
  ### DICT-SLOT ###
543
586
 
544
587
 
545
- class FrozenDictSlot[Key: abc.Hashable, Value](
588
+ class FrozenDictSlot[Key: abc.Hashable, Value]( # type: ignore[misc]
589
+ FrozenObjectSlot[FrozenDict[Key, Value]],
546
590
  FrozenDictLike[Key, Value],
547
591
  ):
548
592
  """Provide slotted frozen dict-like."""
549
593
 
550
- __slots__ = ("_slot",)
551
- _slot: FrozenDictSlot.__Frozen__[Key, Value]
552
-
553
- @setdoc.basic
554
- def __frozen__( # type: ignore[override]
555
- self: Self,
556
- ) -> FrozenDictSlot.__Frozen__[Key, Value]:
557
- return self._slot
594
+ __slots__ = ()
558
595
 
559
596
  @setdoc.basic
560
597
  def __init__(
@@ -568,19 +605,19 @@ class FrozenDictSlot[Key: abc.Hashable, Value](
568
605
 
569
606
  class MutableDictSlot[Key: abc.Hashable, Value](
570
607
  MutableDictLike[Key, Value],
608
+ ObjectSlot[FrozenDict[Key, Value]],
571
609
  ):
572
610
  """Provide slotted mutable dict-like."""
573
611
 
574
- __slots__ = ("_slot",)
575
- _slot: FrozenDictSlot.__Frozen__[Key, Value]
612
+ __slots__ = ()
576
613
 
577
614
  @contextmanager
578
615
  @setdoc.basic
579
616
  def __mutate__(
580
617
  self: Self,
581
618
  /,
582
- ) -> abc.Generator[MutableDictSlot.__Mutable__[Key, Value], None, None]:
583
- slot: MutableDictSlot.__Mutable__[Key, Value]
619
+ ) -> abc.Generator[Dict[Key, Value], None, None]:
620
+ slot: Dict[Key, Value]
584
621
  slot = dict(getattr(self, "_slot", ()))
585
622
  yield slot
586
623
  self._slot = frozendict(slot)
@@ -593,11 +630,10 @@ class Sequence[Item](Collection[Item], abc.Sequence[Item]):
593
630
  """Provide abc for customized sequence."""
594
631
 
595
632
  __slots__ = ()
596
- type __Frozen__[Item_] = Sequence_Frozen[Item_]
597
633
 
598
634
  @abstractmethod
599
635
  @setdoc.basic
600
- def __frozen__(self: Self, /) -> __Frozen__[Item]: ...
636
+ def __frozen__(self: Self, /) -> Sequence_Frozen[Item]: ...
601
637
  @overload
602
638
  @setdoc.basic
603
639
  def __getitem__(self: Self, key: int, /) -> Item: ...
@@ -611,11 +647,14 @@ class Sequence[Item](Collection[Item], abc.Sequence[Item]):
611
647
  return self.__frozen__()[key]
612
648
 
613
649
 
614
- class MutableSequence[Item](Sequence[Item], abc.MutableSequence[Item]):
650
+ class MutableSequence[Item](
651
+ Sequence[Item],
652
+ abc.MutableSequence[Item],
653
+ MutableObject[Sequence_Frozen[Item], MutableSequence_Mutable[Item]],
654
+ ):
615
655
  """Provide abc for custom mutable sequence."""
616
656
 
617
657
  __slots__ = ()
618
- type __Mutable__[Item_] = MutableSequence_Mutable[Item_]
619
658
 
620
659
  @overload
621
660
  @setdoc.basic
@@ -643,10 +682,6 @@ class MutableSequence[Item](Sequence[Item], abc.MutableSequence[Item]):
643
682
  with self.__mutate__() as mutable:
644
683
  return mutable[key]
645
684
 
646
- @abstractmethod
647
- @setdoc.basic
648
- def __mutate__(self: Self, /) -> ContextManager[__Mutable__[Item]]: ...
649
-
650
685
  @overload
651
686
  @setdoc.basic
652
687
  def __setitem__(self: Self, key: int, value: Item, /) -> None: ...
@@ -677,9 +712,6 @@ class ListLike[Item](Sequence[Item]):
677
712
 
678
713
  __slots__ = ()
679
714
 
680
- type __Frozen__[Item_] = tuple[Item_, ...]
681
- # Frozen has to be tuple to allow covariance
682
-
683
715
  @setdoc.basic
684
716
  def __add__[Item_](
685
717
  self: Self, other: ListLike[Item_], /
@@ -698,7 +730,9 @@ class ListLike[Item](Sequence[Item]):
698
730
 
699
731
  @abstractmethod
700
732
  @setdoc.basic
701
- def __frozen__(self: Self, /) -> __Frozen__[Item]: ...
733
+ def __frozen__(self: Self, /) -> tuple[Item, ...]:
734
+ # __frozen__ has to be tuple to allow covariance
735
+ ...
702
736
 
703
737
  @setdoc.basic
704
738
  def __ge__(self: Self, other: ListLike[Any], /) -> bool:
@@ -771,17 +805,19 @@ class FrozenListLike[Item](ListLike[Item], abc.Hashable):
771
805
  __slots__ = ()
772
806
 
773
807
  @setdoc.basic
774
- def __hash__(self: Self) -> int:
808
+ def __hash__(self: Self, /) -> int:
775
809
  return hash(self.__frozen__())
776
810
 
777
811
 
778
- class MutableListLike[Item](ListLike[Item], MutableSequence[Item]):
812
+ class MutableListLike[Item](
813
+ ListLike[Item],
814
+ MutableObjectLike[tuple[Item, ...], list[Item]],
815
+ MutableSequence[Item],
816
+ ):
779
817
  """Provide abc for custom mutable list-like."""
780
818
 
781
819
  __slots__ = ()
782
820
 
783
- type __Mutable__[Item_] = list[Item_]
784
-
785
821
  @overload
786
822
  @setdoc.basic
787
823
  def __delitem__(self: Self, key: SupportsIndex, /) -> None: ...
@@ -796,7 +832,7 @@ class MutableListLike[Item](ListLike[Item], MutableSequence[Item]):
796
832
  del mutable[key]
797
833
 
798
834
  @setdoc.basic
799
- def __frozen__(self: Self) -> MutableListLike.__Frozen__[Item]:
835
+ def __frozen__(self: Self) -> tuple[Item, ...]:
800
836
  with self.__mutate__() as mutable:
801
837
  return tuple(mutable)
802
838
 
@@ -811,10 +847,6 @@ class MutableListLike[Item](ListLike[Item], MutableSequence[Item]):
811
847
  with self.__mutate__() as mutable:
812
848
  mutable.extend(data)
813
849
 
814
- @abstractmethod
815
- @setdoc.basic
816
- def __mutate__(self: Self, /) -> ContextManager[__Mutable__[Item]]: ...
817
-
818
850
  @overload
819
851
  @setdoc.basic
820
852
  def __setitem__(
@@ -835,10 +867,6 @@ class MutableListLike[Item](ListLike[Item], MutableSequence[Item]):
835
867
  with self.__mutate__() as mutable:
836
868
  mutable[key] = value # type: ignore
837
869
 
838
- @setdoc.basic
839
- def copy(self: Self) -> Self:
840
- return type(self)(self)
841
-
842
870
  @setdoc.basic
843
871
  def insert(self: Self, index: SupportsIndex, item: Item, /) -> None:
844
872
  with self.__mutate__() as mutable:
@@ -857,26 +885,26 @@ class MutableListLike[Item](ListLike[Item], MutableSequence[Item]):
857
885
  ### LIST-SLOT ###
858
886
 
859
887
 
860
- class FrozenListSlot[Item](FrozenListLike[Item]):
888
+ class FrozenListSlot[Item](
889
+ FrozenObjectSlot[tuple[Item, ...]],
890
+ FrozenListLike[Item],
891
+ ):
861
892
  """Provide slotted frozen list-like."""
862
893
 
863
- __slots__ = ("_slot",)
864
- _slot: FrozenListSlot.__Frozen__[Item]
865
-
866
- @setdoc.basic
867
- def __frozen__(self: Self) -> FrozenListSlot.__Frozen__[Item]:
868
- return self._slot
894
+ __slots__ = ()
869
895
 
870
896
  @setdoc.basic
871
897
  def __init__(self: Self, data: abc.Iterable[Item] = (), /) -> None:
872
898
  self._slot = tuple(data)
873
899
 
874
900
 
875
- class MutableListSlot[Item](MutableListLike[Item]):
901
+ class MutableListSlot[Item](
902
+ MutableListLike[Item],
903
+ ObjectSlot[tuple[Item, ...]],
904
+ ):
876
905
  """Provide slotted mutable list-like."""
877
906
 
878
- __slots__ = ("_slot",)
879
- _slot: MutableListSlot.__Frozen__[Item]
907
+ __slots__ = ()
880
908
 
881
909
  @contextmanager
882
910
  @setdoc.basic
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datahold
3
- Version: 4.0.0.dev27
3
+ Version: 4.0.0.dev28
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
@@ -20,6 +20,7 @@ src/datahold.egg-info/dependency_links.txt
20
20
  src/datahold.egg-info/requires.txt
21
21
  src/datahold.egg-info/top_level.txt
22
22
  tests/test_FrozenListSlot.py
23
+ tests/test_FrozenSetSlot.py
23
24
  tests/test_MutableDictSlot.py
24
25
  tests/test_MutableListSlot.py
25
26
  tests/test_MutableSetSlot.py
@@ -28,8 +29,8 @@ tests/test_all.py
28
29
  tests/test_attributes.py
29
30
  tests/test_docs.py
30
31
  tests/test_generic.py
31
- tests/test_internal_comparison.py
32
32
  tests/test_issubclass.py
33
+ tests/test_metaclass.py
33
34
  tests/test_name.py
34
35
  tests/test_nested.py
35
36
  tests/test_sorted.py
@@ -0,0 +1,233 @@
1
+ import unittest
2
+ from typing import Self
3
+
4
+ from datahold import FrozenSetSlot
5
+
6
+
7
+ class TestUnionOperator(unittest.TestCase):
8
+ def test_union_with_overlap(self: Self) -> None:
9
+ self.assertEqual(
10
+ FrozenSetSlot({1, 2, 3}) | FrozenSetSlot({3, 4}),
11
+ frozenset({1, 2, 3, 4}),
12
+ )
13
+
14
+ def test_union_with_disjoint_sets(self: Self) -> None:
15
+ self.assertEqual(
16
+ FrozenSetSlot({1, 2}) | FrozenSetSlot({3, 4}),
17
+ frozenset({1, 2, 3, 4}),
18
+ )
19
+
20
+ def test_union_with_empty_set(self: Self) -> None:
21
+ self.assertEqual(
22
+ FrozenSetSlot({1, 2}) | FrozenSetSlot(),
23
+ frozenset({1, 2}),
24
+ )
25
+
26
+ def test_union_with_builtin_frozenset(self: Self) -> None:
27
+ self.assertEqual(
28
+ FrozenSetSlot({1, 2}) | frozenset({2, 3}),
29
+ frozenset({1, 2, 3}),
30
+ )
31
+
32
+
33
+ class TestIntersectionOperator(unittest.TestCase):
34
+ def test_intersection_with_overlap(self: Self) -> None:
35
+ self.assertEqual(
36
+ FrozenSetSlot({1, 2, 3}) & FrozenSetSlot({2, 3, 4}),
37
+ frozenset({2, 3}),
38
+ )
39
+
40
+ def test_intersection_with_disjoint_sets(self: Self) -> None:
41
+ self.assertEqual(
42
+ FrozenSetSlot({1, 2}) & FrozenSetSlot({3, 4}),
43
+ frozenset(),
44
+ )
45
+
46
+ def test_intersection_with_empty_set(self: Self) -> None:
47
+ self.assertEqual(
48
+ FrozenSetSlot({1, 2}) & FrozenSetSlot(),
49
+ frozenset(),
50
+ )
51
+
52
+ def test_intersection_with_builtin_set(self: Self) -> None:
53
+ self.assertEqual(
54
+ FrozenSetSlot({1, 2, 3}) & {2, 3, 4},
55
+ frozenset({2, 3}),
56
+ )
57
+
58
+
59
+ class TestDifferenceOperator(unittest.TestCase):
60
+ def test_difference_with_overlap(self: Self) -> None:
61
+ self.assertEqual(
62
+ FrozenSetSlot({1, 2, 3}) - FrozenSetSlot({2, 3, 4}),
63
+ frozenset({1}),
64
+ )
65
+
66
+ def test_difference_with_disjoint_sets(self: Self) -> None:
67
+ self.assertEqual(
68
+ FrozenSetSlot({1, 2}) - FrozenSetSlot({3, 4}),
69
+ frozenset({1, 2}),
70
+ )
71
+
72
+ def test_difference_with_identical_sets(self: Self) -> None:
73
+ self.assertEqual(
74
+ FrozenSetSlot({1, 2}) - FrozenSetSlot({1, 2}),
75
+ frozenset(),
76
+ )
77
+
78
+ def test_difference_with_empty_set(self: Self) -> None:
79
+ self.assertEqual(
80
+ FrozenSetSlot({1, 2}) - FrozenSetSlot(),
81
+ frozenset({1, 2}),
82
+ )
83
+
84
+
85
+ class TestSymmetricDifferenceOperator(unittest.TestCase):
86
+ def test_symmetric_difference_with_overlap(self: Self) -> None:
87
+ self.assertEqual(
88
+ FrozenSetSlot({1, 2, 3}) ^ FrozenSetSlot({3, 4}),
89
+ frozenset({1, 2, 4}),
90
+ )
91
+
92
+ def test_symmetric_difference_with_disjoint_sets(self: Self) -> None:
93
+ self.assertEqual(
94
+ FrozenSetSlot({1, 2}) ^ FrozenSetSlot({3, 4}),
95
+ frozenset({1, 2, 3, 4}),
96
+ )
97
+
98
+ def test_symmetric_difference_with_identical_sets(self: Self) -> None:
99
+ self.assertEqual(
100
+ FrozenSetSlot({1, 2}) ^ FrozenSetSlot({1, 2}),
101
+ frozenset(),
102
+ )
103
+
104
+ def test_symmetric_difference_with_empty_set(self: Self) -> None:
105
+ self.assertEqual(
106
+ FrozenSetSlot({1, 2}) ^ FrozenSetSlot(),
107
+ frozenset({1, 2}),
108
+ )
109
+
110
+
111
+ class TestSubsetOperator(unittest.TestCase):
112
+ def test_equal_sets_are_subsets(self: Self) -> None:
113
+ self.assertTrue(FrozenSetSlot({1, 2}) <= FrozenSetSlot({1, 2}))
114
+
115
+ def test_proper_subset_is_subset(self: Self) -> None:
116
+ self.assertTrue(FrozenSetSlot({1, 2}) <= FrozenSetSlot({1, 2, 3}))
117
+
118
+ def test_larger_set_is_not_subset(self: Self) -> None:
119
+ self.assertFalse(FrozenSetSlot({1, 2, 3}) <= FrozenSetSlot({1, 2}))
120
+
121
+ def test_empty_set_is_subset(self: Self) -> None:
122
+ self.assertTrue(FrozenSetSlot() <= FrozenSetSlot({1}))
123
+
124
+
125
+ class TestProperSubsetOperator(unittest.TestCase):
126
+ def test_proper_subset(self: Self) -> None:
127
+ self.assertTrue(FrozenSetSlot({1, 2}) < FrozenSetSlot({1, 2, 3}))
128
+
129
+ def test_equal_sets_are_not_proper_subsets(self: Self) -> None:
130
+ self.assertFalse(FrozenSetSlot({1, 2}) < FrozenSetSlot({1, 2}))
131
+
132
+ def test_larger_set_is_not_proper_subset(self: Self) -> None:
133
+ self.assertFalse(FrozenSetSlot({1, 2, 3}) < FrozenSetSlot({1, 2}))
134
+
135
+ def test_empty_set_is_proper_subset_of_nonempty_set(self: Self) -> None:
136
+ self.assertTrue(FrozenSetSlot() < FrozenSetSlot({1}))
137
+
138
+
139
+ class TestSupersetOperator(unittest.TestCase):
140
+ def test_equal_sets_are_supersets(self: Self) -> None:
141
+ self.assertTrue(FrozenSetSlot({1, 2}) >= FrozenSetSlot({1, 2}))
142
+
143
+ def test_larger_set_is_superset(self: Self) -> None:
144
+ self.assertTrue(FrozenSetSlot({1, 2, 3}) >= FrozenSetSlot({1, 2}))
145
+
146
+ def test_smaller_set_is_not_superset(self: Self) -> None:
147
+ self.assertFalse(FrozenSetSlot({1, 2}) >= FrozenSetSlot({1, 2, 3}))
148
+
149
+ def test_every_set_is_superset_of_empty_set(self: Self) -> None:
150
+ self.assertTrue(FrozenSetSlot({1}) >= FrozenSetSlot())
151
+
152
+
153
+ class TestProperSupersetOperator(unittest.TestCase):
154
+ def test_proper_superset(self: Self) -> None:
155
+ self.assertTrue(FrozenSetSlot({1, 2, 3}) > FrozenSetSlot({1, 2}))
156
+
157
+ def test_equal_sets_are_not_proper_supersets(self: Self) -> None:
158
+ self.assertFalse(FrozenSetSlot({1, 2}) > FrozenSetSlot({1, 2}))
159
+
160
+ def test_smaller_set_is_not_proper_superset(self: Self) -> None:
161
+ self.assertFalse(FrozenSetSlot({1, 2}) > FrozenSetSlot({1, 2, 3}))
162
+
163
+ def test_nonempty_set_is_proper_superset_of_empty_set(self: Self) -> None:
164
+ self.assertTrue(FrozenSetSlot({1}) > FrozenSetSlot())
165
+
166
+
167
+ class TestEqualityOperator(unittest.TestCase):
168
+ def test_equal_instances(self: Self) -> None:
169
+ self.assertTrue(FrozenSetSlot({1, 2, 3}) == FrozenSetSlot({3, 2, 1}))
170
+
171
+ def test_equal_to_builtin_frozenset(self: Self) -> None:
172
+ self.assertTrue(FrozenSetSlot({1, 2}) == frozenset({1, 2})) # type: ignore[comparison-overlap]
173
+
174
+ def test_equal_to_builtin_set(self: Self) -> None:
175
+ self.assertTrue(FrozenSetSlot({1, 2}) == {1, 2}) # type: ignore[comparison-overlap]
176
+
177
+ def test_unequal_values(self: Self) -> None:
178
+ self.assertFalse(FrozenSetSlot({1, 2}) == FrozenSetSlot({1, 3}))
179
+
180
+ def test_not_equal_to_non_set_object(self: Self) -> None:
181
+ self.assertFalse(FrozenSetSlot({1, 2}) == [1, 2]) # type: ignore[comparison-overlap]
182
+
183
+
184
+ class TestInequalityOperator(unittest.TestCase):
185
+ def test_different_instances_are_unequal(self: Self) -> None:
186
+ self.assertTrue(FrozenSetSlot({1, 2}) != FrozenSetSlot({1, 3}))
187
+
188
+ def test_equal_instances_are_not_unequal(self: Self) -> None:
189
+ self.assertFalse(FrozenSetSlot({1, 2}) != FrozenSetSlot({2, 1}))
190
+
191
+ def test_equal_builtin_frozenset_is_not_unequal(self: Self) -> None:
192
+ self.assertFalse(FrozenSetSlot({1, 2}) != frozenset({1, 2})) # type: ignore[comparison-overlap]
193
+
194
+ def test_different_builtin_set_is_unequal(self: Self) -> None:
195
+ self.assertTrue(FrozenSetSlot({1, 2}) != {1, 2, 3}) # type: ignore[comparison-overlap]
196
+
197
+ def test_non_set_object_is_unequal(self: Self) -> None:
198
+ self.assertTrue(FrozenSetSlot({1, 2}) != [1, 2]) # type: ignore[comparison-overlap]
199
+
200
+
201
+ class TestMembershipOperator(unittest.TestCase):
202
+ def test_existing_element_is_member(self: Self) -> None:
203
+ self.assertTrue(2 in FrozenSetSlot({1, 2, 3}))
204
+
205
+ def test_missing_element_is_not_member(self: Self) -> None:
206
+ self.assertFalse(4 in FrozenSetSlot({1, 2, 3}))
207
+
208
+ def test_nested_frozenset_is_member(self: Self) -> None:
209
+ nested = frozenset({1, 2})
210
+ self.assertTrue(nested in FrozenSetSlot({nested, frozenset({3})}))
211
+
212
+ def test_equivalent_set_matches_nested_frozenset(self: Self) -> None:
213
+ self.assertTrue({1, 2} in FrozenSetSlot({frozenset({1, 2})}))
214
+
215
+
216
+ class TestNonMembershipOperator(unittest.TestCase):
217
+ def test_missing_element_is_not_member(self: Self) -> None:
218
+ self.assertTrue(4 not in FrozenSetSlot({1, 2, 3}))
219
+
220
+ def test_existing_element_is_member(self: Self) -> None:
221
+ self.assertFalse(2 not in FrozenSetSlot({1, 2, 3}))
222
+
223
+ def test_missing_nested_frozenset_is_not_member(self: Self) -> None:
224
+ self.assertTrue(
225
+ frozenset({3, 4}) not in FrozenSetSlot({frozenset({1, 2})})
226
+ )
227
+
228
+ def test_equivalent_set_is_considered_a_member(self: Self) -> None:
229
+ self.assertFalse({1, 2} not in FrozenSetSlot({frozenset({1, 2})}))
230
+
231
+
232
+ if __name__ == "__main__":
233
+ unittest.main()
@@ -4,7 +4,7 @@ __all__: list[str] = ["TestAbstractmethods"]
4
4
 
5
5
  import inspect as ins
6
6
  import unittest
7
- from typing import Any, Optional, Self
7
+ from typing import Any, Self
8
8
 
9
9
  from Lazy import Lazy
10
10
 
@@ -22,6 +22,8 @@ class TestAbstractmethods(unittest.TestCase):
22
22
  def test_abstractmethods(self: Self, /) -> None:
23
23
  name: Any
24
24
  for name in Lazy.lazy.datatypes.keys():
25
+ if "Object" in name:
26
+ continue
25
27
  with self.subTest(datatype=name):
26
28
  self._test(name, Lazy.get_abstractmethods(name))
27
29
 
@@ -0,0 +1,25 @@
1
+ from __future__ import annotations
2
+
3
+ __all__: list[str] = ["TestMetaclass"]
4
+
5
+ import unittest
6
+ from abc import ABCMeta
7
+ from typing import Any, Self
8
+
9
+ from Lazy import Lazy
10
+
11
+ import datahold
12
+
13
+
14
+ class TestMetaclass(unittest.TestCase):
15
+
16
+ def test_metaclass(self: Self, /) -> None:
17
+ datatype: type[Any]
18
+ for name in Lazy.lazy.datatypes.keys():
19
+ with self.subTest(datatype=name):
20
+ datatype = getattr(datahold, name)
21
+ self.assertIs(type(datatype), ABCMeta)
22
+
23
+
24
+ if __name__ == "__main__":
25
+ unittest.main(verbosity=2)
@@ -31,28 +31,28 @@ class TestName(unittest.TestCase):
31
31
  # all
32
32
  datatype = getattr(datahold, name)
33
33
  self.assertEqual(datatype.__name__, name)
34
- self.assertTrue(hasattr(datatype, "__Frozen__"))
35
- self.assertTrue(hasattr(datatype, "__frozen__"))
34
+ self.assertTrue(issubclass(datatype, datahold.Object))
35
+ if "Object" in name:
36
+ return
36
37
  self.assertTrue(issubclass(datatype, datahold.Collection))
38
+ self.assertTrue(hasattr(datatype, "__frozen__"))
37
39
  # frozen
38
40
  if prefix == "Frozen":
39
41
  self.assertIsNot(datatype.__hash__, object.__hash__)
40
42
  self.assertTrue(issubclass(datatype, abc.Hashable))
41
- self.assertFalse(hasattr(datatype, "__Mutable__"))
42
43
  self.assertFalse(hasattr(datatype, "__mutate__"))
43
44
  ancestor = getattr(datahold, name[6:], object)
44
45
  self.assertTrue(issubclass(datatype, ancestor))
45
46
  # mutable
46
47
  if prefix == "Mutable":
47
48
  self.assertIn(datatype.__hash__, [None, object.__hash__])
48
- self.assertTrue(hasattr(datatype, "__Mutable__"))
49
49
  self.assertTrue(hasattr(datatype, "__mutate__"))
50
+ self.assertTrue(issubclass(datatype, datahold.MutableObject))
50
51
  ancestor = getattr(datahold, name[7:], object)
51
52
  self.assertTrue(issubclass(datatype, ancestor))
52
53
  # no prefix
53
54
  if prefix == "":
54
55
  self.assertIn(datatype.__hash__, [None, object.__hash__])
55
- self.assertFalse(hasattr(datatype, "__Mutable__"))
56
56
  self.assertFalse(hasattr(datatype, "__mutate__"))
57
57
  # like
58
58
  if suffix == "Like":
@@ -60,6 +60,7 @@ class TestName(unittest.TestCase):
60
60
  # slot
61
61
  if suffix == "Slot":
62
62
  self.assertTrue(hasattr(datatype, "__init__"))
63
+ self.assertTrue(issubclass(datatype, datahold.ObjectSlot))
63
64
  ancestor = getattr(datahold, name[:-4] + "Like")
64
65
  self.assertTrue(issubclass(datatype, ancestor))
65
66
  # no suffix
@@ -1,4 +1,5 @@
1
- [datatypes.Collection]
1
+ [datatypes.Collection.issubclass]
2
+ "datahold.Object" = true
2
3
 
3
4
  [datatypes.DictLike.attributes]
4
5
  __or__ = "datahold.DictLike"
@@ -27,8 +28,6 @@ __init__ = "datahold.ListLike"
27
28
  "collections.abc.Sequence" = true
28
29
 
29
30
  [datatypes.FrozenListLike.nested]
30
- __Frozen__ = "builtins.tuple"
31
- __Mutable__ = ""
32
31
 
33
32
  [datatypes.FrozenListLike.varia]
34
33
  generic = 1
@@ -138,12 +137,16 @@ args = [
138
137
  ]
139
138
 
140
139
  [datatypes.FrozenListSlot.nested]
141
- __Frozen__ = "builtins.tuple"
142
- __Mutable__ = ""
143
140
 
144
141
  [datatypes.FrozenListSlot.varia]
145
142
  generic = 1
146
143
 
144
+ [datatypes.FrozenObjectSlot.issubclass]
145
+ "datahold.ObjectSlot" = true
146
+
147
+ [datatypes.FrozenObjectSlot.varia]
148
+ generic = 1
149
+
147
150
  [datatypes.FrozenSetLike.issubclass]
148
151
  "collections.abc.Hashable" = true
149
152
  "collections.abc.Set" = true
@@ -172,8 +175,6 @@ index = "collections.abc.Sequence"
172
175
  "datahold.MutableSequence" = false
173
176
 
174
177
  [datatypes.ListLike.nested]
175
- __Frozen__ = "builtins.tuple"
176
- __Mutable__ = ""
177
178
 
178
179
  [datatypes.ListLike.varia]
179
180
  generic = 1
@@ -185,11 +186,13 @@ generic = 1
185
186
  [datatypes.MutableDictLike.attributes]
186
187
  __ior__ = "datahold.MutableDictLike"
187
188
  __or__ = "datahold.DictLike"
189
+ copy = "datahold.MutableObjectLike"
188
190
 
189
191
  [datatypes.MutableDictLike.issubclass]
190
192
  "collections.abc.Mapping" = true
191
193
  "collections.abc.MutableMapping" = true
192
194
  "datahold.MutableMapping" = true
195
+ "datahold.MutableObjectLike" = true
193
196
 
194
197
  [datatypes.MutableDictSlot.issubclass]
195
198
  "collections.abc.Mapping" = true
@@ -207,6 +210,7 @@ __mutate__ = "datahold.MutableListLike"
207
210
  __reversed__ = "collections.abc.Sequence"
208
211
  append = "collections.abc.MutableSequence"
209
212
  clear = "collections.abc.MutableSequence"
213
+ copy = "datahold.MutableObjectLike"
210
214
  count = "collections.abc.Sequence"
211
215
  extend = "collections.abc.MutableSequence"
212
216
  foo = ""
@@ -221,10 +225,10 @@ reverse = "collections.abc.MutableSequence"
221
225
  "collections.abc.Hashable" = false
222
226
  "collections.abc.MutableMapping" = false
223
227
  "collections.abc.MutableSequence" = true
228
+ "datahold.MutableObjectLike" = true
224
229
  "datahold.MutableSequence" = true
225
230
 
226
231
  [datatypes.MutableListLike.nested]
227
- __Frozen__ = "builtins.tuple"
228
232
  __hash__ = ""
229
233
 
230
234
  [datatypes.MutableListLike.varia]
@@ -237,7 +241,6 @@ generic = 1
237
241
  "datahold.MutableListSlot" = true
238
242
 
239
243
  [datatypes.MutableListSlot.nested]
240
- __Frozen__ = "builtins.tuple"
241
244
  __hash__ = ""
242
245
 
243
246
  [datatypes.MutableListSlot.varia]
@@ -247,9 +250,17 @@ generic = 1
247
250
  "collections.abc.MutableMapping" = true
248
251
  "datahold.Mapping" = true
249
252
 
253
+ [datatypes.MutableObject.issubclass]
254
+ "datahold.Object" = true
255
+
256
+ [datatypes.MutableObjectLike.attributes]
257
+ __init__ = "datahold.MutableObjectLike"
258
+ copy = "datahold.MutableObjectLike"
259
+
260
+ [datatypes.MutableObjectLike.issubclass]
261
+ "datahold.Object" = true
262
+
250
263
  [datatypes.MutableSequence.attributes]
251
- __Frozen__ = "datahold.Sequence"
252
- __Mutable__ = "datahold.MutableSequence"
253
264
  __delitem__ = "datahold.MutableSequence"
254
265
  __frozen__ = "datahold.Sequence"
255
266
  __getitem__ = "datahold.MutableSequence"
@@ -263,11 +274,15 @@ sort = ""
263
274
  "collections.abc.Set" = true
264
275
  "datahold.Collection" = true
265
276
 
277
+ [datatypes.MutableSetLike.attributes]
278
+ copy = "datahold.MutableObjectLike"
279
+
266
280
  [datatypes.MutableSetLike.issubclass]
267
281
  "collections.abc.Hashable" = false
268
282
  "collections.abc.MutableSet" = true
269
283
  "collections.abc.Set" = true
270
284
  "datahold.Collection" = true
285
+ "datahold.MutableObjectLike" = true
271
286
  "datahold.MutableSet" = true
272
287
  "datahold.SetLike" = true
273
288
 
@@ -278,6 +293,15 @@ sort = ""
278
293
  "datahold.MutableSet" = true
279
294
  "datahold.MutableSetLike" = true
280
295
 
296
+ [datatypes.Object.varia]
297
+ generic = 1
298
+
299
+ [datatypes.ObjectSlot.issubclass]
300
+ "datahold.Object" = true
301
+
302
+ [datatypes.ObjectSlot.varia]
303
+ generic = 1
304
+
281
305
  [datatypes.Sequence]
282
306
 
283
307
  [datatypes.Set.issubclass]
@@ -1,50 +0,0 @@
1
- import operator
2
- import unittest
3
- from typing import Any, Self
4
-
5
- from Lazy import Lazy
6
-
7
-
8
- class TestInternalComparsion(unittest.TestCase):
9
- def _test_typename(self: Self, typename: str, /, **kwargs: Any) -> None:
10
- for opername, info in kwargs.items():
11
- oper = getattr(operator, opername)
12
- with self.subTest(operator=opername):
13
- self._test_operator(typename, oper, **info)
14
-
15
- def _test_operator(self: Self, *args: Any, **kwargs: Any) -> None:
16
- for testname, testinfo in kwargs.items():
17
- with self.subTest(testname=testname):
18
- self._test_vars(*args, **testinfo)
19
-
20
- def _test_vars(
21
- self: Self,
22
- typename: str,
23
- oper: Any,
24
- /,
25
- *,
26
- a: str,
27
- b: str,
28
- valid: bool = True,
29
- ) -> None:
30
- example_a = Lazy.get_example(typename, a)
31
- example_b = Lazy.get_example(typename, b)
32
- builtin_a = Lazy.get_builtin_example(typename, a)
33
- builtin_b = Lazy.get_builtin_example(typename, b)
34
- if valid:
35
- answer = oper(example_a, example_b)
36
- solution = oper(builtin_a, builtin_b)
37
- self.assertEqual(answer, solution)
38
- return
39
- with self.assertRaises(Exception):
40
- answer = oper(example_a, example_b)
41
- with self.assertRaises(Exception):
42
- solution = oper(builtin_a, builtin_b)
43
-
44
- def test_internal_comparison(self: Self) -> None:
45
- for typename, info in Lazy.lazy.datatypes.items():
46
- with self.subTest(typename=typename):
47
- self._test_typename(
48
- typename,
49
- **info.get("TestInternalComparsion", {}),
50
- )
File without changes