On Sunday, 8 June 2014 18:24:28 UTC+1, Ian  wrote:
> But that would all be done in getattr, so I don't think it affects
> hasattr's implementation at all.  Since hasattr doesn't push anything
> onto the stack, getattr doesn't have to care whether it was called
> directly from Python or indirectly via getattr; either way the scope
> it needs is just the top frame of the stack.
> Could be a different matter in other implementations, though.

In CPython, the UFCS would not be done in PyObject_GetAttr() as that would 
affect hasattr() as well. Instead, it would be implemented in the bytecode for 
LOAD_ATTR. If LOAD_ATTR was about to return an AttributeError, e.g. for [].len, 
it would perform the equivalent of a LOAD_NAME operation, with the difference 
that if the name is not found or is not callable, it returns AttributeError 
instead of NameError.

If the name is found, then it would return something: for [].len, it would 
return the len() function wrapped to know that it's first argument was the 
list, which might be done by creating a fake Method object, as shown in Ian's 

But getattr([], 'len') and hasattr([], 'len') would both return False.

I'm beginning to think it is too un-Pythonic - too much implicitness, unless it 
can be spelt differently, something like [].len(_) or [].len(...) to explicitly 
indicate that it plans to call a function, but might call a method if one is 

Reply via email to