
Another problem I have with this proposal is the new dunder method. Why do we need a new dunder? We're probably never going to "decorate" a variable and function with the same callable, the two use-cases are very different. But even if we do, we can easily distinguish the two cases. Let's dump the `__decorate_call__` dunder and just use normal call syntax. That will be a HUGE win for useability: any function, class or callable object can be used as the decorator, it doesn't have to be a custom object with a custom class that defines a special dunder. We can distinguish the two contexts by using different signatures. The signature used depends entirely on the call site, not the decorator, so it is easy for the interpreter to deal with. If the decorator is called on a function or class statement, a single argument is always passed, no exceptions: # always calls decorate with one argument @decorate def func(): # or class pass # --> func = decorate(func) If called on a variable, the number of arguments depends on whether it is a bare name, or a value and annotation are provided. There are exactly four cases: # bare name @decorate var # --> var = decorate('var') # name with annotation @decorate var: annot # --> var = decorate('var', annotation=annot) # name bound to value @decorate var = x # --> var = decorate('var', value=x) # name with annotation and value @decorate var: annot = x # --> var = decorate('var', annotation=annot, value=x) Keyword arguments are used because one or both of the value and the annotation may be completely missing. The decorator can either provide default values or collect keyword arguments with `**kwargs`. The only slightly awkward case is the bare variable case. Most of the time there will be no overlap between the function/class decorators and the bare variable decorator, but in the rare case that we need to use a single function in both cases, we can easily distinguish the two cases: def mydecorator(arg, **kwargs): if isinstance(arg, str): # must be decorating a variable ... else: # decorating a function or class assert kwarg == {} So it is easy to handle both uses in a single function, but I emphasise that this would be rare. Normally a single decorator would be used in the function/class case, or the variable case, but not both. -- Steve