weakref.proxy behaviour in python 3.0
Mark Dickinson
dickinsm at gmail.com
Sat Aug 21 10:31:03 EDT 2010
On Aug 21, 1:13 pm, Nicholas Cole <nicholas.c... at gmail.com> wrote:
> I've searched for information on this without success. Has
> weakref.proxy changed in Python 3? I couldn't see any note in the
> documentation, but the following code behaves differently on Python
> 2.6.1 and Python 3:
>
> import weakref
> class Test(object): pass
>
> realobject = Test()
> pobject = weakref.proxy(realobject)
> l = [pobject,]
>
> print(realobject in l) # On python 2.6 this prints False, on Python 3 True.
So the change underlying what you're seeing is that comparisons in 3.x
'unwrap' the proxy, while in 2.x they don't:
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
It looks to me as though this could be a long-standing defect in
Python 2.x, unwittingly(?) corrected in Python 3.x when 3-way
comparisons were removed in favour of rich comparisons. See
http://svn.python.org/view?view=rev&revision=51533
For 2.7, the proxy source (in Objects/weakrefobject.c) defines a
'proxy_compare' function that's used in the 'tp_compare' slot for
proxy objects, and that proxy_compare function has code to unwrap the
proxy objects when necessary so that comparisons are done on the real
underlying objects.
*But* C-level tp_compare slots only ever get called when both objects
have the same type, so when comparing a real object with the proxy for
that object, that's never.
In 3.x, that's replace with a proxy_richcompare function for the
tp_richcompare slot.
So my guess is that the change was unintentional.
It's probably worth a bug report. Even if the behaviour isn't going
to change in either 2.x or 3.x (and it probably isn't), it might be
possible to clarify the docs.
--
Mark
More information about the Python-list
mailing list