I have just bumped into a totally bizarre error. I'm saving a selection of things into a single file. One of these is a version of a class called Tracker, and this copy is called tracker.
file = shelve.open(worldname, 'n')
file['Terramap'] = terramap
file['Satmap'] = satmap
file['Gasmap'] = gasmap
file['Planetset'] = planetset
file['World'] = minimap
file['Picture'] = picturemap
file['Worlddata'] = worlddata
file['Dimension'] = dimension
print "check", len(tracker.families)
file['Tracker'] = tracker
file['Schedule'] = schedule
file['Time'] = time
file.close()
If I have it print something from tracker JUST before the file, purely to test that tracker still exists, it can indeed detect the tracker. But then a single line later, it comes up with:
File "C:\Users\Mark\Desktop\Ultima Ratio Regum\URR0-2-1.py", line 17522, in world_menu
file['Tracker'] = tracker
File "C:\Python27\lib\shelve.py", line 132, in __setitem__
p.dump(value)
TypeError: expected string or Unicode object, NoneType found
I'm just... stumped. This has never happened before, and I don't see how this can be! Can anyone shed any light on this? All I've been doing is adding some things to tracker today, but tracker only really stores lists of strings, up to a few thousand, but that's all. However, if I have it create a new tracker just before the save begins, it saves fine.
EDIT:
Running pickle.dumps(tracker) reveals:
File "C:\Users\Mark\Desktop\Ultima Ratio Regum\29-12-test.py", line 17515, in world_menu
pickle.dumps(tracker)
File "C:\Python27\lib\pickle.py", line 1374, in dumps
Pickler(file, protocol).dump(obj)
File "C:\Python27\lib\pickle.py", line 224, in dump
self.save(obj)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 725, in save_inst
save(stuff)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "C:\Python27\lib\pickle.py", line 663, in _batch_setitems
save(v)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 600, in save_list
self._batch_appends(iter(obj))
File "C:\Python27\lib\pickle.py", line 615, in _batch_appends
save(x)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 725, in save_inst
save(stuff)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "C:\Python27\lib\pickle.py", line 663, in _batch_setitems
save(v)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 748, in save_global
(obj, module, name))
PicklingError: Can't pickle <built-in method capitalize of str object at 0x0A1341C0>: it's not found as __main__.capitalize
That exception is coming from the internals of cPickle.Pickler.dump
, but it doesn't appear in the traceback because of its being in a compiled C module. To get an indication of what the error is, try manually triggering the same thing, but with the pure-Python pickle
module rather than the compiled C cPickle
module:
import pickle
pickle.dumps(tracker)
This should reveal where the error is. My first guess is that your implementation of __reduce_ex__
or __reduce__
doesn't return a value.