Skip to content

Instantly share code, notes, and snippets.

@Kaligraphy247
Created April 5, 2025 09:47
Show Gist options
  • Save Kaligraphy247/14021559bd599417e34acc7d332da9b5 to your computer and use it in GitHub Desktop.
Save Kaligraphy247/14021559bd599417e34acc7d332da9b5 to your computer and use it in GitHub Desktop.
Safe Dictionary Value Retrieval with Dot Notation
"""
Safe Dictionary Value Retrieval with Dot Notation
This module provides a function, `safe_get`, that safely retrieves values from
Python dictionaries, including nested dictionaries, using either a list of keys
or a dot-notation string. It avoids common `KeyError` exceptions and provides
a default value if the specified key path is not found.
This code was generated with the help Gemini 2.0 Flash. Test are completly AI generated. While Gemini 2.0 Flash has been trained
to generate correct and efficient code, it's essential to review and test
the code thoroughly before deploying it in a production environment.
Author: Written and formatted with Gemini 2.0 Flash
"""
from typing import Any, List, Dict, Optional, Union
def safe_get(data: Dict[str, Any], keys: Union[List[str], str], default: Optional[Any] = None) -> Any:
"""
Safely retrieves a value from a dictionary using either a list of keys
or a dot-notation string.
Args:
data (dict): The dictionary to traverse.
keys (Union[List[str], str]): A list of keys or a dot-notation string (e.g., "key1.key2.key3").
default: The value to return if the nested value is not found (default: None).
Returns:
The value if found, the specified default value otherwise.
"""
if isinstance(keys, str):
keys = keys.split('.') # Split dot-notation string into a list of keys
if not isinstance(keys, list):
raise TypeError("keys must be a list of strings or a dot-notation string")
current = data
for key in keys:
if isinstance(current, dict) and key in current:
current = current[key]
else:
return default
return current
import unittest
class NestedDictAccessTest(unittest.TestCase):
def setUp(self):
self.empty_dict = {}
self.one_level_dict = {'key1': {}}
self.two_level_dict = {'key1': {'key2': 123}}
self.none_value_dict = {'key1': None}
self.false_value_dict = {'key1': False}
self.zero_value_dict = {'key1': 0}
self.empty_list_value_dict = {'key1': []}
self.empty_string_value_dict = {'key1': ''}
self.deep_dict = {'key1': {'key2': {'key3': {'key4': {'key5': 'deep_value'}}}}}
def test_list_access_existing(self):
self.assertEqual(safe_get(self.two_level_dict, ['key1', 'key2']), 123)
self.assertEqual(safe_get(self.deep_dict, ['key1', 'key2', 'key3', 'key4', 'key5']), 'deep_value')
def test_list_access_missing(self):
self.assertIsNone(safe_get(self.empty_dict, ['key1', 'key2']))
self.assertIsNone(safe_get(self.one_level_dict, ['key1', 'key2']))
self.assertIsNone(safe_get(self.two_level_dict, ['key1', 'key3']))
self.assertIsNone(safe_get(self.deep_dict, ['key1', 'key2', 'key3', 'key4', 'key6']))
def test_list_access_default(self):
self.assertEqual(safe_get(self.empty_dict, ['key1', 'key2'], 'default'), 'default')
self.assertEqual(safe_get(self.one_level_dict, ['key1', 'key2'], 'default'), 'default')
self.assertEqual(safe_get(self.two_level_dict, ['key1', 'key3'], 'default'), 'default')
self.assertEqual(safe_get(self.deep_dict, ['key1', 'key2', 'key3', 'key4', 'key6'], 'default'), 'default')
def test_list_access_none_values(self):
self.assertIsNone(safe_get(self.none_value_dict, ['key1']))
self.assertIsNone(safe_get(self.false_value_dict, ['key1']))
self.assertIsNone(safe_get(self.zero_value_dict, ['key1']))
self.assertIsNone(safe_get(self.empty_list_value_dict, ['key1']))
self.assertIsNone(safe_get(self.empty_string_value_dict, ['key1']))
self.assertIsNone(safe_get(self.none_value_dict, ['key1', 'key2']))
def test_dot_notation_access_existing(self):
self.assertEqual(safe_get(self.two_level_dict, "key1.key2"), 123)
self.assertEqual(safe_get(self.deep_dict, "key1.key2.key3.key4.key5"), 'deep_value')
def test_dot_notation_access_missing(self):
self.assertIsNone(safe_get(self.empty_dict, "key1.key2"))
self.assertIsNone(safe_get(self.one_level_dict, "key1.key2"))
self.assertIsNone(safe_get(self.two_level_dict, "key1.key3"))
self.assertIsNone(safe_get(self.deep_dict, "key1.key2.key3.key4.key6"))
def test_dot_notation_access_default(self):
self.assertEqual(safe_get(self.empty_dict, "key1.key2", 'default'), 'default')
self.assertEqual(safe_get(self.one_level_dict, "key1.key2", 'default'), 'default')
self.assertEqual(safe_get(self.two_level_dict, "key1.key3", 'default'), 'default')
self.assertEqual(safe_get(self.deep_dict, "key1.key2.key3.key4.key6", 'default'), 'default')
def test_dot_notation_access_none_values(self):
self.assertIsNone(safe_get(self.none_value_dict, "key1"))
self.assertIsNone(safe_get(self.false_value_dict, "key1"))
self.assertIsNone(safe_get(self.zero_value_dict, "key1"))
self.assertIsNone(safe_get(self.empty_list_value_dict, "key1"))
self.assertIsNone(safe_get(self.empty_string_value_dict, "key1"))
self.assertIsNone(safe_get(self.none_value_dict, "key1.key2"))
def test_invalid_keys_type(self):
with self.assertRaises(TypeError):
safe_get(self.two_level_dict, 123) # type: ignore
def test_mixed_access(self):
# Test accessing with a mix of list and dot notation is NOT supported and should act like a failed lookup
self.assertIsNone(safe_get(self.deep_dict, ["key1", "key2.key3", "key4", "key5"]))
if __name__ == '__main__':
unittest.main()
@Kaligraphy247
Copy link
Author

Feel free to copy only the safe_get function, the tests are not mandatory.

@Kaligraphy247
Copy link
Author

More AI generated Test Data

realistic_dict = {
    "user_id": "user12345",
    "username": "john_doe",
    "email": "[email protected]",
    "profile": {
        "first_name": "John",
        "last_name": "Doe",
        "age": 30,
        "is_active": True,
        "address": {
            "street": "123 Main St",
            "city": "Anytown",
            "state": "CA",
            "zip_code": "91234"
        },
        "interests": ["reading", "hiking", "coding"],
    },
    "settings": {
        "notifications": {
            "email_enabled": True,
            "sms_enabled": False,
            "push_enabled": True,
        },
        "privacy": {
            "profile_visibility": "public",
            "data_sharing_enabled": False
        },
        "theme": "dark"
    },
    "last_login": "2024-01-01T12:00:00Z",
    "orders": [
        {
            "order_id": "order001",
            "date": "2023-12-25",
            "total": 49.99,
            "items": ["Book A", "Book B"]
        },
        {
            "order_id": "order002",
            "date": "2023-12-30",
            "total": 99.99,
            "items": ["Gadget X", "Gadget Y", "Gadget Z"]
        }
    ],
    "social_connections": {
        "friends": ["user0001", "user0002", "user0003"],
        "followers": ["user0004", "user0005"],
        "following": ["user0006", "user0007", "user0008"]
    },
    "preferences": {
        "language": "en",
        "currency": "USD",
        "timezone": "America/Los_Angeles"
    },
    "billing_address": None,
    "shipping_address": {
        "street": "456 Oak Ave",
        "city": "Springfield",
        "state": "IL",
        "zip_code": "62704"
    },
    "rewards": {
        "points": 150,
        "level": "Bronze"
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment