# Nested Property Library for Python
A lightweight Python library for **accessing, modifying, and manipulating nested dictionaries and lists** using dot-separated paths. Inspired by JavaScript libraries like `nested-property`, with support for **multi-character list index prefixes**.
---
## Features
- **Get** nested values: `get(obj, path)`
- **Set** nested values: `set(obj, path, value)`
- **Delete** nested values: `delete(obj, path)`
- **Check existence**: `has(obj, path)`
- **Push** values to nested lists: `push(obj, path, value)`
- **Pull** values from nested lists: `pull(obj, path, value=None, index=None)`
- Supports **list indices with optional prefixes**, e.g., `"$0"` or `"idx_0"`
- Default behavior treats numeric keys as list indices automatically (`index_prefix=None`)
---
## Installation
```
pip install nested-property
```
## Usage
import the functions
```
from nested_property import get, set, delete, has, push, pull
```
Note that you can also import `unset` which is an alias for `delete`
Basic usage
```
data = {"a": {"b": {"c": 42}}}
# Get a value
print(get(data, "a.b.c")) # 42
# Set a value
set(data, "a.b.d", 100)
print(data) # {'a': {'b': {'c': 42, 'd': 100}}}
# Check existence
print(has(data, "a.b.c")) # True
# Delete a value
delete(data, "a.b.c")
print(has(data, "a.b.c")) # False
```
Working with lists
```
data = {"items": [1, 2, 3]}
# Push a value to a list
push(data, "items", 4)
print(get(data, "items")) # [1, 2, 3, 4]
# Pull a value by value
pull(data, "items", value=2)
print(get(data, "items")) # [1, 3, 4]
# Pull a value by index
pull(data, "items", index=0)
print(get(data, "items")) # [3, 4]
```
Using index prefix
```
data = {}
# Use "@" as prefix
set(data, "a.b.@0.items", [1, 2, 3], index_prefix="@")
push(data, "a.b.@0.items", 4, index_prefix="@")
print(get(data, "a.b.@0.items", index_prefix="@")) # [1, 2, 3, 4]
# Use multi-character prefix "idx_"
set(data, "x.y.idx_0.list", [10, 20], index_prefix="idx_")
pull(data, "x.y.idx_0.list", value=10, index_prefix="idx_")
print(get(data, "x.y.idx_0.list", index_prefix="idx_")) # [20]
```
Mixed usage
```
data = {"a": [{"b": [1, 2, 3]}]}
# Numeric keys work without prefix
print(get(data, "a.0.b")) # [1, 2, 3]
# Push to nested list
push(data, "a.0.b", 4)
print(get(data, "a.0.b")) # [1, 2, 3, 4]
```
## API
| Function | Description | Parameters |
|----------|-------------|------------|
| `get(obj, path, default=None, index_prefix=None)` | Get nested value | `obj`: dict/list, `path`: str, `default`: any, `index_prefix`: str or None |
| `set(obj, path, value, index_prefix=None)` | Set nested value | `obj`: dict/list, `path`: str, `value`: any, `index_prefix`: str or None |
| `delete(obj, path, index_prefix=None)` | Delete nested value | `obj`: dict/list, `path`: str, `index_prefix`: str or None |
| `unset(obj, path, index_prefix=None)` | Alias for Delete | `obj`: dict/list, `path`: str, `index_prefix`: str or None |
| `has(obj, path, index_prefix=None)` | Check if nested value exists | `obj`: dict/list, `path`: str, `index_prefix`: str or None |
| `push(obj, path, value, index_prefix=None)` | Append value to nested list | `obj`: dict/list, `path`: str, `value`: any, `index_prefix`: str or None |
| `pull(obj, path, value=None, index=None, index_prefix=None)` | Remove value from nested list by value or index | `obj`: dict/list, `path`: str, `value`: any, `index`: int, `index_prefix`: str or None |
## Notes
Dot-separated paths are used for nested keys, e.g., `"a.b.c"` or `"x.y.0.z"`.
Index prefixes allow you to distinguish numeric dictionary keys from list indices.
When `index_prefix=None` (default), any key that is a valid integer string is treated as a list index automatically.
## License
MIT License
## Author
Created by Giles Tetteh. Inspired by JavaScript nested-property library.
Raw data
{
"_id": null,
"home_page": "https://github.com/giesekow/nested-property",
"name": "nested-property",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "nested-property, dict-property",
"author": "Giles Tetteh",
"author_email": "giles.ekow.tetteh@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/df/6d/41adb1512f260bfb4e50ff863817f962b1dfff40ac72e6e586513334f21e/nested_property-1.0.1.tar.gz",
"platform": null,
"description": "# Nested Property Library for Python\n\nA lightweight Python library for **accessing, modifying, and manipulating nested dictionaries and lists** using dot-separated paths. Inspired by JavaScript libraries like `nested-property`, with support for **multi-character list index prefixes**.\n\n---\n\n## Features\n\n- **Get** nested values: `get(obj, path)`\n- **Set** nested values: `set(obj, path, value)`\n- **Delete** nested values: `delete(obj, path)`\n- **Check existence**: `has(obj, path)`\n- **Push** values to nested lists: `push(obj, path, value)`\n- **Pull** values from nested lists: `pull(obj, path, value=None, index=None)`\n- Supports **list indices with optional prefixes**, e.g., `\"$0\"` or `\"idx_0\"`\n- Default behavior treats numeric keys as list indices automatically (`index_prefix=None`)\n\n---\n\n## Installation\n\n```\npip install nested-property\n```\n\n## Usage\n\nimport the functions\n```\nfrom nested_property import get, set, delete, has, push, pull\n```\nNote that you can also import `unset` which is an alias for `delete`\n\nBasic usage\n```\ndata = {\"a\": {\"b\": {\"c\": 42}}}\n\n# Get a value\nprint(get(data, \"a.b.c\")) # 42\n\n# Set a value\nset(data, \"a.b.d\", 100)\nprint(data) # {'a': {'b': {'c': 42, 'd': 100}}}\n\n# Check existence\nprint(has(data, \"a.b.c\")) # True\n\n# Delete a value\ndelete(data, \"a.b.c\")\nprint(has(data, \"a.b.c\")) # False\n```\n\nWorking with lists\n```\ndata = {\"items\": [1, 2, 3]}\n\n# Push a value to a list\npush(data, \"items\", 4)\nprint(get(data, \"items\")) # [1, 2, 3, 4]\n\n# Pull a value by value\npull(data, \"items\", value=2)\nprint(get(data, \"items\")) # [1, 3, 4]\n\n# Pull a value by index\npull(data, \"items\", index=0)\nprint(get(data, \"items\")) # [3, 4]\n```\n\nUsing index prefix\n```\ndata = {}\n\n# Use \"@\" as prefix\nset(data, \"a.b.@0.items\", [1, 2, 3], index_prefix=\"@\")\npush(data, \"a.b.@0.items\", 4, index_prefix=\"@\")\nprint(get(data, \"a.b.@0.items\", index_prefix=\"@\")) # [1, 2, 3, 4]\n\n# Use multi-character prefix \"idx_\"\nset(data, \"x.y.idx_0.list\", [10, 20], index_prefix=\"idx_\")\npull(data, \"x.y.idx_0.list\", value=10, index_prefix=\"idx_\")\nprint(get(data, \"x.y.idx_0.list\", index_prefix=\"idx_\")) # [20]\n```\n\nMixed usage\n```\ndata = {\"a\": [{\"b\": [1, 2, 3]}]}\n\n# Numeric keys work without prefix\nprint(get(data, \"a.0.b\")) # [1, 2, 3]\n\n# Push to nested list\npush(data, \"a.0.b\", 4)\nprint(get(data, \"a.0.b\")) # [1, 2, 3, 4]\n```\n\n## API\n\n| Function | Description | Parameters |\n|----------|-------------|------------|\n| `get(obj, path, default=None, index_prefix=None)` | Get nested value | `obj`: dict/list, `path`: str, `default`: any, `index_prefix`: str or None |\n| `set(obj, path, value, index_prefix=None)` | Set nested value | `obj`: dict/list, `path`: str, `value`: any, `index_prefix`: str or None |\n| `delete(obj, path, index_prefix=None)` | Delete nested value | `obj`: dict/list, `path`: str, `index_prefix`: str or None |\n| `unset(obj, path, index_prefix=None)` | Alias for Delete | `obj`: dict/list, `path`: str, `index_prefix`: str or None |\n| `has(obj, path, index_prefix=None)` | Check if nested value exists | `obj`: dict/list, `path`: str, `index_prefix`: str or None |\n| `push(obj, path, value, index_prefix=None)` | Append value to nested list | `obj`: dict/list, `path`: str, `value`: any, `index_prefix`: str or None |\n| `pull(obj, path, value=None, index=None, index_prefix=None)` | Remove value from nested list by value or index | `obj`: dict/list, `path`: str, `value`: any, `index`: int, `index_prefix`: str or None |\n\n\n## Notes\nDot-separated paths are used for nested keys, e.g., `\"a.b.c\"` or `\"x.y.0.z\"`.\n\nIndex prefixes allow you to distinguish numeric dictionary keys from list indices.\n\nWhen `index_prefix=None` (default), any key that is a valid integer string is treated as a list index automatically.\n\n## License\nMIT License\n\n## Author\nCreated by Giles Tetteh. Inspired by JavaScript nested-property library.\n",
"bugtrack_url": null,
"license": null,
"summary": "A python based library inspired by nested-property module in javascript",
"version": "1.0.1",
"project_urls": {
"Homepage": "https://github.com/giesekow/nested-property"
},
"split_keywords": [
"nested-property",
" dict-property"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "ab587276cfb1dd31384aaf3dbeae65266fd8f878486942c05d93f7e356786ad3",
"md5": "4c8daaef3d61b28649406756f431c98b",
"sha256": "5793e979c07453019b36539786cb172f5330e52ce5169f194e46d127ec978b27"
},
"downloads": -1,
"filename": "nested_property-1.0.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "4c8daaef3d61b28649406756f431c98b",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 4893,
"upload_time": "2025-08-06T16:26:10",
"upload_time_iso_8601": "2025-08-06T16:26:10.475539Z",
"url": "https://files.pythonhosted.org/packages/ab/58/7276cfb1dd31384aaf3dbeae65266fd8f878486942c05d93f7e356786ad3/nested_property-1.0.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "df6d41adb1512f260bfb4e50ff863817f962b1dfff40ac72e6e586513334f21e",
"md5": "1e2c89aa23276e799b498bc5e2c8fb3f",
"sha256": "27f5a11d6597c4d8adb4a62d59d87ad887afb0b6224d5782a3ead436807605c7"
},
"downloads": -1,
"filename": "nested_property-1.0.1.tar.gz",
"has_sig": false,
"md5_digest": "1e2c89aa23276e799b498bc5e2c8fb3f",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 4677,
"upload_time": "2025-08-06T16:26:11",
"upload_time_iso_8601": "2025-08-06T16:26:11.353116Z",
"url": "https://files.pythonhosted.org/packages/df/6d/41adb1512f260bfb4e50ff863817f962b1dfff40ac72e6e586513334f21e/nested_property-1.0.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-06 16:26:11",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "giesekow",
"github_project": "nested-property",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "nested-property"
}