On 07.06.2016 21:49, Nick Coghlan wrote:
On 7 June 2016 at 11:29, M.-A. Lemburg mal@egenix.com wrote:
One approach would be to define what a decorator means in front of an expression (since that's currently a SyntaxError), without adding any new syntactic sugar. Here's a sketch...
@decorator x = obj
compiles to:
x = obj decorator('x', obj, lineno)
As a possible guide to designing the signatures for binding decorators, it's probably worth asking what would be needed to make:
@bindfunction f = lambda : None
equivalent to:
def f(): pass
Since the interpreter already sets __module__ and __globals__ correctly on lambda functions, the main considerations would be to get f.__name__ and f.__qualname__ set correctly, which means just the immediate target would be insufficient - you'd also want the scope naming information that gets included in __qualname__, but is omitted from __name__.
Well, in your example it would still be enough:
f = lambda : None f.__qualname__
'<lambda>'
f.__name__
'<lambda>'
def f(): pass
...
f.__qualname__
'f'
f.__name__
'f'
and even at deeper levels, you could base the new .__qualname__ on the one that is set on the lambda function:
class C:
... f = lambda : None ...
C.f
<function C.<lambda> at 0x7f5f838736a8>
C.f.__qualname__
'C.<lambda>'
C.f.__name__
'<lambda>'
The .__qualname__ is set at the time the lambda is built, so it is known even correct after making the assignment in the class definition:
class C:
... f = lambda : None ... print(f.__qualname__) ... C.<lambda>
so I guess this all works - much to my own surprise, because I wouldn't have expected e.g. the last experiment to actually succeed. Someone did a good job there :-)