bundlewrap/libs/hashable.py
CroneKorkN 730625e36c
libs/hooks/bin: add one-line module docstrings and # purpose: headers
every libs/*.py and hooks/*.py now starts with a one-line module
docstring; every bin/* script starts with a `# purpose:` header.
discovery-by-`ls`-and-read instead of by index.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 15:36:19 +02:00

40 lines
829 B
Python

"""hashable: dict/set subclasses with stable __hash__ via canonical JSON — lets you nest dicts/sets inside sets in metadata."""
import json
from functools import total_ordering
from bundlewrap.metadata import MetadataJSONEncoder
@total_ordering
class Hashable():
def _json(self):
return json.dumps(
self,
sort_keys=True,
cls=MetadataJSONEncoder,
)
def __lt__(self, other):
return self._json() < other._json()
def __eq__(self, other):
return self._json() == other._json()
def __hash__(self):
return hash(self._json())
class HashableDict(Hashable, dict):
pass
class HashableSet(Hashable, set):
pass
def hashable(object):
return {
dict: HashableDict,
set: HashableSet,
}[type(object)](object)