<div dir="ltr"><div class="gmail_default" style="font-family:trebuchet ms,sans-serif">__add__ as a property/descriptor seems to work fine, eg:<br><br><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">>>> class C:<br>...  @property<br>...  def __add__(self):<br>...   return lambda other: [self, other]<br>...<br>>>> C() + C()<br>[<__main__.C object at 0x0000000003652AC8>, <__main__.C object at 0x0000000003652CC0>]<br></blockquote><div><br></div><div>Am I missing something? <br></div></div></div><div class="gmail_extra"><br clear="all"><div><div class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div><span style="font-family:trebuchet ms,sans-serif"><span style="color:rgb(51,51,51)"><br><font size="2"><span style="color:rgb(51,51,51)">Thanks,</span><br><span style="color:rgb(153,153,153)">-- Ionel</span></font></span><font size="2"><font style="color:rgb(153,153,153)"> Cristian Mărieș, <a href="http://blog.ionelmc.ro" target="_blank">http://blog.ionelmc.ro</a><br></font></font></span></div></div></div></div></div></div></div>
<br><div class="gmail_quote">On Sat, Apr 18, 2015 at 12:15 AM, Guido van Rossum <span dir="ltr"><<a href="mailto:guido@python.org" target="_blank">guido@python.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>You won't have any more luck defining __add__ as a property -- just don't do that.<br><br></div>On how to implement a proxy, I'll let other explain. But this is not it.<br></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Apr 17, 2015 at 2:04 PM, Ionel Cristian Mărieș <span dir="ltr"><<a href="mailto:contact@ionelmc.ro" target="_blank">contact@ionelmc.ro</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_default" style="font-family:trebuchet ms,sans-serif">Well yes, from that example it look right, because the call operator uses the __call__ attribute from the type of the object. However, when the call operator gets the __call__ method it will actually use it as a descriptor. From that perspective it's inconsistent.<br><br></div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif">Also there's the issue about not being able to implement a true proxy (as outlined before).<br><br></div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif">What actually prevents this being fixed?<br></div></div><div class="gmail_extra"><span><br clear="all"><div><div><div dir="ltr"><div><div dir="ltr"><div><div><span style="font-family:trebuchet ms,sans-serif"><span style="color:rgb(51,51,51)"><br><font size="2"><span style="color:rgb(51,51,51)">Thanks,</span><br><span style="color:rgb(153,153,153)">-- Ionel</span></font></span><font size="2"><font style="color:rgb(153,153,153)"> Cristian Mărieș, <a href="http://blog.ionelmc.ro" target="_blank">http://blog.ionelmc.ro</a><br></font></font></span></div></div></div></div></div></div></div>
<br></span><div><div><div class="gmail_quote">On Fri, Apr 17, 2015 at 11:55 PM, Guido van Rossum <span dir="ltr"><<a href="mailto:guido@python.org" target="_blank">guido@python.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">I think you're fighting windmills. Like most special operations (e.g. __add__), a __call__ attribute on the object does not work, i.e. it does not make the object callable. E.g.<br><br>$ python3<br>Python 3.5.0a2 (v3.5.0a2:0337bd7ebcb6, Mar  8 2015, 01:12:06) <br>[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin<span><br>Type "help", "copyright", "credits" or "license" for more information.<br></span>>>> class C: pass<br>... <br>>>> c = C()<br>>>> c.__call__ = lambda *a: a<br>>>> c()<span><br>Traceback (most recent call last):<br>  File "<stdin>", line 1, in <module><br></span>TypeError: 'C' object is not callable<br>>>> callable(c)<br>False<br>>>> hasattr(c, '__call__')<br>True<br>>>> <br></div><div class="gmail_extra"><br><div class="gmail_quote"><div><div>On Fri, Apr 17, 2015 at 1:45 PM, Ionel Cristian Mărieș <span dir="ltr"><<a href="mailto:contact@ionelmc.ro" target="_blank">contact@ionelmc.ro</a>></span> wrote:<br></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><div dir="ltr"><div class="gmail_default" style="font-family:trebuchet ms,sans-serif">Hello,<br><br></div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif">I had an issue today with the `callable` builtin because it doesn't correctly check that the object has the __call__ attribute. <br><br></div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif">Effectively what `callable(a)` does is `hasattr(type(a), '__call__')` but that's not very straightforward. A more straightforward implementation would do something like `hasattr(a, '__call__')`.<br><br></div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif">For example:<br><br><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:44:40) [MSC v.1600 64 bit (AMD64)] on win32<br>Type "help", "copyright", "credits" or "license" for more information.<br>>>> callable<br><built-in function callable><br>>>> class A:<br>...  @property<br>...  def __call__(self):<br>...   raise AttributeError('go away')<br>...<br>>>> a = A()<br>>>> a<br><__main__.A object at 0x000000000365B5C0><br>>>> a.__call__<br>Traceback (most recent call last):<br>  File "<stdin>", line 1, in <module><br>  File "<stdin>", line 4, in __call__<br>AttributeError: go away<br>>>> callable(a)<br>True<br>>>> # it should be False :(<br></blockquote></div><div><div><div dir="ltr"><div><div dir="ltr"><div><div><span style="font-family:trebuchet ms,sans-serif"><span style="color:rgb(51,51,51)"><br><div class="gmail_default" style="font-family:trebuchet ms,sans-serif;display:inline">​So it boils down to this:<br><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">>>> hasattr(a, "__call__")<br>False<br>>>> hasattr(type(a), "__call__")<br>True</blockquote><div><br></div><div>My issue is that I didn't call `callable(type(a))` but just `callable(a)`. Clearly mismatching what happens when you do hasattr(a, "__call__").<br><br></div><div>To put in contrast, this is legal and clearly indicates the descriptors are being used as expected:<br><br><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">>>> class B:<br>...  @property<br>...  def __call__(self):<br>...   return lambda: 1<br>...<br>>>> b = B()<br>>>> b()<br>1<br></blockquote></div></div></span></span><span style="font-family:trebuchet ms,sans-serif"><span style="color:rgb(51,51,51)"><br><div class="gmail_default" style="font-family:trebuchet ms,sans-serif;display:inline">​There​</div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif;display:inline">​'s some more discussing in <a href="http://bugs.python.org/issue23990" target="_blank">issue <span style="font-family:trebuchet ms,sans-serif"><span style="color:rgb(51,51,51)">23990</span></span></a>​</div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif;display:inline">​ where I get slightly angry, sorry.​</div><br><br><div class="gmail_default" style="font-family:trebuchet ms,sans-serif;display:inline">​So were is this change actually useful? Proxies! Since new-style objects in Python you cannot really proxy the callable aspect of objects, because `callable` just checks that a field is set in a C struct.​</div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif;display:inline">​ This is fairly inconvenient because you have to know upfront if your target is going to be callable or not.​</div><br><br><br><font size="2"><span style="color:rgb(51,51,51)">Thanks,</span><br><span style="color:rgb(153,153,153)">-- Ionel</span></font></span><font size="2"><font style="color:rgb(153,153,153)"> Cristian Mărieș, <a href="http://blog.ionelmc.ro" target="_blank">http://blog.ionelmc.ro</a><br></font></font></span></div></div></div></div></div></div></div>
</div>
<br></div></div>_______________________________________________<br>
Python-ideas mailing list<br>
<a href="mailto:Python-ideas@python.org" target="_blank">Python-ideas@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-ideas" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a><br>
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" target="_blank">http://python.org/psf/codeofconduct/</a><span><font color="#888888"><br></font></span></blockquote></div><span><font color="#888888"><br><br clear="all"><br>-- <br><div>--Guido van Rossum (<a href="http://python.org/~guido" target="_blank">python.org/~guido</a>)</div>
</font></span></div>
</blockquote></div><br></div></div></div>
</blockquote></div><br><br clear="all"><br>-- <br><div>--Guido van Rossum (<a href="http://python.org/~guido" target="_blank">python.org/~guido</a>)</div>
</div>
</div></div></blockquote></div><br></div>