xoutil.eight.mixins - functions to create helper classes and mixins

Two functions to create helper classes and mixins.

This module is in the eight context because these two functions depend on several concepts that are different in Python 2 and 3.

  • helper_class() creates a base class that represent a meta-class. For example (only for Python 3), xoutil.eight.abc.ABC is different to abc.ABC:

    >>> from xoutil.eight.abc import ABC, ABCMeta
    >>> class One(ABC):
    ...     pass
    >>> One.__bases__ == (ABC, )
    False
    >>> One.__bases__ == (Mixin, )
    True
    
    >>> from abc import ABC
    >>> class Two(ABC):
    ...     pass
    >>> Two.__bases__ == (ABC, )
    True
    >>> Two.__bases__ == (Mixin, )
    False
    
  • mixin() create a base-class tha consolidate several mix-ins and meta-classes. For example:

    >>> from xoutil.eight.abc import ABCMeta
    
    >>> class One(dict):
    ...     pass
    
    >>> class Two:
    ...     pass
    
    >>> class OneMeta(type):
    ...     pass
    
    >>> class TwoMeta(type):
    ...     pass
    
    >>> Test = mixin(One, Two, meta=[OneMeta, TwoMeta, ABCMeta], name='Test')
    >>> Test.__name__ == 'Test'
    True
    >>> isinstance(Test, ABCMeta)
    True
    

These modules (this one and meta) must have four utilities:

  • metaclass to use a unique syntax to declare meta-classes between Python 2 and 3.

  • helper_class to build a class that when used as a base impose a meta-class and not is found in resulting bases of defined class. For example xoutil.eight.abc.ABC.

  • mixin build a mixin-base composing several parts and meta-classes.

  • compose specify the use of a mixin as one of the bases, but the new defined class will not be a mixin, this is not implemented yet because will require a big architecture re-factoring; for example:

    class Foobar(MyBase, compose(MyMixin)):
        pass
    

Maybe the last two names must be interchanged.

xoutil.eight.mixins.helper_class(meta, name=None, meta_doc=False)[source]

Create a helper class based in the meta-class concept.

Parameters:
  • meta – The meta-class type to base returned helper-class on it.
  • name – The name (__name__) to assign to the returned class; if None is given, a nice name is calculated.
  • meta_doc – Append meta documentation.

For example:

>>> from abc import ABCMeta
>>> ABC = helper_class(ABCMeta)    # better than Python 3's abc.ABC :(
>>> class MyError(Exception, ABC):
...     pass
>>> (MyError.__bases__ == (Exception,), hasattr(MyError, 'register'))
(True, True)

This function calls metaclass() internally. So, in the example anterior, MyError declaration is equivalent to:

>>> class MyError(Exception, metaclass(ABCMeta)):
...     pass

New in version 1.9.7: Add parameter ‘meta_doc’.

xoutil.eight.mixins.mixin(*args, **kwargs)[source]

Weave a mixin.

Parameters of this function are a little tricky.

Parameters:
  • name – The name of the new class created by this function. Could be passed as positional or keyword argument. Use __name__ as an alias. See helper_class() for more info about this parameter and next two.
  • doc – Documentation of the returned mixin-class. Could be passed as positional or keyword argument. Use __doc__ as an alias.
  • module – Always given as a keyword parameter. A string -or an object to be used as reference- representing the module name. Use __module__ as an alias.
  • metaclass – Always given as a keyword parameter. Could be one type value or a list of values (multiples meta-classes). Use (__metaclass__, metaclasses, or meta) as aliases.

If several mixins with the same base are used all-together in a class inheritance, Python generates TypeError: multiple bases have instance lay-out conflict. To avoid that, inherit from the class this function returns instead of desired base.