brief-extractor/backend/venv/lib/python3.10/site-packages/dirtyjson/attributed_containers.py
2026-03-06 18:42:46 +00:00

153 lines
4.3 KiB
Python
Executable file

"""Drop-in replacement for collections.AttributedDict by Raymond Hettinger
http://code.activestate.com/recipes/576693/
"""
try:
try:
from collections.abc import MutableMapping as DictMixin
except ImportError:
from collections import MutableMapping as DictMixin
py_level = 3
except ImportError:
# noinspection PyUnresolvedReferences,PyCompatibility
from UserDict import DictMixin
py_level = 2
# Modified from original to support Python 2.4, see
# http://code.google.com/p/dirtyjson/issues/detail?id=53
try:
# noinspection PyStatementEffect
all
except NameError:
# noinspection PyShadowingBuiltins
def all(seq):
for elem in seq:
if not elem:
return False
return True
class AttributedDict(dict, DictMixin):
def __init__(self):
super(AttributedDict, self).__init__()
self.__attributes = {}
self.clear()
# noinspection PyAttributeOutsideInit
def clear(self):
self.__end = end = []
end += [None, end, end] # sentinel node for doubly linked list
self.__map = {} # key --> [key, prev, next]
dict.clear(self)
def add_with_attributes(self, key, value, attributes):
self.__setitem__(key, value)
self.__attributes[key] = attributes
def attributes(self, key):
return self.__attributes.get(key)
def __setitem__(self, key, value):
if key not in self:
end = self.__end
curr = end[1]
curr[2] = end[1] = self.__map[key] = [key, curr, end]
dict.__setitem__(self, key, value)
def __delitem__(self, key):
dict.__delitem__(self, key)
key, prev, next_entry = self.__map.pop(key)
prev[2] = next_entry
next_entry[1] = prev
def __iter__(self):
end = self.__end
curr = end[2]
while curr is not end:
yield curr[0]
curr = curr[2]
def __reversed__(self):
end = self.__end
curr = end[1]
while curr is not end:
yield curr[0]
curr = curr[1]
def popitem(self, last=True):
if not self:
raise KeyError('dictionary is empty')
# Modified from original to support Python 2.4, see
# http://code.google.com/p/dirtyjson/issues/detail?id=53
if py_level == 2:
if last:
# noinspection PyUnresolvedReferences
key = reversed(self).next()
else:
# noinspection PyUnresolvedReferences
key = iter(self).next()
else:
if last:
key = next(reversed(self))
else:
key = next(iter(self))
value = self.pop(key)
return key, value
def __reduce__(self):
items = [[k, self[k]] for k in self]
tmp = self.__map, self.__end
del self.__map, self.__end
inst_dict = vars(self).copy()
self.__map, self.__end = tmp
if inst_dict:
return self.__class__, (items,), inst_dict
return self.__class__, (items,)
def keys(self):
return list(self)
setdefault = DictMixin.setdefault
update = DictMixin.update
pop = DictMixin.pop
values = DictMixin.values
items = DictMixin.items
def __repr__(self):
if not self:
return '%s()' % (self.__class__.__name__,)
return '%s(%s)' % (self.__class__.__name__, list(self.items()))
def copy(self):
return self.__class__(self)
# noinspection PyMethodOverriding
@classmethod
def fromkeys(cls, iterable, value=None):
d = cls()
for key in iterable:
d[key] = value
return d
def __eq__(self, other):
if isinstance(other, AttributedDict):
return len(self) == len(other) and all(
p == q for p, q in zip(sorted(self.items()), sorted(other.items())))
return dict.__eq__(self, other)
def __ne__(self, other):
return not self == other
class AttributedList(list):
def __init__(self):
super(AttributedList, self).__init__()
self.__attributes = []
def append(self, value, attributes=None):
super(AttributedList, self).append(value)
self.__attributes.append(attributes)
def attributes(self, index):
return self.__attributes[index]