Consider the following Python (runs in 2.x or 3.x):
o = Outer()
i = o.Inner()
threading.local()["my o object"] = o
In Python 2.6, a class decorator that's also a custom descriptor matches the specs you give:
class InnerClassDescriptor(object): def __init__(self, cls): self.cls = cls def __get__(self, instance, outerclass): class Wrapper(self.cls): outer = instance Wrapper.__name__ = self.cls.__name__ return Wrapper class Outer(object): @InnerClassDescriptor class Inner(object): def __init__(self): print self.outer o = Outer() i = o.Inner() print 'Outer is a', type(Outer) print 'Inner is a', type(o.Inner)
<__main__.Outer object at 0x82f90> Outer is a <type 'type'> Inner is a <type 'type'>
just to confirm that
o.Inner [[is]] a class object, not something weird like a closure
as per your peculiar specs. Of course it needs to be a different class each time for reentrancy -- even in a single-threaded world, the following:
o1 = Outer() o2 = Outer() i1 = o1.Inner i2 = o2.Inner print i1(), i2(), i1(), i2()
should work cleanly, and stashing o1 vs o2 anywhere else than in the classes returned by
o2.Inner (e.g., in TLS) would mean horrible results for this use.
But then you didn't specify "
o.Inner has to be exactly the same class object for every possible
o that's an instance of
Outer", so this code fully meets the specs you did give;-).