[wxPython] pickle, wxDateTime and wxDateSpan

I'd like to be able to pickle objects containing wxDateTime and wxDateSpan
objects. Currently there is a problem on pickle load.

As an experiment I added __getstate__ and __setstate__ methods to
wxDateTimePtr and wxDateSpanPtr (see below) to wxDateTime and wxDateSpan.

The primary constructors seem to work fine, but I run into problems with the
alternate constructors for wxDateSpan.

wxDateSpan_Months()
wxDateSpan_Years()
etc.

Here's a unit test method to illustrate the problem:

    def testPersistence2(self):
        """ Tests persistence (pickle) with DateSpan_Months(12).

        """
        dateSpan = wxDateSpan_Months(12)
        
        testFileName = 'testfile.dat'
        file = open(testFileName, 'w')
        pickle.dump(dateSpan, file)
        file.close()
        
        try:
            file = open(testFileName, 'r')
            dateSpan2 = pickle.load(file)
            file.close()
            
        except IOError:
            fail('IO Error caught')
            
        except EOFError:
            fail('Unexpected EOF in file.')

        assert dateSpan2 == dateSpan, "dateSpan2 ne dateSpan"

···

======================================================================
ERROR: Tests persistence (pickle) with DateSpan_Months(12).
----------------------------------------------------------------------
Traceback (most recent call last):
  File "./DateSpanTest.py", line 107, in testPersistence2
    dateSpan2 = pickle.load(file)
  File "c:\python21\lib\pickle.py", line 947, in load
    return Unpickler(file).load()
  File "c:\python21\lib\pickle.py", line 567, in load
    dispatch[key](self)
  File "c:\python21\lib\pickle.py", line 747, in load_inst
    value = apply(klass, args)
TypeError: in constructor for wxDateSpanPtr: __init__() takes exactly 2
argument
s (1 given)
----------------------------------------------------------------------

The problem seems to be related to the fact that an object created as
wxDateSpan() is a wxPython.utils.wxDateSpan class object, but an object
created as wxDateSpan_Months() is a wxPython.utils.wxDateSpanPtr class
object.

Here is the experimental code added to the wxDateSpan class:

    def __getinitargs__(self):
        """ I added __getinitargs__() here to force calling __init__()
        """
        return ()
        
    def __getstate__(self):
        odict = {}
        odict['years'] = self.GetYears()
        odict['months'] = self.GetMonths()
        odict['weeks'] = self.GetWeeks()
        odict['days'] = self.GetDays()
        return odict

    def __setstate__(self, dict):
        self.SetYears(dict['years'])
        self.SetMonths(dict['months'])
        self.SetWeeks(dict['weeks'])
        self.SetDays(dict['days'])

The problem might be in my __getinitargs__() method. What are the
appropriate arguments to pass as default arguments in wxDateSpanPtr?

Thanks!!!

Mark Morga [mailto:mmorga@espectech.com]
E-Spectrum Technologies

The problem might be in my __getinitargs__() method. What are the
appropriate arguments to pass as default arguments in wxDateSpanPtr?

All the *Ptr classes take (in addition to self) a string which is a
"swigified pointer" that points to the coresponding C++ object. The only
way to get this is to have an existing C++ object, or to create one and
hijack it's .this attribute.

···

--
Robin Dunn
Software Craftsman
robin@AllDunn.com Java give you jitters?
http://wxPython.org Relax with wxPython!