Hi Nils,
On 2013-09-08, Nils Bruin <
nbr...@sfu.ca> wrote:
> However, shouldn't we recognize that caches are essentially *modifications
> of state* of an object after creation and hence should be set during
> setstate rather than during creation call? It may well be that that solves
> most of our reduce loop problems (at least the ones related to caches).
The point, at least in the original example, is: We have an object O and
an attribute A of O. For creation of A, we need hash(O). Hence, unpickling
of O will only work if A is not dealt with too early.
However, if it is badly done, then dealing with A in the "setstate"
phase of O might still not work easily: Perhaps hash(O) depends on
further data that are inserted during the "setstate" phase?
Actually this is exactly the problem in the original example (with different
names):
In the "creation" phase, a new instance of O.__class__ is created by means
of __new__, but without calling __init__. Then, O.__dict__ shall be
filled in the "setstate" phase. Python decides to first fill it with
A, whose creation relies on hash(O), but in order to get hash(O) one
would first need to fill another attribute "i" into O.__dict__, which Python
has not dealt with yet.
> I think that can be relaxed a bit: data going into the *creation* phase
> should be "minimal" and avoid circularity, because that's where the loops
> really bite. I think the setstate phase can deal with circular stuff.
As I have shown, problems can occur in both phases.
> It probably means that we always have to handcraft our reduce methods,
> which is inconvenient to say the least...
That's the point I wanted to make in my posts on the ticket (and here,
too): When we create a Python class, we *should* implement pickling
by ourselves, either by providing a __reduce__ method or __initargs__
and stuff. We can't rely on Python doing the right thing for us, since
Python can't deal with constructions like the following:
O.A = {O:1}
And my modification of the original example has shown that the problem
is *not* in UniqueRepresentation or __cached_method. You get the same
with any odd dictionary that appears as attribute of "self" and uses
"self" as a key. Python needs help to accomplish pickling in this case.
Best regards,
Simon