New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New class special method lookup change #37537
Comments
The lookup of special methods invoked implicitly by This was reported on c.l.p by Jan Decaluwe using class Iold:
def __init__(self,ob):
self.ob = ob
def __getattr__(self,name):
return getattr(self.ob,name)
class Inew(object):
def __init__(self,ob):
self.ob = ob
def __getattr__(self,name):
return getattr(self.ob,name)
a = Iold(1) #2
b = Inew(1) #2
a.__add__(1) #2
b.__add__(1) #2
a+1 #2
b+1 #error
#TypeError: unsupported operand types for +: 'Inew'
and 'int'
Inew.__getattribute__ = Inew.__getattr__
b+1 #same error, no loop
#TypeError: unsupported operand types for +: 'Inew'
and 'int'
b.__add__(1) # WARNING starts 'infinite' loop
def _(self,other): print 'hello'
Inew.__add__ = _
b+1 #prints 'hello', __getattribute__ bypassed. http://python.org/2.2/descrintro.html says: Was lookup change meant to be one of differences? "There's a new way of overriding attribute access. The But it is different. "But you can now also override __getattribute__, a Except for implicit special methods. I did not classify discrepancy because I don't know |
Logged In: YES Print-style 'debugging' output provided by Bengt Richter in |
Logged In: YES FWIW, this is still true for Python 2.4 (i.e. the search for The 'infinite loop' is courtesy of the call to 'self.ob' Also of interest - int(b) fails with a TypeError, and str(b) So it looks like these methods are not invoked when looking To me, this looks like a documentation bug. Magic methods In order to change the 'implicit' behaviour of the object, |
I was just bit by this today in converting a proxy class from old style This seems like an issue that is going to come up more frequently as Though preferably with some knowledge of all exising magic names. |
The 2.6 and 3.0 documentation has already been updated appropriately. It may be appropriate to add a -3 warning that is triggered whenever a |
I assume when you say that the documentation has already been updated, As both of those claim to still not be up to date in relation to new Sure, there's this note under "Special Method Names": But that only helps you figure it out if you already know what the I'm not arguing that this is something that's going to change, as we're In both cases, since they are generic proxies that once initialized are It's hard to get fancy about it too, as I can't just dynamically add None of the solutions really seem ideal, or at least as good as what |
Agreed that section of the docs should be more explicit in pointing out It's also true that there are quite a few special methods where nothing Perhaps it would be useful to have a method on type instances that could (Note that it's only those methods with dedicated slots in the C type |
I've started a discussion on the Py3k development list regarding the |
I spent an enlightening evening browsing through the source code for This is normally transparent to the user due to the fact that However, this prompted me to try an experiment (Python 2.5.1), and the >>> class Demo:
... def __index__(self):
... return 1
...
>>> a = Demo()
>>> b = weakref.proxy(a)
>>> operator.index(a)
1
>>> operator.index(b)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'weakproxy' object cannot be interpreted as an index Oops. |
Somewhat related: bpo-2605 (descriptor __get__/set/delete) |
I've been following the py3k maliing list disscussion for this issue, The reason I think this approach is valuable is that in all of the This is also why I expect my proxies to keep working the same when I So, yeah, very much in favor of a base proxy class in the standard |
I've attached a sample ProxyBase class that delegates all of the special While there are other special methods in CPython (e.g. __enter__ and For lack of a better name, I called the module typetools (by analogy to Note that correctly implementing a proxy class as a new-style class |
Is there any reason not to name it ProxyMixin, ala DictMixin? |
Attached a new version of the module, along with a unit test file. The |
Added documentation, and assigned to Barry as release manager for 2.6/3.0. Also bumped to 'release blocker' status because I think the loss of If I get the go-ahead from Barry or Guido, I'll add the new module to |
Also changed to a library issue instead of a docs issue. |
Unfortunately, the standard library doesn't tend to do this kind of However, maintaining such a class on PyPI is also fairly undesirable, As far as adding a module for a single class goes, I wouldn't expect it That said, I'd be happy enough with adding the ProxyMixin to the types |
And (mainly for Barry's benefit) a quick recap of why I think this is For performance or correctness reasons, the interpreter is permitted to In CPython's case, this bypassing can occur either because there is a This behaviour creates a problem for value-based delegation such as that The intent of providing a typetools.ProxyMixin (or alternatively a Given the close proximity of the beta perhaps I should PEP'ify this to |
bleh, "application independent decision" in my last post should read |
and "__print__" was meant to be "__unicode__"... |
New patch (proxymixin.diff) uploaded that correctly delegates |
Note that I don't make any promises about the correctness of the ReST |
The name Proxy seems too vague. This class is all about targeted |
I want to make this "bypass getattr" behavior mandatory for those I am not sure that we need a proxy implementation in the stdlib; usually |
Thanks for the pronouncement Guido. We will not let this issue hold up |
The outcome of discussion of this issue on python-dev was that the While I offered to write that new section of the docs during the |
Hi, I was trying to implement a generic proxy class with some I guess my question is that 1> is it just going to be a documentation change (first)? 2> is it technically difficult(other things are going to be broken 2> Otherwise, what is the rationale behind keeping the differences? thank you. |
There are both speed and correctness reasons for special methods being Aside from providing additional details in the language reference on how |
Attaching a documentation patch for the moment until I get some info Once I get my local doc build working again, I'll check the formatting |
Committed for 2.6 as r65487. I also blocked the automatic merge to 3.0 since the references to |
But don't the docs with patch describe the behavior of new-style classes |
I meant to say that I will be merging it manually to avoid bringing the |
Ah, I'm sorry for the noise then. |
Docs updated for 3.0 in r66084 (and I was right in thinking the Closing this issue after a mere 5 years and 9 months - any requests for |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: