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 ajsify.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) pairsjsified_keys(obj)
– Returns a jsified list of keysjsified_values(obj)
– Returns a jsified list of valuesjsified_update(obj, other)
– Updates the dict in placejsified_get(obj, key, default=None)
– Safe get with defaultjsified_setdefault(obj, key, default)
– Set default value if missingjsified_pop(obj, key[, default])
– Pop a keyjsified_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)
ortype(obj) is dict
will not work—jsified objects are not standard dicts/lists/tuples. Useunjsify(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