Question

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
Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top