frozendict

An immutable, hashable dictionary type for Python with a C-accelerated core

Library
PyPI
v2.4.7
181stars
LGPL-3.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
52/100Fair
Development Activity16
Maintenance44
Community68
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
78/100Good
Architecture78
Code Quality74
Innovation68
Learning Curve92

frozendict fills a gap in Python’s builtin types: a dict-like object that is immutable and hashable, so it can be used as a dictionary key, stored in a set, or passed around without risk of accidental mutation. It implements the full Mapping interface (registered with collections.abc.Mapping) while rejecting any operation that would change its contents after construction.

The package ships a C extension built per-Python-version (from CPython’s own dict implementation, c_src/3_6 through newer versions) for near-native dict performance, and falls back transparently to a pure-Python implementation (_frozendict_py.py) when the C extension isn’t available for the running interpreter, so the same from frozendict import frozendict import works everywhere.

What You Get

  • An immutable frozendict class supporting all read-only dict operations (__getitem__, .get(), .keys(), .items(), iteration) while raising on any mutating call
  • Hashability, so frozendict instances can be used as dict keys or set members, unlike a regular dict
  • A C-accelerated implementation compiled per Python minor version against CPython’s dict source, with automatic fallback to a pure-Python implementation when the extension isn’t built
  • Registration with collections.abc.Mapping so isinstance() checks and duck-typing against Mapping work correctly
  • A FrozendictJsonEncoder helper for serializing frozendict values with the standard json module

Common Use Cases

  • Using a dict-shaped value as a dictionary key or set member, which a plain dict cannot do because it’s unhashable
  • Passing configuration or default-argument dictionaries into functions where accidental mutation by a caller or callee would cause bugs
  • Memoizing or caching function results keyed on dict-shaped arguments by first freezing them into a frozendict
  • Representing parsed JSON or config data as read-only structures throughout an application to enforce immutability at the boundary

Under The Hood

Architecture - The package presents a single public entrypoint (frozendict.frozendict) but backs it with two interchangeable implementations selected at import time: a C extension in src/frozendict/c_src/<python-version>/frozendictobject.c derived directly from CPython’s dictobject.c, and a pure-Python fallback in _frozendict_py.py; core.py exists only as a backward-compatible pickle-load shim for older serialized instances. Tech Stack - Primarily C (per-Python-version extension modules built against vendored copies of CPython’s Objects/dictobject.c and dict-common.h) with a pure-Python mirror implementation, built via a custom setup.py/build_py.sh/build.sh toolchain rather than a modern build backend. Code Quality - The C sources are maintained as near-verbatim forks of CPython internals per Python version (3.6 through newer), which keeps behavior faithful to native dict performance but means each new Python release requires porting the extension; the test suite (test/) covers both the C and pure-Python code paths, and py.typed plus a .pyi stub file are shipped for type checkers. API Design - The public API is intentionally a drop-in dict-like object (Mapping semantics, familiar methods) with immutability as the only behavioral difference, so there is close to zero learning curve for anyone already familiar with Python’s dict.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search