Skip to main content

Recursive Namespace. An extension of SimpleNamespace. Enhance get/set and parse from JSON

Project description

RecursiveNamespaceV2

CI Type Check codecov Python Version PyPI version License Code style: ruff

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.a and rn["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 under obj["items"] and obj.items. A FutureWarning reminds you that the matching method must now be called as obj._.items(). FutureWarning (not DeprecationWarning) 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(), …) emit DeprecationWarning and forward to the proxy. They will be removed in v0.1.0 (the first stable release); migrate to obj._.<method>(...) before then. Because this category is silenced by Python's default filter, run with -W default or enable warnings in your test runner (e.g. pytest -W default) to see these during migration.
  • _ itself is reserved. Data keys named "_" raise KeyError.
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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

recursivenamespacev2-0.0.5.tar.gz (15.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

recursivenamespacev2-0.0.5-py3-none-any.whl (15.9 kB view details)

Uploaded Python 3

File details

Details for the file recursivenamespacev2-0.0.5.tar.gz.

File metadata

  • Download URL: recursivenamespacev2-0.0.5.tar.gz
  • Upload date:
  • Size: 15.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for recursivenamespacev2-0.0.5.tar.gz
Algorithm Hash digest
SHA256 3c0780ad7b002ec2e4842061423d8fb19a93265995b69acaf4de7da196cd056b
MD5 c07262e13733ab75a12f50e412ce41a7
BLAKE2b-256 366b72d008025d010320ed7fb2aebd15112fc48da43037aa37720dc91c7f7395

See more details on using hashes here.

Provenance

The following attestation bundles were made for recursivenamespacev2-0.0.5.tar.gz:

Publisher: publish.yml on pasxd245/RecursiveNamespaceV2

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file recursivenamespacev2-0.0.5-py3-none-any.whl.

File metadata

File hashes

Hashes for recursivenamespacev2-0.0.5-py3-none-any.whl
Algorithm Hash digest
SHA256 5117369ff853033e27879015de6cc00c77d997aa966db0b2dd80ac9d9ab67381
MD5 83a6505bf2f4459a48ae015553e42bf6
BLAKE2b-256 b51cf78cdd9318b4e40f488ae5c0c4e03733f408c39e6cf148bd2876b1ee36c3

See more details on using hashes here.

Provenance

The following attestation bundles were made for recursivenamespacev2-0.0.5-py3-none-any.whl:

Publisher: publish.yml on pasxd245/RecursiveNamespaceV2

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page