On 07.06.2016 01:20, Guido van Rossum wrote:
On Mon, Jun 6, 2016 at 4:14 PM, Barry Warsaw email@example.com wrote:
On Jun 07, 2016, at 12:53 AM, M.-A. Lemburg wrote:
This would work as well and indeed reads better, but you'd need to have the compiler generate:
x = obj recordbinding(obj, 'x', 2)
ie. pass in the object, the bound name and the line number and recordbinding would then have to decide what to do with the parameters.
+1 although I'd bikeshed on the order of the arguments.
I used the method variant, because a very common use case is to let the object know about the name under which it is now known to Python. This can be used to eg. define records, forms, mappings, etc.
Yep. So given the above, `recordbinding(obj, 'x', 2)` would of course be free to delegate to `obj.recordbinding('x', 2)`, but it would be up to the decorator (and its author), not the compiler to do that delegation.
Right, your approach is more generic.
I just wonder how we could tell the compiler to special case this decorator in a clean way.
That's the rub, but I do think you're on to a good general solution to a common set of problems.
I think we're on to something here. Maybe. Perhaps.
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
x = obj decorator('x', obj, lineno)
(I'm using obj in the calls to decorator here - those would not be new lookups, but instead work using DUP_TOP in the byte code)
Things get a bit tricky when you use tuples on the left hand side:
@decorator a, b, c = obj
a, b, c = obj decorator('a, b, c', obj, lineno)
Not sure whether this would be useful. Perhaps it's better not to allow for such a use.
Same problem for star assignments:
@decorator a, *b, c = obj
Multiple assignments would work, though:
@decorator a = b = c = obj
a = b = c = obj decorator('a', obj, lineno) decorator('b', obj, lineno) decorator('c', obj, lineno)
Augmented assigns are tricky, but would work as well:
@decorator a += obj
a += obj decorator('a', value, lineno)
(here value stands for the result of the += operation; in byte code this would be a DUP_TOP before the STORE_FAST to 'a')
More complex right hand sides should not pose a problem, since it's clear that only the result matters (which is pushed to the stack and can be DUP_TOPed as necessary).
Looking at https://docs.python.org/3/reference/grammar.html, I think those are all cases to consider, unless I missed one.
The grammar would need to be extended with:
""" decorated: decorators (classdef | funcdef | async_funcdef | assign_expr)
assign_expr: NAME (augassign (yield_expr|testlist) | ('=' (yield_expr|assign_expr))*) """
The above disallows testlist or star assignments.