def latestClass(oldClass): """ Get the latest version of a class. """ module = reflect.namedModule(oldClass.__module__) newClass = getattr(module, oldClass.__name__) newBases = [latestClass(base) for base in newClass.__bases__] try: # This makes old-style stuff work newClass.__bases__ = tuple(newBases) return newClass except TypeError: if newClass.__module__ == "__builtin__": # __builtin__ members can't be reloaded sanely return newClass ctor = getattr(newClass, '__metaclass__', type) return ctor(newClass.__name__, tuple(newBases), dict(newClass.__dict__))
def unjellyAO(self, ao): """Unjelly an Abstract Object and everything it contains. I return the real object. """ self.stack.append(ao) t = type(ao) if t is types.InstanceType: #Abstract Objects c = ao.__class__ if c is Module: return reflect.namedModule(ao.name) elif c in [Class, Function] or issubclass(c, type): return reflect.namedObject(ao.name) elif c is InstanceMethod: im_name = ao.name im_class = reflect.namedObject(ao.klass) im_self = self.unjellyAO(ao.instance) if im_name in im_class.__dict__: if im_self is None: return getattr(im_class, im_name) elif isinstance(im_self, crefutil.NotKnown): return crefutil._InstanceMethod( im_name, im_self, im_class) else: return new.instancemethod(im_class.__dict__[im_name], im_self, im_class) else: raise TypeError("instance method changed") elif c is Instance: klass = reflect.namedObject(ao.klass) state = self.unjellyAO(ao.state) if hasattr(klass, "__setstate__"): inst = new.instance(klass, {}) self.callAfter(inst.__setstate__, state) else: inst = new.instance(klass, state) return inst elif c is Ref: o = self.unjellyAO(ao.obj) #THIS IS CHANGING THE REF OMG refkey = ao.refnum ref = self.references.get(refkey) if ref is None: self.references[refkey] = o elif isinstance(ref, crefutil.NotKnown): ref.resolveDependants(o) self.references[refkey] = o elif refkey is None: # This happens when you're unjellying from an AOT not read from source pass else: raise ValueError( "Multiple references with the same ID: %s, %s, %s!" % (ref, refkey, ao)) return o elif c is Deref: num = ao.refnum ref = self.references.get(num) if ref is None: der = crefutil._Dereference(num) self.references[num] = der return der return ref elif c is Copyreg: loadfunc = reflect.namedObject(ao.loadfunc) d = self.unjellyLater(ao.state).addCallback( lambda result, _l: apply(_l, result), loadfunc) return d #Types elif t in _SIMPLE_BUILTINS: return ao elif t is types.ListType: l = [] for x in ao: l.append(None) self.unjellyInto(l, len(l) - 1, x) return l elif t is types.TupleType: l = [] tuple_ = tuple for x in ao: l.append(None) if isinstance(self.unjellyInto(l, len(l) - 1, x), crefutil.NotKnown): tuple_ = crefutil._Tuple return tuple_(l) elif t is types.DictType: d = {} for k, v in ao.items(): kvd = crefutil._DictKeyAndValue(d) self.unjellyInto(kvd, 0, k) self.unjellyInto(kvd, 1, v) return d else: raise TypeError("Unsupported AOT type: %s" % t) del self.stack[-1]
def unjellyAO(self, ao): """Unjelly an Abstract Object and everything it contains. I return the real object. """ self.stack.append(ao) t = type(ao) if t is types.InstanceType: #Abstract Objects c = ao.__class__ if c is Module: return reflect.namedModule(ao.name) elif c in [Class, Function] or issubclass(c, type): return reflect.namedObject(ao.name) elif c is InstanceMethod: im_name = ao.name im_class = reflect.namedObject(ao.klass) im_self = self.unjellyAO(ao.instance) if im_name in im_class.__dict__: if im_self is None: return getattr(im_class, im_name) elif isinstance(im_self, crefutil.NotKnown): return crefutil._InstanceMethod(im_name, im_self, im_class) else: return new.instancemethod(im_class.__dict__[im_name], im_self, im_class) else: raise TypeError("instance method changed") elif c is Instance: klass = reflect.namedObject(ao.klass) state = self.unjellyAO(ao.state) if hasattr(klass, "__setstate__"): inst = new.instance(klass, {}) self.callAfter(inst.__setstate__, state) else: inst = new.instance(klass, state) return inst elif c is Ref: o = self.unjellyAO(ao.obj) #THIS IS CHANGING THE REF OMG refkey = ao.refnum ref = self.references.get(refkey) if ref is None: self.references[refkey] = o elif isinstance(ref, crefutil.NotKnown): ref.resolveDependants(o) self.references[refkey] = o elif refkey is None: # This happens when you're unjellying from an AOT not read from source pass else: raise ValueError("Multiple references with the same ID: %s, %s, %s!" % (ref, refkey, ao)) return o elif c is Deref: num = ao.refnum ref = self.references.get(num) if ref is None: der = crefutil._Dereference(num) self.references[num] = der return der return ref elif c is Copyreg: loadfunc = reflect.namedObject(ao.loadfunc) d = self.unjellyLater(ao.state).addCallback( lambda result, _l: apply(_l, result), loadfunc) return d #Types elif t in _SIMPLE_BUILTINS: return ao elif t is types.ListType: l = [] for x in ao: l.append(None) self.unjellyInto(l, len(l)-1, x) return l elif t is types.TupleType: l = [] tuple_ = tuple for x in ao: l.append(None) if isinstance(self.unjellyInto(l, len(l)-1, x), crefutil.NotKnown): tuple_ = crefutil._Tuple return tuple_(l) elif t is types.DictType: d = {} for k,v in ao.items(): kvd = crefutil._DictKeyAndValue(d) self.unjellyInto(kvd, 0, k) self.unjellyInto(kvd, 1, v) return d else: raise TypeError("Unsupported AOT type: %s" % t) del self.stack[-1]