From ncoghlan at gmail.com Wed Aug 5 13:29:44 2015 From: ncoghlan at gmail.com (Nick Coghlan) Date: Wed, 5 Aug 2015 21:29:44 +1000 Subject: [Import-SIG] On singleton modules, heap types, and subinterpreters In-Reply-To: References: Message-ID: On 30 July 2015 at 18:13, Petr Viktorin wrote: > On Thu, Jul 30, 2015 at 5:30 AM, Nick Coghlan wrote: >> That way, we could walk the type hierarchy to find the defining class >> on first look up, and then cache it on the derived type when done. > > It sounds classes with index-based __typeslots__ would be incompatible > for multiple inheritance. __slots__ already mess with multiple inheritance, so having __typeslots__ also mess with that wouldn't be a new limitation. However, I figured out a worse problem with the idea - it doesn't actually solve the problem we're trying to solve, which is that we ideally want this messy scenario to "do the right thing" even after being Cythonised: base.py: class Example: def __str__(self): return "Example str from {}.format(__name__) derived.py: import base class Example(base.Example): def __repr__(self): return "Example repr from {}.format(__name__) def __str__(self): return super().__str__() assert repr(Example()) == "Example repr from derived" assert str(Example()) == "Example str from base" On the other hand, zero-argument super, which is essentially the same problem we have here when it comes to walking the MRO from the right starting point, only at the Python level, may point us towards a possible solution: conceiving of this problem in terms of closures and cell dereferencing, with the cell reference stored on the method implementations themselves, rather than accessing it indirectly through the type object. Under that model, we'd be back to my "wrapped slot" idea, but rather than using an active module stack, we'd instead add a "PyObject *defclass" parameter to the signature of the *implementation* for wrapped slots, and implement the method wrapper at type definition time as a closure that references the defining __class__. Cython presumably needs a capability along these lines to handle zero-argument super reliably anyway. Such methods would take a slight speed hit from always having to dereference the cell at method call time, but if we combined this with the __typeslots__ idea, they'd also gain a type-definition-scoped fast access storage area. Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia