New submission from Sylvain Marie <sylvain.ma...@schneider-electric.com>:

Python decorators are frequently proposed by libraries as an easy way to add 
functionality to user-written functions: see `attrs`, `pytest`, `click`, 
`marshmallow`, etc.

A common pattern in most such libraries, is that they do not want to provide 
users with two different symbols for the same function. So they end up 
implementing decorators that can be used both as decorators (no arguments no 
parenthesis) AND decorator factories (arguments in parenthesis). This is 
convenient and intuitive for users. Unfortunately this is not something trivial 
to implement because the python language does not make any difference between a 
no-parenthesis decorator call and a with-parenthesis decorator factory call.

So these libraries have to rely on "tricks", the most common one being to check 
existence of a non-default first parameter that is a callable.

Examples: 

https://github.com/python-attrs/attrs/blob/c2a9dd8e113a0dc72f86490e330f25bc0111971a/src/attr/_make.py#L940

https://github.com/pytest-dev/pytest/blob/13a9d876f74f17907ad04b13132cbd4aa4ad5842/src/_pytest/fixtures.py#L1041

https://github.com/marshmallow-code/marshmallow/blob/ec51dff98999f2189a255fb8bbc22e549e3cc673/src/marshmallow/decorators.py#L161

Implementing these tricks is a bit ugly, but more importantly it is a waste of 
development time because when one changes his decorators signatures, the trick 
has to possibly be changed (order of arguments, default values, etc). Therefore 
it is quite a brake to agile development in the first phase of a project, where 
the api is not very stable.

I regrouped all known and possible tricks in a library 
https://github.com/smarie/python-decopatch/ to provide a handy way to solve 
this problem. But it is still "a bunch of tricks". This library, or the manual 
implementations such as the examples above, could be much faster/efficient if 
there were at least, a way to determine if a frame is a call to `@`.

So this is a request to at least have a `inspect.is_decorator_call(frame)` 
feature in the stdlib. That function would return `True` if the frame is a 
decorator call using `@`.

Note that a more convenient way to solve this problem is also proposed in 
https://smarie.github.io/python-decopatch/pep_proposal/#2-preserving-backwards-compatibility
 : it would be to offer a `@decorator_factory` helper in the stdlib. But first 
feedback from python-ideas mailing list showed that this was maybe too 
disruptive :)

----------
components: Library (Lib)
messages: 339599
nosy: smarie
priority: normal
severity: normal
status: open
title: inspect.is_decorator_call(frame)
type: enhancement

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue36553>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to