Source code for coalib.bearlib.aspects.meta
from inspect import getmembers, signature
from coala_utils.decorators import generate_repr
from .base import aspectbase
from .docs import Documentation
from .taste import Taste
[docs]class aspectclass(type):
"""
Metaclass for aspectclasses.
Root aspectclass is :class:`coalib.bearlib.aspectclasses.Root`.
"""
def __init__(cls, clsname, bases, clsattrs):
"""
Initializes the ``.subaspects`` dict on new aspectclasses.
"""
cls.subaspects = {}
@property
def tastes(cls):
"""
Get a dictionary of all taste names mapped to their
:class:`coalib.bearlib.aspectclasses.Taste` instances.
"""
if cls.parent:
return dict(cls.parent.tastes, **cls._tastes)
return dict(cls._tastes)
[docs] def subaspect(cls, subcls):
"""
The sub-aspectclass decorator.
See :class:`coalib.bearlib.aspectclasses.Root` for description
and usage.
"""
aspectname = subcls.__name__
docs = getattr(subcls, 'docs', None)
aspectdocs = Documentation(subcls.__doc__, **{
attr: getattr(docs, attr, '') for attr in
list(signature(Documentation).parameters.keys())[1:]})
# search for tastes int the sub-aspectclass
subtastes = {}
for name, member in getmembers(subcls):
if isinstance(member, Taste):
# tell the taste its own name
member.name = name
subtastes[name] = member
class Sub(subcls, aspectbase, metaclass=aspectclass):
__module__ = subcls.__module__
parent = cls
docs = aspectdocs
_tastes = subtastes
members = sorted(Sub.tastes)
if members:
Sub = generate_repr(*members)(Sub)
Sub.__name__ = aspectname
Sub.__qualname__ = '%s.%s' % (cls.__qualname__, aspectname)
cls.subaspects[aspectname] = Sub
setattr(cls, aspectname, Sub)
return Sub
def __repr__(cls):
return '<%s %s>' % (type(cls).__name__, repr(cls.__qualname__))