<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Wed, 11 Apr 2018 at 05:09 Steven D'Aprano <<a href="mailto:steve@pearwood.info">steve@pearwood.info</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Wed, Apr 11, 2018 at 08:21:01AM -0300, Joao S. O. Bueno wrote:<br>
> I just came across a code snippet that<br>
> would define a method with the "__dict__" name - like in:<br>
> <br>
> class A:<br>
> def __dict__(self):<br>
> return ()<br>
<br>
That's a strange thing to do, but I don't think it ought to be illegal. <br>
Consenting adults and all that.<br>
<br>
<br>
> The resulting class's instances can be assigned<br>
> dynamic attributes as usual, but one can never acess<br>
> its actual local variables through instance.__dict__ -<br>
> the method is retrieved instead.<br>
<br>
Yes, I believe that is expected behaviour for attribute access since the <br>
descriptor protocol was added. Methods take priority over data <br>
attributes, if I recall correctly.<br></blockquote><div><br></div><div>Yep, they do.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<br>
> Calling "vars" will also fail on objects of this class.<br>
<br>
I consider that a pseudo-bug. I can't call it an actual bug, because <br>
vars() doesn't document that it will work even when __dict__ is shadowed <br>
in this way, but I think it should. So its a bug against a future <br>
feature :-)<br>
<br>
Attribute access still works correctly even with such a shadow:<br>
<br>
py> class W:<br>
... def __dict__(self):<br>
... return ()<br>
...<br>
py> obj = W()<br>
py> obj.spam = 1<br>
py> obj.spam<br>
1<br>
<br>
so there is still an instance dict somewhere inside the instance, and <br>
the C attribute-access machinary can access it. I think vars() should be <br>
able to do the same.<br>
<br>
(I'm not saying this in order to encourage people to shadow __dict__.)<br>
<br>
<br>
> This behavior is weird, and I believe is actually a side-effect<br>
> of implementation details on CPython.<br>
<br>
Its certain a weird thing to do, but I don't believe it is an <br>
implementation detail. Apart from the behaviour of vars(), I think the <br>
behaviour here all follows from the documented behaviour of the <br>
descriptor protocol.<br>
<br>
<br>
> I am not sure whether it should just:<br>
> 1 - be left as is - whoever reuses __dict__ as a method had it coming<br>
> 2 - document CPython behavior<br>
> 3 - file that as a bug to disallow __dict__ override in class declaration<br>
> 4 - file that as a bug to not-create class __dict__ when one is explictly<br>
> created in Python code (the same that happens when one have "__slots__".<br>
> <br>
> I have the feeling that (1) is just good - but then, I am at least<br>
> posting this e-mail here.<br>
<br>
I agree that (1) is the best, but vars() ought to work even in the <br>
presence of a method shadowing __dict__.<br></blockquote><div><br></div><div>I say option 1 as well.<br><br></div><div>-Brett<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<br>
> Similar weird things go when one creates a method named "__class__",<br>
> and possible other names.<br>
<br>
type(instance) still works correctly when instance.__class__ is shadowed <br>
by a method.<br>
<br>
<br>
-- <br>
Steve<br>
_______________________________________________<br>
Python-Dev mailing list<br>
<a href="mailto:Python-Dev@python.org" target="_blank">Python-Dev@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-dev" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-dev</a><br>
Unsubscribe: <a href="https://mail.python.org/mailman/options/python-dev/brett%40python.org" rel="noreferrer" target="_blank">https://mail.python.org/mailman/options/python-dev/brett%40python.org</a><br>
</blockquote></div></div>