[cctbxbb] boost python and metaclass inheritance

David Waterman dgwaterman at gmail.com
Wed Jan 8 05:37:46 PST 2014


Hi Luc,

Thanks for this. I thought that a limited use of python's own abc module
would be one of the safer uses of metaclasses. But apparently even this is
not without pain. My google-fu is slowly warming up this new year, and
eventually I did find a message (from Ralf) suggesting that a boost python
wrapper's __metaclass__ is its __class__, depending how it is constructed.
I still couldn't work out from that how to proceed though, so I'm happy to
put this aside. Your explicit alternative produces exactly the behaviour I
was after, in a more obvious way.

Cheers

-- David


On 8 January 2014 10:05, Luc Bourhis <luc_j_bourhis at mac.com> wrote:

> Hi David,
>
> I am afraid this is a dead end. Indeed
> scitbx.lstbx.normal_eqns.non_linear_ls is a Boost Python wrapper. What you
> could do instead is write:
>
> class Refinery(object):
>
>         def __new__(cls, *args, **kwds):
>                 assert cls.__bases__
>                 return object.__new__(cls)
>
> class AdaptLstbx(Refinery, normal_eqns.non_linear_ls):
>         pass
>
> It is then impossible to construct an instance of Refinery. Only heirs of
> Refinery can be instantiated. You could make the assert more subtle to suit
> your needs of course.
>
> Generally speaking, i.e. it would not apply to you, David, if you do not
> plan to commit metaclass-based code to the cctbx, I would strongly advise
> cctbx developers against using metaclasses at all. This is one of the
> surest way to make the code impossible to understand to your fellow
> programmers as it introduces highly implicit behaviour: explicit is better
> than implicit in the long run.
>
> As any rule, it has exceptions: there are 4 uses of metaclasses in the
> cctbx as I write this. But they are highly specialised and self-contained
> uses.
>
> Best wishes,
>
> Luc J. Bourhis
>
> > Hi,
> >
> > Does anyone know how to use __metaclass__ specification alongside
> inheritance from boost python classes? This code illustrates the problem:
> >
> > import abc
> > from scitbx.lstbx import normal_eqns
> >
> > class Refinery(object):
> >   __metaclass__ = abc.ABCMeta
> >   pass
> >
> > class AdaptLstbx(Refinery, normal_eqns.non_linear_ls):
> >   pass
> >
> > The result is
> >
> > Traceback (most recent call last):
> >   File "<stdin>", line 1, in <module>
> >   File "/usr/lib/python2.7/abc.py", line 87, in __new__
> >     cls = super(ABCMeta, mcls).__new__(mcls, name, bases, namespace)
> > TypeError: Error when calling the metaclass bases
> >     metaclass conflict: the metaclass of a derived class must be a
> (non-strict) subclass of the metaclasses of all its bases
> >
> > The real Refinery is a class that has one method that must be supplied
> by a concrete subclass. I like the idea of making it impossible to
> instantiate a base Refinery rather than relying on e.g. raise
> NotImplementedError() in that method definition. This is what ABCMeta would
> give me, if only I could get it to work here. Google found me some answers
> that require me to know the __metaclass__ of the bases (as suggested by the
> error message), but normal_eqns.non_linear_ls.__metaclass__ does not exist.
> >
> > I don't terribly mind the raise NotImplementedError() alternative, but I
> thought that if I can easily use ABCMeta, I'd like to.
> >
> > Cheers
> >
> > -- David
> > _______________________________________________
> > cctbxbb mailing list
> > cctbxbb at phenix-online.org
> > http://phenix-online.org/mailman/listinfo/cctbxbb
>
> _______________________________________________
> cctbxbb mailing list
> cctbxbb at phenix-online.org
> http://phenix-online.org/mailman/listinfo/cctbxbb
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://phenix-online.org/pipermail/cctbxbb/attachments/20140108/a7b41db4/attachment.htm>


More information about the cctbxbb mailing list