enumerific 1.0.6__tar.gz → 1.0.8__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. {enumerific-1.0.6/source/enumerific.egg-info → enumerific-1.0.8}/PKG-INFO +37 -1
  2. {enumerific-1.0.6 → enumerific-1.0.8}/README.md +36 -0
  3. {enumerific-1.0.6 → enumerific-1.0.8}/source/enumerific/extensible.py +37 -5
  4. enumerific-1.0.8/source/enumerific/version.txt +1 -0
  5. {enumerific-1.0.6 → enumerific-1.0.8/source/enumerific.egg-info}/PKG-INFO +37 -1
  6. {enumerific-1.0.6 → enumerific-1.0.8}/tests/test_extensible_enums.py +56 -2
  7. enumerific-1.0.6/source/enumerific/version.txt +0 -1
  8. {enumerific-1.0.6 → enumerific-1.0.8}/LICENSE.md +0 -0
  9. {enumerific-1.0.6 → enumerific-1.0.8}/pyproject.toml +0 -0
  10. {enumerific-1.0.6 → enumerific-1.0.8}/requirements.development.txt +0 -0
  11. {enumerific-1.0.6 → enumerific-1.0.8}/requirements.distribution.txt +0 -0
  12. {enumerific-1.0.6 → enumerific-1.0.8}/requirements.txt +0 -0
  13. {enumerific-1.0.6 → enumerific-1.0.8}/setup.cfg +0 -0
  14. {enumerific-1.0.6 → enumerific-1.0.8}/source/enumerific/__init__.py +0 -0
  15. {enumerific-1.0.6 → enumerific-1.0.8}/source/enumerific/exceptions.py +0 -0
  16. {enumerific-1.0.6 → enumerific-1.0.8}/source/enumerific/logging.py +0 -0
  17. {enumerific-1.0.6 → enumerific-1.0.8}/source/enumerific/standard.py +0 -0
  18. {enumerific-1.0.6 → enumerific-1.0.8}/source/enumerific.egg-info/SOURCES.txt +0 -0
  19. {enumerific-1.0.6 → enumerific-1.0.8}/source/enumerific.egg-info/dependency_links.txt +0 -0
  20. {enumerific-1.0.6 → enumerific-1.0.8}/source/enumerific.egg-info/requires.txt +0 -0
  21. {enumerific-1.0.6 → enumerific-1.0.8}/source/enumerific.egg-info/top_level.txt +0 -0
  22. {enumerific-1.0.6 → enumerific-1.0.8}/source/enumerific.egg-info/zip-safe +0 -0
  23. {enumerific-1.0.6 → enumerific-1.0.8}/tests/test_enumerific_library.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: enumerific
3
- Version: 1.0.6
3
+ Version: 1.0.8
4
4
  Summary: Simplifies working with Python enums.
5
5
  Author: Daniel Sissman
6
6
  License-Expression: MIT
@@ -675,6 +675,42 @@ assert Colors.PURPLE.rgb == (255, 0, 255)
675
675
  assert Colors.PURPLE.primary is False
676
676
  ```
677
677
 
678
+ #### Example 19: Reconciling Enumeration Options via Annotations
679
+
680
+ ```python
681
+ from enumerific import Enumeration, auto
682
+
683
+ class Colors(Enumeration):
684
+ """Create a test Color enumeration based on the Enumeration class"""
685
+
686
+ RED = auto(RGB=(255, 0, 0))
687
+ GREEN = auto(RGB=(0, 255, 0))
688
+ BLUE = auto(RGB=(0, 0, 255))
689
+
690
+ # Ensure that the Colors enumeration subclass is of the expected types
691
+ assert issubclass(Colors, Enumeration)
692
+
693
+ # Attempt to reconcile a Color against one of its annotations (via annotation keyword)
694
+ color = Colors.reconcile(RGB=(255, 0, 0))
695
+
696
+ assert isinstance(color, Colors)
697
+ assert isinstance(color, Enumeration)
698
+
699
+ assert color.name == "RED"
700
+ assert color.value == 1
701
+ assert color.RGB == (255, 0, 0)
702
+
703
+ # Attempt to reconcile a Color against one of its annotations (via annotation argument)
704
+ color = Colors.reconcile(value=(0, 255, 0), annotation="RGB")
705
+
706
+ assert isinstance(color, Colors)
707
+ assert isinstance(color, Enumeration)
708
+
709
+ assert color.name == "GREEN"
710
+ assert color.value == 2
711
+ assert color.RGB == (0, 255, 0)
712
+ ```
713
+
678
714
  # Enumerific Library Enumerations: Classes & Methods
679
715
 
680
716
  The Enumerific library's `Enumeration` class is a greenfield implementation of enumerations
@@ -645,6 +645,42 @@ assert Colors.PURPLE.rgb == (255, 0, 255)
645
645
  assert Colors.PURPLE.primary is False
646
646
  ```
647
647
 
648
+ #### Example 19: Reconciling Enumeration Options via Annotations
649
+
650
+ ```python
651
+ from enumerific import Enumeration, auto
652
+
653
+ class Colors(Enumeration):
654
+ """Create a test Color enumeration based on the Enumeration class"""
655
+
656
+ RED = auto(RGB=(255, 0, 0))
657
+ GREEN = auto(RGB=(0, 255, 0))
658
+ BLUE = auto(RGB=(0, 0, 255))
659
+
660
+ # Ensure that the Colors enumeration subclass is of the expected types
661
+ assert issubclass(Colors, Enumeration)
662
+
663
+ # Attempt to reconcile a Color against one of its annotations (via annotation keyword)
664
+ color = Colors.reconcile(RGB=(255, 0, 0))
665
+
666
+ assert isinstance(color, Colors)
667
+ assert isinstance(color, Enumeration)
668
+
669
+ assert color.name == "RED"
670
+ assert color.value == 1
671
+ assert color.RGB == (255, 0, 0)
672
+
673
+ # Attempt to reconcile a Color against one of its annotations (via annotation argument)
674
+ color = Colors.reconcile(value=(0, 255, 0), annotation="RGB")
675
+
676
+ assert isinstance(color, Colors)
677
+ assert isinstance(color, Enumeration)
678
+
679
+ assert color.name == "GREEN"
680
+ assert color.value == 2
681
+ assert color.RGB == (0, 255, 0)
682
+ ```
683
+
648
684
  # Enumerific Library Enumerations: Classes & Methods
649
685
 
650
686
  The Enumerific library's `Enumeration` class is a greenfield implementation of enumerations
@@ -1458,29 +1458,61 @@ class EnumerationMetaClass(type):
1458
1458
  value: Enumeration | object = None,
1459
1459
  name: str = None,
1460
1460
  caselessly: bool = False,
1461
+ annotation: str = None,
1462
+ **annotations: dict[str, object],
1461
1463
  ) -> Enumeration | None:
1462
1464
  """The 'reconcile' method can be used to reconcile Enumeration type, enumeration
1463
1465
  values, or enumeration names to their matching Enumeration type instances. If a
1464
1466
  match is found the Enumeration type instance will be returned otherwise None will
1465
1467
  be returned, unless the class is configured to raise an error for mismatches."""
1466
1468
 
1467
- if name is None and value is None:
1469
+ if isinstance(annotation, str):
1470
+ annotations[annotation] = value
1471
+
1472
+ if name is None and value is None and len(annotations) == 0:
1468
1473
  raise ValueError(
1469
- "Either the 'value' or 'name' argument must be specified when calling the 'reconcile' function!"
1474
+ "Either a 'value', 'name' or annotation keyword argument must be specified when calling the 'reconcile' function!"
1470
1475
  )
1471
1476
 
1472
1477
  if not value is None and not isinstance(value, (Enumeration, object)):
1473
1478
  raise TypeError(
1474
- "The 'value' argument must reference an Enumeration type or have an enumeration value!"
1479
+ "The 'value' argument, if specified, must reference an Enumeration type or have an enumeration value!"
1475
1480
  )
1476
1481
 
1477
1482
  if not name is None and not isinstance(name, str):
1478
- raise TypeError("The 'name' argument must have a string value!")
1483
+ raise TypeError(
1484
+ "The 'name' argument, if specified, must have a string value!"
1485
+ )
1479
1486
 
1480
1487
  reconciled: Enumeration = None
1481
1488
 
1482
1489
  for attribute, enumeration in self._enumerations.items():
1483
- if isinstance(value, Enumeration):
1490
+ if len(annotations) > 0:
1491
+ comparisons: list[bool] = []
1492
+
1493
+ for annotation, value in annotations.items():
1494
+ if annotation in enumeration._annotations:
1495
+ if enumeration._annotations[annotation] is value:
1496
+ comparisons.append(True)
1497
+ elif enumeration._annotations[annotation] == value:
1498
+ comparisons.append(True)
1499
+ else:
1500
+ comparisons.append(False)
1501
+ else:
1502
+ comparisons.append(False)
1503
+
1504
+ logger.debug(
1505
+ "The enumeration option, %s, has no '%s' annotation!"
1506
+ % (
1507
+ enumeration,
1508
+ annotation,
1509
+ )
1510
+ )
1511
+
1512
+ if len(comparisons) == len(annotations) and False not in comparisons:
1513
+ reconciled = enumeration
1514
+ break
1515
+ elif isinstance(value, Enumeration):
1484
1516
  if enumeration is value:
1485
1517
  reconciled = enumeration
1486
1518
  break
@@ -0,0 +1 @@
1
+ 1.0.8
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: enumerific
3
- Version: 1.0.6
3
+ Version: 1.0.8
4
4
  Summary: Simplifies working with Python enums.
5
5
  Author: Daniel Sissman
6
6
  License-Expression: MIT
@@ -675,6 +675,42 @@ assert Colors.PURPLE.rgb == (255, 0, 255)
675
675
  assert Colors.PURPLE.primary is False
676
676
  ```
677
677
 
678
+ #### Example 19: Reconciling Enumeration Options via Annotations
679
+
680
+ ```python
681
+ from enumerific import Enumeration, auto
682
+
683
+ class Colors(Enumeration):
684
+ """Create a test Color enumeration based on the Enumeration class"""
685
+
686
+ RED = auto(RGB=(255, 0, 0))
687
+ GREEN = auto(RGB=(0, 255, 0))
688
+ BLUE = auto(RGB=(0, 0, 255))
689
+
690
+ # Ensure that the Colors enumeration subclass is of the expected types
691
+ assert issubclass(Colors, Enumeration)
692
+
693
+ # Attempt to reconcile a Color against one of its annotations (via annotation keyword)
694
+ color = Colors.reconcile(RGB=(255, 0, 0))
695
+
696
+ assert isinstance(color, Colors)
697
+ assert isinstance(color, Enumeration)
698
+
699
+ assert color.name == "RED"
700
+ assert color.value == 1
701
+ assert color.RGB == (255, 0, 0)
702
+
703
+ # Attempt to reconcile a Color against one of its annotations (via annotation argument)
704
+ color = Colors.reconcile(value=(0, 255, 0), annotation="RGB")
705
+
706
+ assert isinstance(color, Colors)
707
+ assert isinstance(color, Enumeration)
708
+
709
+ assert color.name == "GREEN"
710
+ assert color.value == 2
711
+ assert color.RGB == (0, 255, 0)
712
+ ```
713
+
678
714
  # Enumerific Library Enumerations: Classes & Methods
679
715
 
680
716
  The Enumerific library's `Enumeration` class is a greenfield implementation of enumerations
@@ -1613,8 +1613,8 @@ def test_membership_in_tuple():
1613
1613
  assert Colors.VIOLET not in colors
1614
1614
 
1615
1615
 
1616
- def test_attribute_access():
1617
- """Test access to attributes (methods, properties, etc) on an Enumeration subclass"""
1616
+ def test_annotation_access():
1617
+ """Test access to annotations (methods, properties, etc) on an Enumeration subclass"""
1618
1618
 
1619
1619
  class Colors(Enumeration, backfill=True):
1620
1620
  """Create a test Color enumeration based on the Enumeration class"""
@@ -1812,3 +1812,57 @@ def test_attribute_access():
1812
1812
  assert color.isMetallic() is False # isMetallic() is defined on the Colors subclass
1813
1813
  assert color.HEX == "FF0000" # HEX is a property defined on the Colors subclass
1814
1814
  assert color.count() == 8 # count() is a classmethod defined on the Colors subclass
1815
+
1816
+
1817
+ def test_annotation_reconciliation():
1818
+ """Test reconciliation of enumeration options via their annotations."""
1819
+
1820
+ class Colors(Enumeration):
1821
+ """Create a test Color enumeration based on the Enumeration class"""
1822
+
1823
+ RED = auto(RGB=(255, 0, 0), primary=True)
1824
+ ORANGE = auto(RGB=(255, 165, 0))
1825
+ YELLOW = auto(RGB=(255, 255, 0), primary=True)
1826
+ GREEN = auto(RGB=(0, 255, 0))
1827
+ BLUE = auto(RGB=(0, 0, 255), primary=True)
1828
+ VIOLET = auto(RGB=(255, 0, 255))
1829
+
1830
+ # Ensure that the Colors enumeration subclass is of the expected types
1831
+ assert issubclass(Colors, Enumeration)
1832
+ assert issubclass(Colors, EnumerationInteger)
1833
+
1834
+ # Attempt to reconcile a Color against one of its annotations (via annotation keyword)
1835
+ color = Colors.reconcile(RGB=(255, 0, 0))
1836
+
1837
+ assert isinstance(color, Colors)
1838
+ assert isinstance(color, Enumeration)
1839
+
1840
+ assert color.name == "RED"
1841
+ assert color.value == 1
1842
+ assert color.RGB == (255, 0, 0)
1843
+
1844
+ # Attempt to reconcile a Color against two of its annotations (via annotation keywords)
1845
+ color = Colors.reconcile(RGB=(255, 255, 0), primary=True)
1846
+
1847
+ assert isinstance(color, Colors)
1848
+ assert isinstance(color, Enumeration)
1849
+
1850
+ assert color.name == "YELLOW"
1851
+ assert color.value == 3
1852
+ assert color.RGB == (255, 255, 0)
1853
+
1854
+ # Attempt to reconcile a Color against one of its annotations (via annotation argument)
1855
+ color = Colors.reconcile(value=(0, 255, 0), annotation="RGB")
1856
+
1857
+ assert isinstance(color, Colors)
1858
+ assert isinstance(color, Enumeration)
1859
+
1860
+ assert color.name == "GREEN"
1861
+ assert color.value == 4
1862
+ assert color.RGB == (0, 255, 0)
1863
+
1864
+ # Test reconciliation against a non-existent option
1865
+ color = Colors.reconcile(RGB=(125, 125, 125))
1866
+
1867
+ # Ensure the return value is None when a matching enumeration option cannot be found
1868
+ assert color is None
@@ -1 +0,0 @@
1
- 1.0.6
File without changes
File without changes
File without changes
File without changes