Skip to content

Dill can't pickle abstractproperty, abstractclassmethod, or abstractstaticmethod objects #365

@alimuldal

Description

@alimuldal

The following:

import abc
import dill

print(dill.__version__)  # 0.3.1.1

class FooBar(abc.ABC):

    @abc.abstractproperty
    def thingy(self):
        return 42


dill.dumps(FooBar)

fails with:

---------------------------------------------------------------------------                                                                                                                                         
TypeError                                 Traceback (most recent call last)                                                                                                                                         
<ipython-input-4-ad16237f3136> in <module>                                                                                                                                                                          
----> 1 dill.dumps(FooBar)                                                                                                                                                                                          
                                                                                                                                                                                                                    
~/.venvs/dill/lib/python3.7/site-packages/dill/_dill.py in dumps(obj, protocol, byref, fmode, recurse, **kwds)                                                                                                      
    263     """pickle an object to a string"""                                                                                                                                                                      
    264     file = StringIO()                                                                                                                                                                                       
--> 265     dump(obj, file, protocol, byref, fmode, recurse, **kwds)#, strictio)                                                                                                                                    
    266     return file.getvalue()                                                                                                                                                                                  
    267                                                                                                                                                                                                             
                                                                                                                                                                                                                    
~/.venvs/dill/lib/python3.7/site-packages/dill/_dill.py in dump(obj, file, protocol, byref, fmode, recurse, **kwds)                                                                                                 
    257     _kwds = kwds.copy()                                                                                                                                                                                     
    258     _kwds.update(dict(byref=byref, fmode=fmode, recurse=recurse))                                                                                                                                           
--> 259     Pickler(file, protocol, **_kwds).dump(obj)                                                                                                                                                              
    260     return                                                                                                                                                                                                  
    261                                                                                                                                                                                                             
                                                                                                                                                                                                                    
~/.venvs/dill/lib/python3.7/site-packages/dill/_dill.py in dump(self, obj)                                                                                                                                          
    443             raise PicklingError(msg)                                                                                                                                                                        
    444         else:                                                                                                                                                                                               
--> 445             StockPickler.dump(self, obj)                                                                                                                                                                    
    446         stack.clear()  # clear record of 'recursion-sensitive' pickled objects                                                                                                                              
    447         return                                                                                                                                                                                              
                                                                                                                                                                                                                    
/usr/lib/python3.7/pickle.py in dump(self, obj)                                                                                                                                                                     
    435         if self.proto >= 4:                                                                                                                                                                                 
    436             self.framer.start_framing()                                                                                                                                                                     
--> 437         self.save(obj)                                                                                                                                                                                      
    438         self.write(STOP)                                                                                                                                                                                    
    439         self.framer.end_framing()                                                                                                                                                                           
                                                                                                                                                                                                                    
/usr/lib/python3.7/pickle.py in save(self, obj, save_persistent_id)                                                                                                                                                 
    502         f = self.dispatch.get(t)                                                                                                                                                                            
    503         if f is not None:                                                                                                                                                                                   
--> 504             f(self, obj) # Call unbound method with explicit self                                                                                                                                           
    505             return                                                                                                                                                                                          
    506                                                                                                                                                                                                             
                                                                                                                                                                                                                    
~/.venvs/dill/lib/python3.7/site-packages/dill/_dill.py in save_type(pickler, obj)                                                                                                                                  
   1339             del _dict[name]                                                                                                                                                                                 
   1340         pickler.save_reduce(_create_type, (type(obj), obj.__name__,
-> 1341                                            obj.__bases__, _dict), obj=obj)
   1342         log.info("# %s" % _t)
   1343     # special cases: NoneType

/usr/lib/python3.7/pickle.py in save_reduce(self, func, args, state, listitems, dictitems, obj)
    636         else:
    637             save(func)
--> 638             save(args)
    639             write(REDUCE)
    640 

/usr/lib/python3.7/pickle.py in save(self, obj, save_persistent_id)
    502         f = self.dispatch.get(t)
    503         if f is not None:
--> 504             f(self, obj) # Call unbound method with explicit self
    505             return
    506 

/usr/lib/python3.7/pickle.py in save_tuple(self, obj)
    787         write(MARK)
    788         for element in obj:
--> 789             save(element)
    790 
    791         if id(obj) in memo:

/usr/lib/python3.7/pickle.py in save(self, obj, save_persistent_id)
    502         f = self.dispatch.get(t)
    503         if f is not None:
--> 504             f(self, obj) # Call unbound method with explicit self
    505             return
    506 

~/.venvs/dill/lib/python3.7/site-packages/dill/_dill.py in save_module_dict(pickler, obj)
    910             # we only care about session the first pass thru
    911             pickler._session = False
--> 912         StockPickler.save_dict(pickler, obj)
    913         log.info("# D2")
    914     return

/usr/lib/python3.7/pickle.py in save_dict(self, obj)
    857 
    858         self.memoize(obj)
--> 859         self._batch_setitems(obj.items())
    860 
    861     dispatch[dict] = save_dict

/usr/lib/python3.7/pickle.py in _batch_setitems(self, items)
    883                 for k, v in tmp:
    884                     save(k)
--> 885                     save(v)
    886                 write(SETITEMS)
    887             elif n:

/usr/lib/python3.7/pickle.py in save(self, obj, save_persistent_id)
    522             reduce = getattr(obj, "__reduce_ex__", None)
    523             if reduce is not None:
--> 524                 rv = reduce(self.proto)
    525             else:
    526                 reduce = getattr(obj, "__reduce__", None)

TypeError: can't pickle abstractproperty objects

abstractclassmethod and abstractstaticmethod also fail in the same way.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions