Issue1534

classification
Title: new style object __dict__[name] ignored
Type: Severity: normal
Components: Core Versions: 2.5.1
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: pjenvey Nosy List: iamedu, pjenvey
Priority: Keywords:

Created on 2010-01-06.13:19:11 by iamedu, last changed 2010-01-10.22:30:45 by pjenvey.

Messages
msg5410 (view) Author: Eduardo Diaz (iamedu) Date: 2010-01-06.13:19:10
This is a bit strange, here is the sample:

class Attr(object):
    def __init__(self, name):
        self.name = name

    def __set__(self, instance, value):
        instance.__dict__[self.name] = value


class Test(object):
    attr = Attr('attr')

    def test(self):
        self.attr = 5

t = Test()
print t.attr
t.test()
print t.attr

In python, if you have a newstyle object called x, and in some point define the attribute __dict__["x"] as 5 then getting the value of x. So in python that program would return:

<__main__.Attr object at 0x7f1b820b7f90>
5

On jython it returns:

<__main__.Attr object at 0x1>
<__main__.Attr object at 0x1>

A workaround would be to add a __get__ method something like this:

    def __get__(self, instance, owner):
        return instance.__dict__[self.name]

But for compatibility it would be nice to change this.

Thanks!
msg5415 (view) Author: Philip Jenvey (pjenvey) Date: 2010-01-06.18:34:18
Thanks for logging this, I just went over it with Chris McDonough yesterday. pypy also suffers from this
msg5422 (view) Author: Philip Jenvey (pjenvey) Date: 2010-01-10.22:30:44
Jython/Pypy seem more correct than CPython according to the rules on http://docs.python.org/reference/datamodel.html

"For instance bindings, the precedence of descriptor invocation depends on the which descriptor methods are defined. Normally, data descriptors define both __get__() and __set__(), while non-data descriptors have just the __get__() method. Data descriptors always override a redefinition in an instance dictionary. In contrast, non-data descriptors can be overridden by instances."

"A descriptor can define any combination of __get__(), __set__() and __delete__(). If it does not define __get__(), then accessing the attribute even on an instance will return the descriptor object itself. If the descriptor defines __set__() and/or __delete__(), it is a data descriptor; if it defines neither, it is a non-data descriptor."

But I don't think we can fault CPython as it's had this behavior forever
History
Date User Action Args
2010-01-10 22:30:45pjenveysetmessages: + msg5422
2010-01-06 18:34:18pjenveysetassignee: pjenvey
messages: + msg5415
nosy: + pjenvey
2010-01-06 13:19:12iameducreate