It was intentionally left a generic "cannot pickle 'type' object". Because there are many ways to make an object pickleable, and it is non-pickleable in all other cases.
* "missing `__getstate__()` on variable-length object"
It creates false impression that implementing __getstate__() is the only way to solve the problem. Actually you can make that object pickleable by:
- implementing __reduce__() or __reduce_ex__()
- implementing __getnewargs__() or __getnewargs_ex__()
- implementing __getstate__()
- make it a subclass of list or dict
So more correct error message should contain "missing __reduce__(), __reduce_ex__(), __getnewargs__(), __getnewargs_ex__() and __getstate__() on variable-length object which is not a list or dict". And even this is not completely correct, because it has __reduce__() and __reduce_ex__() inherited from class object, but it is not enough. Completely correct error message can be hundreds characters long.
And this still may be misleading error message, because the root cause is not that some object is not pickleable, but that you try to pickle an object which has an unexpected non-pickleable component.
* "basic size greater than expected"
Basic size is an implementation detail, and the end user can have no guess what is it. Actually it means that an object implemented in C likely has some inner state and the pickle module does not have access to it because the object does not implement __reduce__(), __reduce_ex__(), __getnewargs__(), __getnewargs_ex__() or __getstate__().
* "object has no `__new__()`"
Every object has __new__ at Python level, even if its tp_new slot is NULL. tp_new is the C implementation detail and should not be mentioned in the error message. And the object without tp_new still can be pickleable, if it implements __reduce__() or __reduce_ex__().
It is all too complicated. It is better to omit details in error messages than provide not correct and direct user in wrong way.
|