On 21Oct2019 17:18, Yonatan Zunger <zun...@humu.com> wrote:
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.

Personally, I have 2 concerns. 1: this introduces a lot of scope for arbitrary complexity after the @ versus the extremely readable "name(...)" form. 2: I'm not sure what this would to to uses of "@" as an operator, as has been suggested various times for various laudable reasons; remember that an @decorator or other function definition is just another statement, and arbitrary expressions are already statements.

*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.

Maybe a better form, already supported, might be this:

   @CronJob('job-name', params...)
   @cron_override('dev', more-params...)
   def the_function...

i.e. decorate the decorated function. I would choose to write it like the above, even though the decorators run from inside to out, amounting to having @cron_override prepare an environment specific decoration and @CronJob just be the "default for an otherwise unspecified environment" decoration.

No new syntax needed. And it reads nicely, at least to my eye.

You will probably run into some resistance if there's no case for your syntax which can't be addressed with the nested decoration above (or something equivalent - the point here isn't that what I've written above is a great thing (though I like it) but that it requires no new syntax).

Cheers,
Cameron Simpson <c...@cskk.id.au>
_______________________________________________
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/ALXX3W6N5WYSHCQMAPZ3DGBC6EULUQFJ/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to