1717
1818- recursive objects
1919- pointer sharing
20- - class instances
20+ - classes and class instances
2121
2222Pickle is Python-specific. This has the advantage that there are no
2323restrictions imposed by external standards such as CORBA (which probably
6262return a *tuple* containing the arguments to be passed to the class
6363constructor.
6464
65- Classes can influence how they are pickled -- if the class defines
65+ Classes can influence how their instances are pickled -- if the class defines
6666the method __getstate__, it is called and the return state is pickled
6767as the contents for the instance, and if the class defines the
6868method __setstate__, it is called with the unpickled state. (Note
108108- strings
109109- tuples, lists and dictionaries containing only picklable objects
110110- class instances whose __dict__ or __setstate__() is picklable
111+ - classes
111112
112113Attempts to pickle unpicklable objects will raise an exception
113114after having written an unspecified number of bytes to the file argument.
125126I have no answers. Garbage Collection may also become a problem here.)
126127"""
127128
128- __format_version__ = "1.0" # File format version
129- __version__ = "1.4" # Code version
129+ __version__ = "1.5" # Code version
130130
131131from types import *
132132import string
133133
134+ format_version = "1.1" # File format version we write
135+ compatible_formats = ["1.0" ] # Old format versions we can read
136+
134137PicklingError = "pickle.PicklingError"
135138
136139AtomicTypes = [NoneType , IntType , FloatType , StringType ]
@@ -153,6 +156,7 @@ def safe(object):
153156LIST = 'l'
154157DICT = 'd'
155158INST = 'i'
159+ CLASS = 'c'
156160GET = 'g'
157161PUT = 'p'
158162APPEND = 'a'
@@ -300,8 +304,8 @@ def save_inst(self, object):
300304 self .write (MARK )
301305 for arg in args :
302306 self .save (arg )
303- self .write (INST + module + '\n ' + name + '\n ' +
304- PUT + `d` + '\n ' )
307+ self .write (INST + module + '\n ' + name + '\n ' +
308+ PUT + `d` + '\n ' )
305309 self .memo [d ] = object
306310 try :
307311 getstate = object .__getstate__
@@ -313,6 +317,14 @@ def save_inst(self, object):
313317 self .write (BUILD )
314318 dispatch [InstanceType ] = save_inst
315319
320+ def save_class (self , object ):
321+ d = id (object )
322+ module = whichmodule (object )
323+ name = object .__name__
324+ self .write (CLASS + module + '\n ' + name + '\n ' +
325+ PUT + `d` + '\n ' )
326+ dispatch [ClassType ] = save_class
327+
316328
317329classmap = {}
318330
@@ -410,25 +422,36 @@ def load_inst(self):
410422 del self .stack [k :]
411423 module = self .readline ()[:- 1 ]
412424 name = self .readline ()[:- 1 ]
425+ klass = self .find_class (module , name )
426+ value = apply (klass , args )
427+ self .stack .append (value )
428+ dispatch [INST ] = load_inst
429+
430+ def load_class (self ):
431+ module = self .readline ()[:- 1 ]
432+ name = self .readline ()[:- 1 ]
433+ klass = self .find_class (module , name )
434+ self .stack .append (klass )
435+ return klass
436+ dispatch [CLASS ] = load_class
437+
438+ def find_class (self , module , name ):
413439 env = {}
414440 try :
415441 exec 'from %s import %s' % (module , name ) in env
416442 except ImportError :
417443 raise SystemError , \
418444 "Failed to import class %s from module %s" % \
419445 (name , module )
420- else :
421- klass = env [name ]
422- if type (klass ) != ClassType :
423- raise SystemError , \
424- "imported object %s from module %s is not a class" % \
425- (name , module )
426- value = apply (klass , args )
427- self .stack .append (value )
428- dispatch [INST ] = load_inst
446+ klass = env [name ]
447+ if type (klass ) != ClassType :
448+ raise SystemError , \
449+ "Imported object %s from module %s is not a class" % \
450+ (name , module )
451+ return klass
429452
430453 def load_pop (self ):
431- del self .stack [- 1 ]
454+ del self .stack [- 1 ]
432455 dispatch [POP ] = load_pop
433456
434457 def load_dup (self ):
@@ -482,6 +505,28 @@ def load_stop(self):
482505 dispatch [STOP ] = load_stop
483506
484507
508+ # Shorthands
509+
510+ def dump (object , file ):
511+ Pickler (file ).dump (object )
512+
513+ def dumps (object ):
514+ import StringIO
515+ file = StringIO .StringIO ()
516+ Pickler (file ).dump (object )
517+ return file .getvalue ()
518+
519+ def load (file ):
520+ return Unpickler (file ).load ()
521+
522+ def loads (str ):
523+ import StringIO
524+ file = StringIO .StringIO (str )
525+ return Unpickler (file ).load ()
526+
527+
528+ # The rest is used for testing only
529+
485530class C :
486531 def __cmp__ (self , other ):
487532 return cmp (self .__dict__ , other .__dict__ )
0 commit comments