classification
Title: weakref.proxy unequal to its referent in 2.x
Type: behavior Stage: needs patch
Components: Documentation Versions: Python 3.1, Python 3.2, Python 2.7
process
Status: closed Resolution: duplicate
Dependencies: Superseder: weakref.proxy incorrect behaviour
View: 1170766
Assigned To: docs@python Nosy List: docs@python, georg.brandl, mark.dickinson, terry.reedy
Priority: normal Keywords:

Created on 2010-08-21 19:44 by mark.dickinson, last changed 2010-08-21 21:35 by georg.brandl. This issue is now closed.

Messages (3)
msg114557 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2010-08-21 19:44
Nicholas Cole noted on python-list that the behaviour of weakref.proxy with respect to equality changed between 2.x and 3.x:

Python 2.7 (r27:82500, Aug 15 2010, 14:21:15) 
[GCC 4.2.1 (Apple Inc. build 5664)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import weakref 
>>> s = set() 
>>> s == weakref.proxy(s) 
False 

Python 3.1.2 (r312:79147, Aug 20 2010, 20:06:00) 
[GCC 4.2.1 (Apple Inc. build 5664)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import weakref 
>>> s = set() 
>>> s == weakref.proxy(s) 
True

This seems to be an inadvertent change resulting from the switch from 3-way comparisons to rich comparisons:  the 2.x source implements tp_compare for proxy objects.  The tp_compare slot *does* unwrap the proxy objects before comparing, but since the tp_compare slot in general  is only ever called (for objects implemented in C) when the types of the objects being compared are the same, a proxy object won't compare equal to its referent.

I believe that Nicholas ran into this when using weakrefs as elements of containers.  Nicholas:  is that right?  Care to elaborate?

The 3.x source changes this to use tp_richcompare (see r51533), so now a proxy object *does* compare equal to its referent.

The 3.x behaviour seems better to my limited eyes, and the 2.x behaviour has been around a long time without causing problems, so we probably don't want to change the behaviour in either case.  But it might be good to document the difference somewhere.
msg114565 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2010-08-21 21:30
This is definitely not a critical fix for 2.6 ;-)

The weakref.proxy doc says nothing about comparisons:

"weakref.proxy(object[, callback]) 
Return a proxy to object which uses a weak reference. This supports use of the proxy in most contexts instead of requiring the explicit dereferencing used with weak reference objects. The returned object will have a type of either ProxyType or CallableProxyType, depending on whether object is callable. Proxy objects are not hashable regardless of the referent; this avoids a number of problems related to their fundamentally mutable nature, and prevent their use as dictionary keys. callback is the same as the parameter of the same name to the ref() function."

so this is not a behavior bug.

A patch for 2.7 could include a note that the behavior changes in 3.x. The 3.x patch should only say what the 3.x behavior is. This is assuming that the behavior should be defined as in 3.x for all implementations. Since it seems straightforward, it seems reasonable to me to do so.

The comparison behavior of 'basic' types is actually defined in the ref manual section 5.9 Comparisons (3.1). Cross-type behavior is summarized as "Comparison of objects of the differing types depends on whether either of the types provide explicit support for the comparison." I think the detailed info for weakref proxys belongs with the weakref proxy entry as suggested above.
msg114567 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2010-08-21 21:35
Duplicate of #1170766 -- the lack of tp_richcompare support is reported among other missing slots there.
History
Date User Action Args
2010-08-21 21:35:59georg.brandlsetstatus: open -> closed

nosy: + georg.brandl
messages: + msg114567

superseder: weakref.proxy incorrect behaviour
resolution: duplicate
2010-08-21 21:31:00terry.reedysetassignee: docs@python
components: + Documentation
versions: + Python 3.1, Python 3.2, - Python 2.6
nosy: + docs@python, terry.reedy

messages: + msg114565
stage: needs patch
2010-08-21 19:44:20mark.dickinsoncreate