My solution, which is currently working, was to : 

    def __reduce__(self):
        return type(self), (),  self.__getstate__()

    def __getstate__(self):
        if hasattr(self, "__dict__"):
            return (self.inboundkey, self.inboundlinks, self.tags,
self.__dict__)
        else:
            return (self.inboundkey, self.inboundlinks, self.tags, {})

    def __setstate__(self, state):
        (self.inboundkey, self.inboundlinks, self.tags, tgtdict)  =
state
        for k, v in tgtdict.iteritems() :
            setattr(self, k, v)
        

That is, if an object has a dict, take that dict and return it as an
argument. Then when we unpickle just restore everything in that dict. 

I'd love to hear if someone has a better way, but this is working great
right now. Thanks again to everyone who helped. 
                        ...Eric


On Tue, 2008-05-27 at 20:45 -0300, Lisandro Dalcin wrote:
> Tomorrow I'll give the details, but yes, you could return a dict from
> __getstate__, and then in __setstate__ loop over the dict items and
> calling setattr(self, key, value). Perhaps that's enough for you, give
> a try!.
> 
> On 5/27/08, Eric Jonas <[EMAIL PROTECTED]> wrote:
> > _amazing_
> >
> >  Thank you so much.
> >
> >  So one final question regarding additional state in derived classes. To
> >  simplify I've written a new bit of code for test.py:
> >
> >
> >  class MyPairExtra(pair):
> >     def __init__(self, f=0, s=0):
> >         self.first  = f
> >         self.second = s
> >         self.extra = 1234
> >         self.extra2 = 0
> >
> >
> >  p6 = MyPairExtra()
> >  p6.extra2 = 5678
> >
> >  s6p2 = pkl.dumps(p6, 2)
> >
> >  s6p2load = pkl.loads(s6p2)
> >  assert s6p2load.extra == 1234
> >  assert s6p2load.extra2 == 5678
> >
> >  The last assertion currently fails. You'll note that the "extra"
> >  attribute is correctly recovered by the "extra2" attribute, which we set
> >  after construction to 5678, is not. Is there any way to pickle arbitrary
> >  extra object state?
> >
> >  Thanks again,
> >
> >                         ...Eric
> >
> >
> >
> >
> >  On Tue, 2008-05-27 at 18:57 -0300, Lisandro Dalcin wrote:
> >  > Eric, please sorry for the confussion, I just had a bug in __reduce__
> >  > . Look at the new files attached, your last use case is included in
> >  > the test script.
> >  >
> >  >  __reduce__ returns a 3-tuple: the fist item is the type object, with
> >  > pickle sees as a callable, the second is a tuple argument for that
> >  > callable, and the third is the state
> >  >
> >  > In general, if you implement __reduce__ like this
> >  >
> >  > def __reduce__(self):
> >  >    return function, args, state
> >  >
> >  > the at un-pickle time, Python (2.5) does
> >  >
> >  > function, args, state = unpickle(stream)
> >  > newobj = function(*args)
> >  > newobj.__setstate__(state)
> >  >
> >  > and then 'newobj' is the final recoverd object.
> >  >
> >  > I hope I was clear enough. If you still want to need more complicated
> >  > stuff, please just keep coming. All this discussion will surelly help
> >  > in the future at the time Cython tries to implement something to
> >  > automatically manage all this beast.
> >  >
> >  >
> >  >
> >  >
> >  > On 5/27/08, Eric Jonas <[EMAIL PROTECTED]> wrote:
> >  > > To start with, this is awesome. Thank you so much!
> >  > >
> >  > >  Next question: What if I want MyPair to have a zero-argument
> >  > >  constructor? (Well, besides self, that is). If I do:
> >  > >
> >  > >  class MyPair(pair):
> >  > >    def __init__(self):
> >  > >        pass
> >  > >
> >  > >  then I get "TypeError: ('__init__() takes exactly 1 argument (3 
> > given)".
> >  > >  Does this mean that derived types must always have constructors with 
> > the
> >  > >  same number (or more) than their base type?
> >  > >
> >  > >  Thanks,
> >  > >
> >  > >         ...Eric
> >  > >
> >  > >
> >  > >
> >  > >
> >  > >  On Tue, 2008-05-27 at 15:47 -0300, Lisandro Dalcin wrote:
> >  > >  > Well, I admit that the Python docs are a bit hard to follow, but 
> > let's
> >  > >  > solve your issue. Look at the  attached files,
> >  > >  >
> >  > >  > * mod.pyx: a simple 'cdef' class pair, like the C++ one
> >  > >  > * test.py: a full test, all pickle protocols, includes subclassing
> >  > >  > * cy2py: my lovely distutils based script for the process 
> > *.pyx->*.so
> >  > >  > (no need of makefiles, improvements welcome!)
> >  > >  >  run like $ python cy2py mod.pyx . This way, you get mod.so.
> >  > >  >
> >  > >  > If you find this code useful, you can donate some dollars ... Just a
> >  > >  > joke! But if you can make it a really good example, It would be 
> > great
> >  > >  > to have this included in Cython docs, in order to help other doing
> >  > >  > this, I just do not have the time.
> >  > >  >
> >  > >  > Enjoy!
> >  > >  >
> >  > >  >
> >  > >  > On 5/27/08, Eric Jonas <[EMAIL PROTECTED]> wrote:
> >  > >  > >
> >  > >  > >  > But there is definitelly better ways. You sould look at the 
> > docs of
> >  > >  > >  > pickle module, and particularly to the 
> > __getinitargs__/__getnewargs__
> >  > >  > >  > and the __getstate__/__setstate__  stuff.  Iff I were to 
> > implement
> >  > >  > >  > pickle protocol, I would explicitely use that.
> >  > >  > >
> >  > >  > >
> >  > >  > >
> >  > >  > > The python pickle docs, which I've been struggling to understand, 
> > seem
> >  > >  > >  to suggest that __reduce__ is necessary for all extensions, or 
> > to use
> >  > >  > >  the copy_reg module. But it seems that __getstate__/__setstate__ 
> > are not
> >  > >  > >  applicable for c-extensions. Is this correct?
> >  > >  > >
> >  > >  > >  Thanks,
> >  > >  > >
> >  > >  > >                 ...Eric
> >  > >  > >
> >  > >  > >
> >  > >  > >
> >  > >  > >  _______________________________________________
> >  > >  > >  Cython-dev mailing list
> >  > >  > >  [email protected]
> >  > >  > >  http://codespeak.net/mailman/listinfo/cython-dev
> >  > >  > >
> >  > >  >
> >  > >  >
> >  > >  > _______________________________________________
> >  > >  > Cython-dev mailing list
> >  > >  > [email protected]
> >  > >  > http://codespeak.net/mailman/listinfo/cython-dev
> >  > >
> >  > >  _______________________________________________
> >  > >  Cython-dev mailing list
> >  > >  [email protected]
> >  > >  http://codespeak.net/mailman/listinfo/cython-dev
> >  > >
> >  >
> >  >
> >  > _______________________________________________
> >  > Cython-dev mailing list
> >  > [email protected]
> >  > http://codespeak.net/mailman/listinfo/cython-dev
> >
> >  _______________________________________________
> >  Cython-dev mailing list
> >  [email protected]
> >  http://codespeak.net/mailman/listinfo/cython-dev
> >
> 
> 

_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to