Source code for dpipe.dataset.base

from abc import ABCMeta
from functools import wraps
from typing import Tuple


class AbstractAttribute:
    def __init__(self, description: str):
        self.description = description

    def __repr__(self):
        return self.description


class ABCAttributesMeta(ABCMeta):
    def __new__(mcs, *args, **kwargs):
        cls = super().__new__(mcs, *args, **kwargs)
        initialize = cls.__init__

        @wraps(initialize)
        def __init__(self, *args_, **kwargs_):
            return_value = initialize(self, *args_, **kwargs_)

            # the check must be performed only after own __init__ is called
            if type(self) is cls:
                missing = []
                for name in dir(self):
                    value = getattr(self, name)
                    if isinstance(value, AbstractAttribute) or value is AbstractAttribute:
                        missing.append(name)
                if missing:
                    raise AttributeError(f'Class "{cls.__name__}" requires the following attributes '
                                         f'which are not defined during init: {", ".join(missing)}.')
            return return_value

        cls.__init__ = __init__
        return cls


[docs]class Dataset(metaclass=ABCAttributesMeta): """ Interface for datasets. Its subclasses must define the `ids` attribute - a tuple of identifiers, one for each dataset entry, as well as methods for loading an entry by its identifier. Attributes ---------- ids: a tuple of identifiers, one for each dataset entry. """ ids: Tuple[str] = AbstractAttribute