Python currently requires that all decorators consist of a dotted name, optionally followed by a single call. This PEP proposes removing these limitations and allowing decorators to be any valid expression.

When decorators were first being introduced, Guido described the motivation to limit their syntax as a preference, not a technical requirement:

I have a gut feeling about this one. I'm not sure where it comes from, but I have it... So while it would be quite easy to change the syntax to @test in the future, I'd like to stick to with the more restricted form unless a real use case is presented where allowing @test would increase readability.

While these limitations were rarely encountered in practice, BPO issues and mailing list posts have consistently surfaced over the years requesting that they be removed. The most recent one (which prompted this proposal) contained a good example of code using the PyQt5 library that would become more readable, idiomatic, and maintainable if the existing restrictions were relaxed. Slightly modified:

buttons = [QPushButton(f'Button {i}') for i in range(10)] # Do stuff with the list of buttons... @buttons[0].clicked.connect def spam(): ... @buttons[1].clicked.connect def eggs(): ... # Do stuff with the list of buttons...

Currently, these decorations must be rewritten as something like:

button_0 = buttons[0] @button_0.clicked.connect def spam(): ... button_1 = buttons[1] @button_1.clicked.connect def eggs(): ...

Further, the current grammar is already loose enough that it's trivial to hack more complicated decorator expressions together. So rather than disallow arbitrarily complex expressions, as intended, the current restrictions only make them uglier and less efficient:

# Identity function hack: def _(x): return x @_(buttons[0].clicked.connect) def spam(): ... # eval hack: @eval("buttons[1].clicked.connect") def eggs(): ...