Skip to content

Commit

Permalink
Merge pull request #9 from jzombie/feature/0.7.0
Browse files Browse the repository at this point in the history
0.7.0
  • Loading branch information
jzombie authored Apr 4, 2024
2 parents 3b79710 + e6a3f7d commit f8d79af
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 6 deletions.
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

- **to_dict**: Convert an enum class to a dictionary representation, mapping member names to their values.
- **get_initial**: Retrieve the first value defined in the enum, useful for cases where a default or initial value is needed.
- **get**: Mimics the dictionary `get` method, allowing retrieval of enum values with an optional default fallback.
- **get**: Mimics the dictionary `get` method, allowing retrieval of enum values with an optional default fallback. Additionally, it supports an optional custom mapping dictionary for dynamically mapped value retrieval.
- **validate_mapping_keys**: Ensure that a provided mapping includes all enum values, raising an error for any missing mappings.
- **map**: Map enum members to values based on the provided dictionary.
- **keys**: Retrieve the keys of the enum class as a list or as a KeysView.
Expand Down Expand Up @@ -52,7 +52,7 @@ print(initial_color)

### Using the `get` Method

Retrieve an enum value by its name, with an option to specify a default value if the name does not exist.
Retrieve an enum value by its name, with an option to specify a default value if the name does not exist. Additionally, you can pass a custom mapping dictionary to retrieve a mapped value instead of the enum's default value.

#### Get a value for an existing key

Expand All @@ -72,6 +72,15 @@ print(Color.get('PURPLE', default='unknown')) # Output: 'unknown'
print(Color.get('PURPLE')) # Output: 'red'
```

### Get a value using a custom mapping

You can also use a custom mapping dictionary to retrieve a value. This is useful when you need to map enum members to different values dynamically.

```python
custom_mapping = {'RED': 'Rouge', 'GREEN': 'Vert', 'BLUE': 'Bleu'}
print(Color.get('RED', mapping=custom_mapping)) # Output: 'Rouge'
```

## Ensuring Completeness of Mappings with `validate_mapping_keys`

Validate that a provided mapping covers all enum members.
Expand Down
26 changes: 23 additions & 3 deletions enum_with_dict/enum_with_dict.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,31 @@ def get_initial(cls) -> Any:
return next(iter(cls.to_dict().values()))

@classmethod
def get(cls, key: str, default: Any = None) -> Any:
"""Get the value for the given key or return default or initial value."""
# If default is not provided, use the initial value
def get(cls, key: str, default: Any = None, mapping: Dict[str, Any] = None) -> Any:
"""
Get the value for the given key from the optional mapping or the enum,
return default or initial value if not found.
Args:
key (str): The key to look for.
default (Any, optional): The default value to return if the key is not found.
If not provided, the initial enum value is used.
mapping (Dict[str, Any], optional): An optional mapping of keys to custom values.
Returns:
Any: The value associated with the key, either from the mapping or the enum's default values.
"""
# Use the initial value as the default if no default is provided
if default is None:
default = cls.get_initial()

# If a mapping is provided, try to get the value from it
if mapping is not None:
cls.validate_mapping_keys(mapping)

return mapping.get(key, default)

# Fallback to the enum's default values if no mapping is provided or the key is not in the mapping
return cls.to_dict().get(key, default)

@classmethod
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

setup(
name='enum_with_dict',
version='0.6.2',
version='0.7.0',
packages=find_packages(),
author='Jeremy Harris',
author_email='[email protected]',
Expand Down
43 changes: 43 additions & 0 deletions test/test_enum_with_dict.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,5 +178,48 @@ class TestEnum(EnumWithDict):
self.assertNotEqual(TestEnum.values(as_list = False), [1,2,3])
self.assertEqual(list(TestEnum.values(as_list = False)), [1,2,3])

def test_get_with_mapping(self):
class TestEnum(EnumWithDict):
VALUE_1 = 1
VALUE_2 = 2
VALUE_3 = 3

custom_mapping = {
'VALUE_1': 'Mapped 1',
'VALUE_2': 'Mapped 2',
'VALUE_3': 'Mapped 3'
}

# Test getting a value from custom mapping
self.assertEqual(TestEnum.get('VALUE_1', mapping=custom_mapping), 'Mapped 1')

# Test getting a value without custom mapping
self.assertEqual(TestEnum.get('VALUE_3'), 3)

# Test getting a value with a default specified, when the key is not in the custom mapping or enum
self.assertEqual(TestEnum.get('VALUE_4', default='Default', mapping=custom_mapping), 'Default')

# Test getting a value without a default specified, when the key is not in the custom mapping or enum
# It should fall back to the initial value of the enum
self.assertEqual(TestEnum.get('VALUE_4', mapping=custom_mapping), 1) # Initial value

# Validation should fail because of incomplete mapping
with self.assertRaises(KeyError) as context:
TestEnum.get('VALUE_2', mapping={
'VALUE_2': 'Mapped 2',
})

# Validation should fail because of empty mapping
with self.assertRaises(KeyError) as context:
TestEnum.get('VALUE_2', mapping={})

# Validation should fail because of empty mapping
with self.assertRaises(KeyError) as context:
invalid_custom_mapping = custom_mapping
invalid_custom_mapping['VALUE_4'] = 'Mapped 4'

TestEnum.get('VALUE_2', mapping=invalid_custom_mapping)


if __name__ == '__main__':
unittest.main()

0 comments on commit f8d79af

Please sign in to comment.