def _unjelly_dereference(self, lst): refid = lst[0] x = self.references.get(refid) if x is not None: return x der = _Dereference(refid) self.references[refid] = der return der
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 unjellyNode(self, node): if node.tagName.lower() == "none": retval = None elif node.tagName == "string": # XXX FIXME this is obviously insecure # if you doubt: # >>> unjellyFromXML('''<string value="h"+str(__import__("sys"))+"i" />''') # "h<module 'sys' (built-in)>i" # XXX Freevo changes: # wrap this around 'Unicode()' retval = Unicode(str(eval('"%s"' % node.getAttribute("value")))) elif node.tagName == "int": retval = int(node.getAttribute("value")) elif node.tagName == "float": retval = float(node.getAttribute("value")) elif node.tagName == "longint": retval = long(node.getAttribute("value")) elif node.tagName == "bool": retval = int(node.getAttribute("value")) if retval: retval = True else: retval = False elif node.tagName == "module": retval = namedModule(str(node.getAttribute("name"))) elif node.tagName == "class": retval = namedClass(str(node.getAttribute("name"))) elif node.tagName == "unicode": retval = unicode(str(node.getAttribute("value")).replace("\\n", "\n").replace("\\t", "\t"), "raw_unicode_escape") elif node.tagName == "function": retval = namedObject(str(node.getAttribute("name"))) elif node.tagName == "method": im_name = node.getAttribute("name") im_class = namedClass(node.getAttribute("class")) im_self = self.unjellyNode(getValueElement(node)) if im_class.__dict__.has_key(im_name): if im_self is None: retval = getattr(im_class, im_name) elif isinstance(im_self, NotKnown): retval = _InstanceMethod(im_name, im_self, im_class) else: retval = instancemethod(im_class.__dict__[im_name], im_self, im_class) else: raise Exception("instance method changed") elif node.tagName == "tuple": l = [] tupFunc = tuple for subnode in node.childNodes: if isinstance(subnode, Element): l.append(None) if isinstance(self.unjellyInto(l, len(l)-1, subnode), NotKnown): tupFunc = _Tuple retval = tupFunc(l) elif node.tagName == "list": l = [] finished = 1 for subnode in node.childNodes: if isinstance(subnode, Element): l.append(None) self.unjellyInto(l, len(l)-1, subnode) retval = l elif node.tagName == "dictionary": d = {} keyMode = 1 for subnode in node.childNodes: if isinstance(subnode, Element): if keyMode: kvd = _DictKeyAndValue(d) if not subnode.getAttribute("role") == "key": raise Exception("Unjellying Error: key role not set") self.unjellyInto(kvd, 0, subnode) else: self.unjellyInto(kvd, 1, subnode) keyMode = not keyMode retval = d elif node.tagName == "instance": className = node.getAttribute("class") clasz = namedClass(className) if issubclass(clasz, DOMJellyable): retval = instance(clasz, {}) retval.unjellyFromDOM(self, node) else: state = self.unjellyNode(getValueElement(node)) if hasattr(clasz, "__setstate__"): inst = instance(clasz, {}) inst.__setstate__(state) else: inst = instance(clasz, state) retval = inst elif node.tagName == "reference": refkey = node.getAttribute("key") retval = self.references.get(refkey) if retval is None: der = _Dereference(refkey) self.references[refkey] = der retval = der elif node.tagName == "copyreg": nodefunc = namedObject(node.getAttribute("loadfunc")) loaddef = self.unjellyLater(getValueElement(node)).addCallback( lambda result, _l: apply(_l, result), nodefunc) retval = loaddef else: raise Exception("Unsupported Node Type: %s" % str(node.tagName)) if node.hasAttribute("reference"): refkey = node.getAttribute("reference") ref = self.references.get(refkey) if ref is None: self.references[refkey] = retval elif isinstance(ref, NotKnown): ref.resolveDependants(retval) self.references[refkey] = retval else: assert 0, "Multiple references with the same ID!" return retval
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 in _SIMPLE_BUILTINS: return ao elif t is list: l = [] for x in ao: l.append(None) self.unjellyInto(l, len(l)-1, x) return l elif t is tuple: 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 dict: d = {} for k,v in ao.items(): kvd = crefutil._DictKeyAndValue(d) self.unjellyInto(kvd, 0, k) self.unjellyInto(kvd, 1, v) return d else: #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 _constructMethod(im_class, im_name, im_self) else: raise TypeError("instance method changed") elif c is Instance: klass = reflect.namedObject(ao.klass) state = self.unjellyAO(ao.state) if hasattr(klass, "__new__"): inst = klass.__new__(klass) else: inst = _OldStyleInstance(klass) if hasattr(klass, "__setstate__"): self.callAfter(inst.__setstate__, state) else: inst.__dict__ = 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: _l(*result), loadfunc) return d else: raise TypeError("Unsupported AOT type: %s" % t) del self.stack[-1]
def unjellyNode(self, node): if node.tagName.lower() == "none": retval = None elif node.tagName == "string": # XXX FIXME this is obviously insecure # if you doubt: # >>> unjellyFromXML('''<string value="h"+str(__import__("sys"))+"i" />''') # "h<module 'sys' (built-in)>i" # XXX Freevo changes: # wrap this around 'Unicode()' retval = Unicode(str(eval('"%s"' % node.getAttribute("value")))) elif node.tagName == "int": retval = int(node.getAttribute("value")) elif node.tagName == "float": retval = float(node.getAttribute("value")) elif node.tagName == "longint": retval = long(node.getAttribute("value")) elif node.tagName == "bool": retval = int(node.getAttribute("value")) if retval: retval = True else: retval = False elif node.tagName == "module": retval = namedModule(str(node.getAttribute("name"))) elif node.tagName == "class": retval = namedClass(str(node.getAttribute("name"))) elif node.tagName == "unicode": retval = unicode( str(node.getAttribute("value")).replace("\\n", "\n").replace( "\\t", "\t"), "raw_unicode_escape") elif node.tagName == "function": retval = namedObject(str(node.getAttribute("name"))) elif node.tagName == "method": im_name = node.getAttribute("name") im_class = namedClass(node.getAttribute("class")) im_self = self.unjellyNode(getValueElement(node)) if im_class.__dict__.has_key(im_name): if im_self is None: retval = getattr(im_class, im_name) elif isinstance(im_self, NotKnown): retval = _InstanceMethod(im_name, im_self, im_class) else: retval = instancemethod(im_class.__dict__[im_name], im_self, im_class) else: raise "instance method changed" elif node.tagName == "tuple": l = [] tupFunc = tuple for subnode in node.childNodes: if isinstance(subnode, Element): l.append(None) if isinstance(self.unjellyInto(l, len(l) - 1, subnode), NotKnown): tupFunc = _Tuple retval = tupFunc(l) elif node.tagName == "list": l = [] finished = 1 for subnode in node.childNodes: if isinstance(subnode, Element): l.append(None) self.unjellyInto(l, len(l) - 1, subnode) retval = l elif node.tagName == "dictionary": d = {} keyMode = 1 for subnode in node.childNodes: if isinstance(subnode, Element): if keyMode: kvd = _DictKeyAndValue(d) if not subnode.getAttribute("role") == "key": raise "Unjellying Error: key role not set" self.unjellyInto(kvd, 0, subnode) else: self.unjellyInto(kvd, 1, subnode) keyMode = not keyMode retval = d elif node.tagName == "instance": className = node.getAttribute("class") clasz = namedClass(className) if issubclass(clasz, DOMJellyable): retval = instance(clasz, {}) retval.unjellyFromDOM(self, node) else: state = self.unjellyNode(getValueElement(node)) if hasattr(clasz, "__setstate__"): inst = instance(clasz, {}) inst.__setstate__(state) else: inst = instance(clasz, state) retval = inst elif node.tagName == "reference": refkey = node.getAttribute("key") retval = self.references.get(refkey) if retval is None: der = _Dereference(refkey) self.references[refkey] = der retval = der elif node.tagName == "copyreg": nodefunc = namedObject(node.getAttribute("loadfunc")) loaddef = self.unjellyLater(getValueElement(node)).addCallback( lambda result, _l: apply(_l, result), nodefunc) retval = loaddef else: raise "Unsupported Node Type: %s" % str(node.tagName) if node.hasAttribute("reference"): refkey = node.getAttribute("reference") ref = self.references.get(refkey) if ref is None: self.references[refkey] = retval elif isinstance(ref, NotKnown): ref.resolveDependants(retval) self.references[refkey] = retval else: assert 0, "Multiple references with the same ID!" return retval