Hey everyone, I came across a case which *might* be a use case for a syntax extension, but I'm not sure. Wanted to get feedback from the group.
*The extension: *Extend the decorator syntax from decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE to decorator ::= "@" expression NEWLINE where the expression must return a callable that accepts a function of the indicated signature as its argument. *The motivating case: *I'm using function decorators to define cron jobs in my system, with the rather nice syntax "@cronJob(parameters) def myFunction(standard args)". The decorator registers the function, this causes all sorts of magic to occur, and out the other end of the pipe jobs run in production. It's working very nicely. However, we'd like to improve the syntax to allow different cron configurations for the job in different production environments. Since the default-plus-overrides model is natural for the actual use cases, a nice way to do this would be to replace the cronJob function with a class whose __init__ and __call__ methods respectively load up the parameters and do the actual work of registration, but which also has an override() method that lets you specify per-environment overrides and then returns self. This would allow a syntax like: @CronJob('job-name', params...).override('dev', more-params...) def myFunction(...) However, this is invalid syntax in Python 3.8 because you can't have a general expression in a decorator statement. Instead, the nearest option is myJob = CronJob('job-name', params...).override('dev', more-params...) @myJob def myFunction(...) Which is uglier for no obvious benefit. *Possible pros and cons: * This extends the existing syntax in a way that's very intuitive w.r.t. the current one -- the docs say "A function definition may be wrapped by one or more decorator expressions. Decorator expressions are evaluated when the function is defined, in the scope that contains the function definition. The result must be a callable, which is invoked with the function object as the only argument. The returned value is bound to the function name instead of the function object. Multiple decorators are applied in nested fashion." It's not obvious from the syntax why the decorator expression *needs* to have this limited form. It increases consistency, by eliminating this one unusual use of dotted expressions as special relative to other expressions. (NB this is the only call to ast_for_dotted_expr in ast.c!) The meaning of the operation remains unambiguous, and is just as accessible to tools like linters, type checkers, and syntax highlighters, as the @ operator simply modifies the succeeding expression. On the downside, it's more flexible, and so offers more chances for a user to shoot themselves in the foot. It's somewhat of a corner case, so it's not obvious that the syntax extension is worth it. What do people think?
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/ECOVHGZKRMCFD2JWFCOKGY2LZJAJTH4E/ Code of Conduct: http://python.org/psf/codeofconduct/