2

I am trying to pickle a django model object in django 1.11 and it is throwing an error - "TypeError: can't pickle function objects"

I am using cPickle.dumps(obj)

I understand we cannot pickle function objects.

But same object when I try to pickle in django 1.3 environment it is doing it properly. So, to check this I went into copy_reg.py -> _reduce_ex function, here self is coming as function my_func_name at 0x7fe5075e6f50 in django 1.11 and django.db.models.base.ModelState object at 0x7fdda59765d0 in django 1.3.

So, in django 1.3 ModelState can be pickled but not in django 1.11 as it is function object.

Why is the self coming as function in 1.11 and ModelState class in 1.3.

Following is the function from copy_reg.py --

def _reduce_ex(self, proto):
    assert proto < 2
    for base in self.__class__.__mro__:
        if hasattr(base, '__flags__') and not base.__flags__ & _HEAPTYPE:
            break
    else:
        base = object # not really reachable
    if base is object:
        state = None
    else:
        if base is self.__class__:
            raise TypeError, "can't pickle %s objects" % base.__name__
        state = base(self)
    args = (self.__class__, base, state)
    try:
        getstate = self.__getstate__
    except AttributeError:
        if getattr(self, "__slots__", None):
            raise TypeError("a class that defines __slots__ without "
                        "defining __getstate__ cannot be pickled")
        try:
            dict = self.__dict__
        except AttributeError:
            dict = None
    else:
        dict = getstate()
    if dict:
        return _reconstructor, args, dict
    else:
        return _reconstructor, args
mukul
  • 111
  • 8
  • One thing I found is that a dynamically added function does not get pickled by cPickle or pickle. And in django.db.models.base I am monkey patching my version of model_unpickle which is giving this error. How can I pickle a dynamically created function ? – mukul May 16 '17 at 23:05

0 Answers0