Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > weakref.proxy behaviour in python 3.0

Reply
Thread Tools

weakref.proxy behaviour in python 3.0

 
 
Nicholas Cole
Guest
Posts: n/a
 
      08-21-2010
Dear List,

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.

Is this an expected change?

Best wishes,

Nicholas
 
Reply With Quote
 
 
 
 
Mark Dickinson
Guest
Posts: n/a
 
      08-21-2010
On Aug 21, 1:13*pm, Nicholas Cole <(E-Mail Removed)> 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
 
Reply With Quote
 
 
 
 
Nicholas Cole
Guest
Posts: n/a
 
      08-21-2010
On Sat, Aug 21, 2010 at 3:31 PM, Mark Dickinson <(E-Mail Removed)> wrote:

[SNIP]

> 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.


Dear Mark,

I think the docs should be fixed: it would be good to have a list of
key examples where the behaviour is different. Although the new
behaviour is better, it certainly tripped me up badly.

I'm happy to fill a report out, but since you seem to know much more
about the internals, I wonder if a bug report written by you would be
more useful!

Just in case it helps, one thing that does seem to be the case is that
two different proxy objects to the same real object get compared in
the same way on both versions. So this code:

a = weakref.proxy(the_real_object)
b = weakref.proxy(the_real_object)

this_list = [ a, ]

l.remove(a) # Obviously works on both - just here for clarity.

l.remove(the_real_object) # Fails on python 2.6

l.remove(b) # gives an empty list on python 2.6 and python 3.


Very best wishes,

Nicholas
 
Reply With Quote
 
Mark Dickinson
Guest
Posts: n/a
 
      08-21-2010
On Aug 21, 5:06*pm, Nicholas Cole <(E-Mail Removed)> wrote:
> On Sat, Aug 21, 2010 at 3:31 PM, Mark Dickinson <(E-Mail Removed)> wrote:
>
> [SNIP]
>
> > 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.

>
> I think the docs should be fixed: it would be good to have a list of
> key examples where the behaviour is different. *Although the new
> behaviour is better, it certainly tripped me up badly.
>
> I'm happy to fill a report out, but since you seem to know much more
> about the internals, I wonder if a bug report written by you would be
> more useful!


http://bugs.python.org/issue9658

Please do log in and add any extra comments you feel appropriate.

--
Mark
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
debugger behaviour different to execution behaviour Andy Chambers Java 1 05-14-2007 09:51 AM
Python 2.3.3 super() behaviour Nicolas Lehuen Python 11 04-22-2004 08:46 AM
Unexpected mod-python behaviour. Simon Wittber Python 1 02-06-2004 06:45 PM
Unexpected python behaviour Richard Philips Python 2 11-28-2003 03:14 PM
Strange Python COM behaviour a_bogdan_marinescu Python 1 11-16-2003 02:12 AM



Advertisments