Dict

Overview

jsify.Dict is the jsified wrapper for Python dictionaries, created by passing any dict (or dict-containing structure) to jsify().

Key features:

  • Dot-style attribute access for all keys (even deeply nested).

  • Bracket/item access: obj[‘key’] works as expected.

  • Most standard dict operations via helpers: see “Dict Methods” and Dict Functions for details.

  • Mutable and reference-based: changes are always reflected in the original data and vice versa, including all nested containers.

  • Safe chaining: missing attributes/keys always return Undefined, never raise KeyError or AttributeError.

  • Consistent interface: all nested dicts/lists are jsified recursively, changing their type and adding dot-access and chaining.

  • Iteration returns a :class:`jsify.Iterator` that supports Python and JavaScript-like iteration semantics.

Warning

Jsified Dict objects do not provide most standard dict methods as direct attributes (e.g., obj.items() or obj.copy() will not work). Instead, use the corresponding jsified_* helper functions. If a key matches a dict method name (e.g., "items", "get"), the key always takes priority and the method is unavailable by attribute. For native type methods, use unjsify(obj) to obtain a standard dict.

Creating a Jsified Dict

from jsify import jsify

d = {"a": 1, "b": {"c": 2}, "arr": [1, 2]}
obj = jsify(d)

print(type(obj))       # <class 'jsify.Dict'>
print(type(obj.b))     # <class 'jsify.Dict'>
print(type(obj.arr))   # <class 'jsify.List'>

Note

All nested dicts and lists will be jsified recursively. Their type and interface change to support dot/item access, safe chaining, and JavaScript-like behaviors. Use unjsify(obj) if you need a raw Python dict or list.

Accessing Elements

  • Use dot access: obj.a

  • Use item (bracket) access: obj["a"]

  • Both work at any depth; all nested dicts/lists are jsified

print(obj.a)          # 1
print(obj["a"])       # 1
print(obj.b.c)        # 2
print(obj["b"]["c"])  # 2

# Lists inside dicts are jsified:
print(obj.arr[1])     # 2
print(type(obj.arr))  # <class 'jsify.List'>

# Safe for missing keys/attributes (never raises):
print(obj.nope)       # Undefined
print(obj["nope"])    # Undefined

Important

Dot-style attribute access never raises for missing keys—missing attributes always return Undefined. This enables safe chaining, e.g., obj.not_here.foo.bar is valid and always returns Undefined.

If a dict key matches a Python dict method name (e.g., "items", "get", etc.), dot-access returns the key’s value, not the method. Dict methods are not available as attributes if shadowed.

Iteration

  • Iterating over a jsify.Dict returns a jsify.Iterator.

  • The iterator supports Python and JavaScript-like iteration semantics.

it = iter(obj)
print(type(it))  # <class 'jsify.Iterator'>

for key in it:
    print(key)

Standard Dict Methods

jsify.Dict supports most standard Python dict operations via helper functions in the jsify package. Classic methods like items(), keys(), values(), etc. are not available directly on jsified objects—use helpers:

  • jsified_items(obj) – Returns a jsified list of (key, value) pairs

  • jsified_keys(obj) – Returns a jsified list of keys

  • jsified_values(obj) – Returns a jsified list of values

  • jsified_update(obj, other) – Updates the dict in place

  • jsified_get(obj, key, default=None) – Safe get with default

  • jsified_setdefault(obj, key, default) – Set default value if missing

  • jsified_pop(obj, key[, default]) – Pop a key

  • jsified_popitem(obj) – Remove and return a (key, value) pair

See Dict Functions for all available helpers and full documentation.

from jsify import (
    jsified_items, jsified_keys, jsified_values,
    jsified_update, jsified_get, jsified_setdefault,
    jsified_pop, jsified_popitem
)

obj = jsify({"x": 1, "y": 2})

print(list(jsified_keys(obj)))    # ['x', 'y']
print(list(jsified_values(obj)))  # [1, 2]
print(list(jsified_items(obj)))   # [('x', 1), ('y', 2)]

jsified_update(obj, {"z": 3})
print(obj.z)     # 3

print(jsified_get(obj, "x"))     # 1
jsified_pop(obj, "x")
print(obj.x)     # Undefined

jsified_setdefault(obj, "w", 99)
print(obj.w)     # 99

k, v = jsified_popitem(obj)
print(f"Removed: {k}={v}")

Reference Behavior

  • All changes to the jsified dict and its nested elements are reflected in the original Python dict, and vice versa.

  • Mutations are always reference-based: editing any nested dict/list structure via a jsified object mutates the original.

  • Assigning a jsified object as a value in a dict keeps it jsified (see deep unjsify in jsify / unjsify if you want to convert back to native types everywhere).

Limitations and Gotchas

  • All mutation operations (assignment, pop, update, etc.) directly affect the original data, recursively for all contained structures.

  • When unjsifying, only the top-level dict becomes native unless you use unjsify_deepcopy (see jsify / unjsify).

  • Classic dict methods (such as copy, clear, fromkeys, etc.) are not available as direct methods. Use provided helper functions for supported operations, or unjsify to access native methods.

  • Type checks with isinstance(obj, dict) or type(obj) is dict will not work—jsified objects are not standard dicts/lists/tuples. Use unjsify(obj) for such checks.

  • If your keys clash with dict method names (e.g., obj.items), the key always takes priority; use the helper function for the classic method.

See Also

  • Dict Functions for full documentation of dict utilities and helpers

  • List for jsified lists

  • Tuple for jsified tuples

  • jsify / unjsify for conversion, reference rules, and copying

  • jsify.Iterator for iterators returned by dicts and other containers