Source code for sugar.core.meta
# (C) 2024, Tom Eulenfeld, MIT license
"""
Metadata related classes, `.Attr` and `.Meta`
"""
import collections.abc
import copy
[docs]
class Attr(collections.abc.MutableMapping):
"""
A class which behaves like a dictionary.
:param dict data: Dictionary with initial keywords.
.. rubric:: Basic Usage
You can use the following syntax to modify or access data in this class.
>>> attr = Attr()
>>> attr.comment = 'bla'
>>> attr['another_comment'] = 'yeah'
>>> print(attr.get('comment'))
bla
>>> print(attr['comment'])
bla
>>> print(attr.comment)
bla
"""
def __init__(self, *args, **kwargs):
"""
An Attr object can be initialized in two ways. It can be given an
existing dictionary as a simple argument or alternatively all keyword
arguments will become (key, value) pairs.
>>> attr1 = Attr({'a':1, 'b':2})
>>> attr2 = Attr(a=1, b=2)
"""
self.update(dict(*args, **kwargs))
def __repr__(self):
items = (f'{k}={v!r}' for k, v in self.__dict__.items())
return '{}({})'.format(type(self).__name__, ', '.join(items))
def __getitem__(self, key):
return self.__dict__[key]
def __setitem__(self, key, value):
if (isinstance(value, collections.abc.Mapping) and not
isinstance(value, Attr)):
self.__dict__[key] = Attr(value)
else:
self.__dict__[key] = value
def __delitem__(self, name):
del self.__dict__[name]
def __getattr__(self, name):
try:
return self.__getitem__(name)
except KeyError as e:
raise AttributeError(e.args[0])
__setattr__ = __setitem__
__delattr__ = __delitem__
[docs]
def copy(self):
"""Return a deep copy of the object"""
return copy.deepcopy(self)
[docs]
def update(self, adict={}):
"""Update from other mapping or iterable"""
for (key, value) in adict.items():
self.__setitem__(key, value)
def __iter__(self):
return iter(self.__dict__)
def __len__(self):
return len(self.__dict__)
[docs]
def setdefault(self, k, *args):
"""
Like `setdefault() <python:dict.setdefault>`, but creates a new Attr instance when no value is present and no default is set
.. rubric:: Example:
>>> seqs = read()
>>> seqs[0].meta.setdefault('_stockholm').setdefault('GR').mykey = 'value'
>>> print(seqs[0].meta._stockholm)
Attr(GR=Attr(mykey='value'))
"""
if len(args) > 1:
raise ValueError('Too many arguments for')
v = {} if len(args) == 0 else args[0]
super().setdefault(k, v)
return self[k]