def pickle_instance(obj, list, level=0, deepcopy=0): """Pickle the given object into a <PyObject> Add XML tags to list. Level is indentation (for aesthetic reasons) """ # concept: to pickle an object, we pickle two things: # # 1. the object attributes (the "stuff") # 2. initargs, if defined # # There is a twist to this -- instead of always putting the "stuff" # into a container, we can make the elements of "stuff" first-level attributes, # which gives a more natural-looking XML representation of the object. # # We only put the "stuff" into a container if we'll need to pass it # later as an object to __setstate__. # tests below are in same order as pickle.py, in case someone depends on that. # note we save the special __getstate__ and __getinitargs__ objects in containers # of the same name -- we know for sure that the object can't also have # data attributes of that same name # first, get the initargs, if present try: args = obj.__getinitargs__() try: len(args) # must be a sequence, from pickle.py except: raise XMLPicklingError, \ "__getinitargs__() must return a sequence" except: args = None # next, decide what the "stuff" is try: stuff = obj.__getstate__() except: #stuff = obj.__dict__ stuff = attr_dict(obj) # save initargs, if we have them if args is not None: # put them in an <attr name="__getinitargs__" ...> container list.append(_attr_tag('__getinitargs__', args, level, deepcopy)) # decide how to save the "stuff", depending on whether we need # to later grab it back as a single object if not hasattr(obj, '__setstate__'): if type(stuff) is DictType: # don't need it as a single object - save keys/vals as # first-level attributes for key, val in stuff.items(): list.append(_attr_tag(key, val, level, deepcopy)) else: raise XMLPicklingError, \ "__getstate__ must return a DictType here" else: # else, encapsulate the "stuff" in an <attr name="__getstate__" ...> list.append(_attr_tag('__getstate__', stuff, level, deepcopy))
def pickle_instance(obj, list, level=0, deepcopy=0): """Pickle the given object into a <PyObject> Add XML tags to list. Level is indentation (for aesthetic reasons) """ # concept: to pickle an object, we pickle two things: # # 1. the object attributes (the "stuff") # 2. initargs, if defined # # There is a twist to this -- instead of always putting the "stuff" # into a container, we can make the elements of "stuff" first-level attributes, # which gives a more natural-looking XML representation of the object. # # We only put the "stuff" into a container if we'll need to pass it # later as an object to __setstate__. # tests below are in same order as pickle.py, in case someone depends on that. # note we save the special __getstate__ and __getinitargs__ objects in containers # of the same name -- we know for sure that the object can't also have # data attributes of that same name # first, get the initargs, if present try: args = obj.__getinitargs__() try: len(args) # must be a sequence, from pickle.py except: raise XMLPicklingError, \ "__getinitargs__() must return a sequence" except: args = None # next, decide what the "stuff" is try: stuff = obj.__getstate__() except: #stuff = obj.__dict__ stuff = attr_dict(obj) # save initargs, if we have them if args is not None: # put them in an <attr name="__getinitargs__" ...> container list.append(_attr_tag('__getinitargs__', args, level, deepcopy)) # decide how to save the "stuff", depending on whether we need # to later grab it back as a single object if not hasattr(obj,'__setstate__'): if type(stuff) is DictType: # don't need it as a single object - save keys/vals as # first-level attributes for key,val in stuff.items(): list.append(_attr_tag(key, val, level, deepcopy)) else: raise XMLPicklingError, \ "__getstate__ must return a DictType here" else: # else, encapsulate the "stuff" in an <attr name="__getstate__" ...> list.append(_attr_tag('__getstate__', stuff, level, deepcopy))