> Flat is better than nested. I remember being confused a lot when I was learning how to write my first decorator. Now eight years later, with the last two spent full-time writing Python, I introduced a bug in production because I forgot to return the inner function from within a decorator.
By introducing multiple parameter lists when defining a function, Scala does a great job at improving readability for curried functions (https://docs.scala-lang.org/tour/multiple-parameter-lists.html). In Python, that could look like e.g.: def log(level=logging.DEBUG, logger=logging.root)(func)(*args, **kwargs): logger.log(level, 'call: %s', func.__qualname__) return func(*args, **kwargs) Which would be sugar for: def log(level=logging.DEBUG, logger=logging.root): def _log(func): def __log(*args, **kwargs): logger.log(level, 'call: %s', func.__qualname__) return func(*args, **kwargs) return __log return _log The obvious problem in this example, is that `functools.wraps` is missing. One solution would be for me to flex my 8 years of experience, and present these two (super/meta-)decorators: def wraps_decorator(decorator: Callable[[F], F]): @functools.wraps(decorator) def _wraps_decorator(func): return functools.wraps(func)(decorator(func)) return _wraps_decorator @wraps_decorator def wraps_decorator_factory(decorator_factory)(*args, **kwargs): return wraps_decorator(decorator_factory(*args, **kwargs)) Applying the latter on the first example, it becomes @wraps_decorator_factory def log(level=logging.DEBUG, logger=logging.root)(func)(*args, **kwargs): logger.log(level, 'call: %s', func.__qualname__) return func(*args, **kwargs) which is equivalent to: def log(level=logging.DEBUG, logger=logging.root): def _log(func): @functools.wraps(func) def __log(*args, **kwargs): logger.log(level, 'call: %s', func.__qualname__) return func(*args, **kwargs) return __log return _log Implementation-wise, I think it's very feasible since it's only sugar. And I'm sure that the required grammar changes are possible with the shiny new parser. And considering PEP 659, I can imagine that this syntax is beneficial because the closure variables coincide with the parameter lists. _______________________________________________ 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/2HGGXLQGGIUOG2ENLNAAT3YY6GPDD3DF/ Code of Conduct: http://python.org/psf/codeofconduct/