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