max
max

Reputation: 52283

can weakref not evaluate to None even though no non-weak references point to an object?

From what I understand, Python 3 does not make any guarantees about when the memory for an object is released except that it is not released as long as at least one non-weak reference points to an object.

Does the language make any other guarantees about the weak references? In particular, suppose I create a weakref wr pointing to some object. Suppose by some later time, all non-weak references to that object have been destroyed. Is it guaranteed that at that time wr would evaluate to None, or might it still evaluate to the original object for a while?

Apart from the language guarantees, is there any interesting implementation behavior around weakref?

Upvotes: 3

Views: 1050

Answers (4)

Lee McCuller
Lee McCuller

Reputation: 86

Since It seems that all weak references being released coherently is not guaranteed (as per Guido's post). One thing that you could do is to use a single weak reference across every location where you would otherwise generate a new weak reference (since the single reference must look the same to all that are using it).

Here you would lose the nice callback mechanism for all of the different references-to-references, but you could recover them by subclassing weakref.ref and adding some kind of registration scheme. You would also need some way of locating a weakref's single instance. Either package it with the instance to be referenced and make a helper method to get it or create-it (be aware of thread safety issues, use getattr with a default if you don't want locks too). Alternatively you could make a singleton to find them (use the first method...).

Coherent dissapearence in weakrefs seems like it should be guaranteed for the sake of sane memoization schemes, but using a single weakref should work albeit at the cost of reimplementing the weakref scheme of the interpreter with the guarantees you need.

you actually could use the .__weakref__ attribute, where weakrefs show up on instances within the interpreter and use the helper function method with that.

Upvotes: 0

Guido van Rossum
Guido van Rossum

Reputation: 16890

The weakref either gives you a valid object (from Python's POV), or None. At which point an object is actually deallocated (causing the weakref to go to None) is undefined except that there cannot be any non-weak references to the object from any other live objects. The reference counting behavior you observe in CPython is not guaranteed.

Upvotes: 0

Thomas Wouters
Thomas Wouters

Reputation: 133445

No, Python doesn't make any guarantees as to when an object is actually collected and the weakref will return None. It could happen right away (and it often is in CPython, which uses reference counting plus a cyclic-reference garbage collector, but much less often in other Python implementations that don't use refcounting.) It can also be delayed for a number of reasons -- when not using CPython (or using a version of CPython that doesn't use refcounting), or when using refcounting but when your objects participate in a reference cycle.

Upvotes: 1

Mike Chamberlain
Mike Chamberlain

Reputation: 42490

A weakly referenced object will only be destroyed once GC kicks in. As this is non-deterministic, it is not guaranteed that it will be destroyed as soon as all strong references have been dropped.

From the docs:

...when the only remaining references to a referent are weak references, garbage collection is free to destroy the referent and reuse its memory for something else.

The operative phrase is "free to destroy the referent" - it may not happen immediately.

Upvotes: 1

Related Questions