RecursiveNamespaceV2
Description
RecursiveNamespaceV2 extends Python's SimpleNamespace to make nested dicts easy to work with using attribute access, dict access, and chain-keys.
Full documentation: https://recursivenamespacev2.readthedocs.io/
Key features:
- Recursive conversion of nested dicts/lists
- Attribute and dict access (
rn.aandrn["a"]) - Chain-key access (
rn._.val_get("a.b.c")) - Array indexing and append syntax (
items[].0,items[].#) - Typed, zero-dependency, pure Python
Installation
pip install RecursiveNamespaceV2
Or with uv:
uv add RecursiveNamespaceV2
For development from source:
git clone https://github.com/pasxd245/RecursiveNamespaceV2.git
cd RecursiveNamespaceV2
uv venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
uv pip install -e ".[test]"
Quick Start
from recursivenamespace import RNS # or RecursiveNamespace
data = {
'name': 'John',
'age': 30,
'address': {
'street': '123 Main St',
'city': 'Anytown'
},
'friends': ['Jane', 'Tom']
}
rn = RNS(data)
print(rn.address.city) # Anytown
print(rn["friends"][1]) # Tom
# Chain-key access
rn._.val_set("address.zip", "12345")
print(rn._.val_get("address.zip")) # 12345
# Convert back to dict
data2 = rn._.to_dict()
print(data2["address"]["city"]) # Anytown
Accessing methods when data keys collide
User data often contains keys like "items", "keys", "update", or
"to_dict". These names share namespace with library methods, so the
library keeps them reachable from one canonical place: the obj._
proxy.
- Data with method-name keys is accepted.
RNS({"items": [...]})works; the value is stored underobj["items"]andobj.items. AFutureWarningreminds you that the matching method must now be called asobj._.items().FutureWarning(notDeprecationWarning) so the signal surfaces under Python's default warning filter — you'll see it the first time a user-supplied key collides, without needing-W default. - Direct calls to the legacy methods (
obj.to_dict(),obj.items(), …) emitDeprecationWarningand forward to the proxy. They will be removed in v0.1.0 (the first stable release); migrate toobj._.<method>(...)before then. Because this category is silenced by Python's default filter, run with-W defaultor enable warnings in your test runner (e.g.pytest -W default) to see these during migration. _itself is reserved. Data keys named"_"raiseKeyError.
rn = RNS({"name": "John"})
# Preferred (silent):
rn._.to_dict()
rn._.val_set("address.zip", "12345")
# Also works — class-level, useful in tests and tooling:
RNS._.to_dict(rn)
# Legacy (works but warns):
rn.to_dict() # DeprecationWarning
See docs/guides/method-proxy.rst for
the full migration plan and
examples/advanced/13_method_proxy.py
for a runnable example.
Examples
See the examples/ directory for 15 runnable examples organized by difficulty (basic, intermediate, advanced, real-world).
Testing
To run tests, navigate to the project's root directory and execute:
uv run pytest -s
# or with coverage:
uv run coverage run -m pytest
# to generate html report:
uv run coverage html
Release
Versions are derived automatically from git tags (via hatch-vcs):
git tag -a v1.2.3 -m "v1.2.3"
git push --tags
CI automatically builds, publishes to PyPI (OIDC trusted publishing), and creates a GitHub Release with auto-generated notes.
Contributing
Contributions to the RecursiveNamespace project are welcome! Please ensure that any pull requests include tests covering new features or fixes. See CONTRIBUTING.md for details.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Transparency
AI-assisted development (e.g., Claude Code, Copilot) was used for scaffolding and iteration.
Release files for RecursiveNamespaceV2 0.0.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| recursivenamespacev2-0.0.5.tar.gz | 15.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| recursivenamespacev2-0.0.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 31.6 kB
Release files / recursivenamespacev2-0.0.5.tar.gz
| Download URL | recursivenamespacev2-0.0.5.tar.gz |
|---|---|
| Size | 15.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3c0780ad7b002ec2e4842061423d8fb19a93265995b69acaf4de7da196cd056b
|
|
BLAKE2b-256 checksum How to use checksums |
366b72d008025d010320ed7fb2aebd15112fc48da43037aa37720dc91c7f7395
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 26, 2026.
Transparency logRelease files / recursivenamespacev2-0.0.5-py3-none-any.whl
| Download URL | recursivenamespacev2-0.0.5-py3-none-any.whl |
|---|---|
| Size | 15.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5117369ff853033e27879015de6cc00c77d997aa966db0b2dd80ac9d9ab67381
|
|
BLAKE2b-256 checksum How to use checksums |
b51cf78cdd9318b4e40f488ae5c0c4e03733f408c39e6cf148bd2876b1ee36c3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 26, 2026.
Transparency log