Source code for redditwarp.http.util.case_insensitive_dict


from __future__ import annotations
from typing import TypeVar, Mapping, MutableMapping, Iterator, IO, Optional, Any

from pprint import PrettyPrinter

V = TypeVar('V')

[docs]class CaseInsensitiveDict(MutableMapping[str, V]): """A case-folding, case-preserving dictionary. Entries are stored as if `str.casefold()` was called on the key. Iterators producing keys will contain case-sensitive keys since the casing of the last key supplied when setting is retained. However, as expected, lookups and membership checks are not case-sensitive, as are comparisons with other mappings. """ def __init__(self, data: Optional[Mapping[str, V]] = None, **kwargs: V) -> None: self._store: MutableMapping[str, tuple[str, V]] = {} if data is None: data = {} self.update(data, **kwargs) def __repr__(self) -> str: if self._store: return '%s(%r)' % (type(self).__name__, dict(self)) return type(self).__name__ + '()' def __contains__(self, item: object) -> bool: if not isinstance(item, str): return False return item.casefold() in self._store def __iter__(self) -> Iterator[str]: return (k for k, _ in self._store.values()) def __len__(self) -> int: return len(self._store) def __getitem__(self, key: str) -> V: return self._store[key.casefold()][1] def __setitem__(self, key: str, value: V) -> None: self._store[key.casefold()] = (key, value) def __delitem__(self, key: str) -> None: del self._store[key.casefold()] def __eq__(self, other: object) -> bool: if isinstance(other, Mapping): if not isinstance(other, self.__class__): other = CaseInsensitiveDict(other) return other.items() == self.items() return NotImplemented def __getstate__(self) -> Mapping[str, tuple[str, V]]: return self._store def __setstate__(self, state: Mapping[str, tuple[str, V]]) -> None: object.__setattr__(self, '_store', state) @staticmethod def _pprint( printer: PrettyPrinter, obj: Mapping[str, V], stream: IO[str], indent: int, allowance: int, context: Mapping[int, Any], level: int, ) -> None: cls_name = obj.__class__.__name__ stream.write(cls_name + '(') printer._format( # type: ignore[attr-defined] dict(obj), stream, indent + len(cls_name) + 1, allowance + 1, context, level, ) stream.write(')') if isinstance(getattr(PrettyPrinter, '_dispatch', None), dict): PrettyPrinter._dispatch[__repr__] = _pprint.__func__ # type: ignore[attr-defined]