{"id":2109,"library":"magicattr","title":"MagicAttr","description":"MagicAttr (current version 0.1.6) provides an enhanced `getattr` and `setattr` functionality for Python, capable of navigating and modifying attributes within deeply nested objects, lists, and dictionaries. It stands out by retaining the original cause of failure instead of exclusively raising an `AttributeError`, offering more granular error information. The library sees infrequent but active maintenance, with the latest release in January 2022.","status":"active","version":"0.1.6","language":"en","source_language":"en","source_url":"https://github.com/frmdstryr/magicattr","tags":["attribute","nested","getattr","setattr","utility","reflection","data-manipulation"],"install":[{"cmd":"pip install magicattr","lang":"bash","label":"Install latest version"}],"dependencies":[],"imports":[{"symbol":"magicattr","correct":"from magicattr import magicattr"}],"quickstart":{"code":"from magicattr import magicattr\n\nclass Person:\n    def __init__(self, name, age, settings=None, friends=None):\n        self.name = name\n        self.age = age\n        self.settings = settings if settings is not None else {}\n        self.friends = friends if friends is not None else []\n\nbob = Person(\"Bob\", 30, {'preferences': {'theme': 'dark'}})\njill = Person(\"Jill\", 25, friends=[Person(\"Jack\", 28), Person(\"Jane\", 27)])\n\n# Get a nested attribute\ntheme = magicattr.get(bob, 'settings.preferences.theme')\nprint(f\"Bob's theme: {theme}\")\n\n# Set a nested attribute\nmagicattr.set(bob, 'age', 32)\nprint(f\"Bob's new age: {bob.age}\")\n\nmagicattr.set(jill, 'friends[0].age', 29)\nprint(f\"Jill's first friend's new age: {jill.friends[0].age}\")\n\n# Delete a nested attribute\nmagicattr.delete(jill, 'friends[0]')\nprint(f\"Jill's friends after deletion: {[f.name for f in jill.friends] if jill.friends else 'None'}\")\n\n# Demonstrate setting a new deeply nested attribute, creating intermediate dicts\nmagicattr.set(bob, 'address.city', 'New York')\nprint(f\"Bob's city: {bob.address.city}\")\n","lang":"python","description":"Demonstrates getting, setting, and deleting nested attributes using string paths, including auto-creation of intermediate dictionary structures."},"warnings":[{"fix":"Ensure attribute paths are simple dot-separated or bracket-indexed strings. Perform complex logic outside the `magicattr` call.","message":"MagicAttr's path parsing does not support advanced Python syntax such as slicing (e.g., `list[1:3]`), arbitrary expressions (e.g., `list[0+1]`), function calls (e.g., `list.pop(0)`), or `eval` related constructs within the attribute string. Attempting to use these will result in `NotImplementedError` or `ValueError`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Inspect the return value carefully for `None` or specific exceptions like `KeyError` or `IndexError` when an attribute might not exist, rather than solely catching `AttributeError`.","message":"Unlike standard `getattr`/`setattr` which consistently raise `AttributeError` for missing or invalid attributes, `magicattr` aims to return the underlying exception (e.g., `KeyError` for dicts, `IndexError` for lists) or `None` for missing attributes/indices. This can lead to different error handling patterns than typically expected from Python's built-in attribute access.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Explicitly initialize intermediate objects with the desired types before using `magicattr.set()` if `dict` or `list` are not appropriate defaults.","message":"When using `magicattr.set()` to create new, deeply nested structures (e.g., `magicattr.set(obj, 'new_attr.nested_key', 'value')`), the library automatically infers and creates intermediate `dict` or `list` types as needed. While convenient, this might not always align with expectations if a different custom object type was desired for those intermediate steps.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-09T00:00:00.000Z","next_check":"2026-07-08T00:00:00.000Z"}