arcticfreeze
Note: This is a fork of KerstenBreuer/arcticfreeze maintained by the German Human Genome-Phenome Archive (GHGA). It was created to bring in fixes and updates required by GHGA-related projects. Many thanks to Kersten Breuer for the initial implementation. The distribution is published as
ghga-arcticfreeze, but the import path remainsarcticfreeze, so it is a drop-in replacement for the upstream package.
Enjoy Python on the rocks with deeply (recursively) frozen data structures.
Description
Python's built-in immutable types only go one level deep: a tuple may still contain a
list, and a frozenset cannot contain a dict at all. arcticfreeze closes that
gap by recursively converting a nested data structure into an immutable counterpart.
It provides:
freeze– a function that deep freezes an arbitrary object. It walks the object tree bottom-up and replaces every mutable container with an immutable equivalent (list/deque→tuple,dict→FrozenDict,set→frozenset), leaving already-immutable values untouched.FrozenDict– a hashable, immutableMapping(built on immutabledict) with first-class type-hint support and out-of-the-box Pydantic v2 integration (validation, JSON schema, and serialization).Converter– an extension point for teachingfreezehow to handle your own types, including a priority mechanism to override the standard converters.
Freezing is useful wherever shared data must not be mutated by accident: configuration objects, cached values, dictionary keys, or any value that should be hashable and safe to pass around.
Installation
Requirements
- Python 3.11+
Install from PyPI
pip install ghga-arcticfreeze
To use the FrozenDict type within Pydantic models, install the optional pydantic
extra:
pip install "ghga-arcticfreeze[pydantic]"
Usage
Deep freezing
from arcticfreeze import FrozenDict, freeze
original = {"a": [1, 2, {"b": {"c", "d"}}]}
frozen = freeze(original)
# The nested list became a tuple, the nested dicts became FrozenDicts,
# and the nested set became a frozenset:
assert frozen == FrozenDict({"a": (1, 2, FrozenDict({"b": frozenset({"c", "d"})}))})
# The result is hashable and cannot be modified:
hash(frozen)
Custom types are supported by providing additional converters:
from arcticfreeze import Converter, freeze
class Point:
def __init__(self, x: int, y: int):
self.x = x
self.y = y
point_converter = Converter(
input_type=Point,
convert=lambda obj, freeze_child: (freeze_child(obj.x), freeze_child(obj.y)),
)
assert freeze(Point(1, 2), add_converters=[point_converter]) == (1, 2)
FrozenDict in Pydantic models
from arcticfreeze import FrozenDict
from pydantic import BaseModel
class Config(BaseModel):
parameters: FrozenDict[str, int]
config = Config(parameters={"a": 1})
# The mapping is validated and converted into a FrozenDict:
assert isinstance(config.parameters, FrozenDict)
# It serializes to a plain dict in JSON mode and stays a FrozenDict in Python mode:
assert config.model_dump(mode="json") == {"parameters": {"a": 1}}
assert isinstance(config.model_dump()["parameters"], FrozenDict)
Development
This package is a member of the GHGA monorepo and is
developed from the repository root rather than on its own. The repository ships a
devcontainer with the whole toolchain: open it in VS Code and run
Remote-Containers: Reopen in Container, or set the environment up directly with
just sync.
The usual tasks, run from the repository root (see ADR-0034 for the full recipe list):
just sync # install every member plus the shared dev toolchain
just test libs/ghga-arcticfreeze # this member's test suite
just lint # ruff check + format check across the workspace
License
This repository is free to use and modify according to the Apache 2.0 License.
Metadata
Release files for ghga-arcticfreeze 1.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ghga_arcticfreeze-1.1.2.tar.gz | 17.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ghga_arcticfreeze-1.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 36.5 kB
Release files / ghga_arcticfreeze-1.1.2.tar.gz
| Download URL | ghga_arcticfreeze-1.1.2.tar.gz |
|---|---|
| Size | 17.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
734d5dbd3639d9848c81a345d12ca6253e0123c9f15cba244912f8450bcca248
|
|
BLAKE2b-256 checksum How to use checksums |
661f44205a50557c4d3fa2cf4e3a124a6b7898f60f7f5bf4618cc0d9f6382a3d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.21 {"installer":{"name":"uv","version":"0.12.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / ghga_arcticfreeze-1.1.2-py3-none-any.whl
| Download URL | ghga_arcticfreeze-1.1.2-py3-none-any.whl |
|---|---|
| Size | 19.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
84c03422b2bb13d6fdd5489c9fa9e79920dac0cde30c25c10e3fc8dd1715463f
|
|
BLAKE2b-256 checksum How to use checksums |
8bd216a223b249b8460b7ad1e034e50626b87ebd316410240852239a8f1e3d2c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.21 {"installer":{"name":"uv","version":"0.12.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|