On 2 July 2016 at 14:59, Jonathan Underwood <[email protected]> wrote: > On 2 July 2016 at 14:54, Mike Bayer <[email protected]> wrote: >> >> >> On 07/02/2016 07:46 AM, Jonathan Underwood wrote: >>> >>> Hi, >>> >>> As documented, the default constructor for objects that inherit from >>> Base doesn't work in multiple inheritance situations (unless Base is >>> last in the list of classes, I suppose). It wouldn't be too difficult to >>> change this without breaking existing expectations, I believe. Something >>> like this: >>> >>> def _declarative_constructor(self, **kwargs): >>> """A simple constructor that allows initialization from kwargs. Sets >>> attributes on the constructed instance using the names and values >>> in ``kwargs``. >>> >>> Differs from the default constructor in that (a) keys not present >>> in the attributes of the instance's class are ignored; (b) we call >>> super at the end to ensure proper multiple inheritance behaviour. >>> >>> """ >>> cls_ = type(self) >>> unused_kwargs = dict() >>> for k in kwargs: >>> if hasattr(cls_, k): >>> setattr(self, k, kwargs[k]) >>> else: >>> unused_kwargs.update({k:kwargs[k]}) >>> >>> super(Base, self).__init__(**unused_kwargs) >> >> >> Well, all existing tests would have to pass, but also I wonder where are you >> getting "Base" above? It's not present and would have to be passed to an >> enclosing function that generates a _declarative_constructor as a closure. >> That would imply a change in the API of the declarative_base function, which >> accepts a constructor function as an argument, to now accept a >> constructor-generating function. > > Yes, I had this thought too, after sending the earlier email. Having > thought about it, I can't immediately see an easy way to establish the > name of the generated declarative_base class without the API change > you describe (which I assume you'd be opposed to). This is a shame, as > it would be nice not to break multiple inheritance, but I really can't > see a good general fix.
As an addenda, it's interesting to note that on python 3, a bare super() call would work in this situation (I think) and the problem is solved. So, this is actually a python 2 compatibility thing.. when the world has moved to python 3 we could revisit this. -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at https://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.
