def obj_from_node(node, paranoia=1): """Given a <PyObject> node, return an object of that type. __init__ is NOT called on the new object, since the caller may want to do some additional work first. """ classname = node.getAttribute('class') # allow <PyObject> nodes w/out module name # (possibly handwritten XML, XML containing "from-air" classes, # or classes placed in the CLASS_STORE) try: modname = node.getAttribute('module') except: modname = None # must exist in xml_pickle namespace, or thin-air return obj_from_name(classname, modname, paranoia)
def olddata_to_newdata(data, extra, paranoia): """Given raw data, the extra= tag, and paranoia setting, recreate the object that was passed to newdata_to_olddata.""" (module, klass) = extra.split() o = obj_from_name(klass, module, paranoia) #if isinstance(o,ComplexType) and \ # type(data) in [StringType,UnicodeType]: # # yuck ... have to strip () from complex data before # # passing to __init__ (ran into this also in one of the # # parsers ... maybe the () shouldn't be in the XML at all?) # if data[0] == '(' and data[-1] == ')': # data = data[1:-1] if isinstance_any(o,(IntType,FloatType,ComplexType,LongType)) and \ type(data) in [StringType,UnicodeType]: data = aton(data) o = setCoreData(o, data) return o
def olddata_to_newdata(data,extra,paranoia): """Given raw data, the extra= tag, and paranoia setting, recreate the object that was passed to newdata_to_olddata.""" (module,klass) = extra.split() o = obj_from_name(klass,module,paranoia) #if isinstance(o,ComplexType) and \ # type(data) in [StringType,UnicodeType]: # # yuck ... have to strip () from complex data before # # passing to __init__ (ran into this also in one of the # # parsers ... maybe the () shouldn't be in the XML at all?) # if data[0] == '(' and data[-1] == ')': # data = data[1:-1] if isinstance_any(o,(IntType,FloatType,ComplexType,LongType)) and \ type(data) in [StringType,UnicodeType]: data = aton(data) o = setCoreData(o,data) return o
def startElement(self, name, attrs): dbg("** START ELEM %s,%s" % (name, attrs._attrs)) # push on elem_stk as tuple: # (name,family,type,attr_name,attrs,[container]?) # name = attr/item/key/val/etc. # family = normalized family name # type = list/dict/string/etc. # attr_name = attribute name=, or none # attrs = dict of all tag attributes # container = for container types, the empty container to # be filled node_type = attrs._attrs.get('type') # determine object family family = attrs._attrs.get('family') if node_type is None and name == 'PyObject': # <PyObject> doesn't have a "type=" if not mutated family = 'obj' elif name == 'entry': # entries don't need family= family = '' else: family = _dom._fix_family(family, node_type) if not attrs._attrs.get('refid'): # we don't set a container for <entry> -- also see below if family == 'seq': container = [] elif family == 'map': container = {} elif family == 'obj' or name == 'PyObject': container = obj_from_name(attrs._attrs.get('class'), attrs._attrs.get('module', None), self.paranoia) else: container = None else: # don't want container for refs container = None elem = (name, family, node_type, attrs._attrs.get('name'), attrs._attrs, container) if container is not None: # have to save ref to container before we start grabbing subitems, # in case the subitems reference the container. self.save_obj_id(container, elem) self.elem_stk.append(elem) # for each "container" type, we place a STOP token # on the val_stk we'll know exactly where the elements # begin and end -- maybe there's a way to avoid this, # but this keeps things simple (otherwise, given for example # (1,(2,3,4),(5,6)), you get a string of <items> and # it's hard to tell which belongs where) # # (don't need a STOP token for <entry>, since it always # holds a single key/value pair) if container is not None: if not attrs._attrs.get('refid'): self.val_stk.append(("STOP", )) # reset content self.content = '' self.prstk()
def startElement(self,name,attrs): dbg("** START ELEM %s,%s"%(name,attrs._attrs)) # push on elem_stk as tuple: # (name,family,type,attr_name,attrs,[container]?) # name = attr/item/key/val/etc. # family = normalized family name # type = list/dict/string/etc. # attr_name = attribute name=, or none # attrs = dict of all tag attributes # container = for container types, the empty container to # be filled node_type = attrs._attrs.get('type') # determine object family family = attrs._attrs.get('family') if node_type is None and name == 'PyObject': # <PyObject> doesn't have a "type=" if not mutated family = 'obj' elif name == 'entry': # entries don't need family= family = '' else: family = _dom._fix_family(family,node_type) if not attrs._attrs.get('refid'): # we don't set a container for <entry> -- also see below if family == 'seq': container = [] elif family == 'map': container = {} elif family == 'obj' or name == 'PyObject': container = obj_from_name(attrs._attrs.get('class'), attrs._attrs.get('module',None), self.paranoia) else: container = None else: # don't want container for refs container = None elem = (name, family, node_type, attrs._attrs.get('name'), attrs._attrs, container) if container is not None: # have to save ref to container before we start grabbing subitems, # in case the subitems reference the container. self.save_obj_id(container,elem) self.elem_stk.append(elem) # for each "container" type, we place a STOP token # on the val_stk we'll know exactly where the elements # begin and end -- maybe there's a way to avoid this, # but this keeps things simple (otherwise, given for example # (1,(2,3,4),(5,6)), you get a string of <items> and # it's hard to tell which belongs where) # # (don't need a STOP token for <entry>, since it always # holds a single key/value pair) if container is not None: if not attrs._attrs.get('refid'): self.val_stk.append(("STOP",)) # reset content self.content = '' self.prstk()