Skip to content Skip to sidebar Skip to footer

Python Decorator @func().attribute Syntax Error

I tried to find an answer here, but could not. @obj.func # works @obj.func(**kwargs) #works @obj.func1(**kwargs).func2 #-> syntax error I do not understand why the third fo

Solution 1:

The Function definitions grammar does not allow for calls with further dotted names; the syntax is limited to dotted names and an optional call at the end:

decorated      ::=  decorators (classdef | funcdef)
decorators     ::=  decorator+
decorator      ::=  "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE
funcdef        ::=  "def" funcname "(" [parameter_list] ")"":" suite
dotted_name    ::=  identifier ("." identifier)*

Note that that's not a full expression, but a very limited subset.

This echoes the PEP, which states:

The decorator statement is limited in what it can accept -- arbitrary expressions will not work. Guido preferred this because of a gut feeling [17] .

and

The rationale for having a function that returns a decorator is that the part after the @ sign can be considered to be an expression (though syntactically restricted to just a function), and whatever that expression returns is called. See declaration arguments [16] .

Emphasis mine.

The rationale is that Guido feels there isn't a real use case for allowing more:

So while it would be quite easy to change the syntax to @test in the future, I'd like to stick with the more restricted form unless a real use case is presented where allowing @test would increase readability. (@foo().bar() doesn't count because I don't expect you'll ever need that).

You'll have to convince Guido and the other core developers that your case is a proper usecase worthy of lifting these restrictions!

Solution 2:

As explained in the other answer, Guido had a "gut feeling" was the reason for the restriction originally.

This restriction is lifted in Python 3.9., allowing decorators to be any valid expression.

Previously, the grammar for decorators was:

decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE

In Python 3.9 the grammar is simplified to:

decorator:'@' namedexpr_test NEWLINE

This is the only grammar change between 3.8 and 3.9. See PEP 614 -- Relaxing Grammar Restrictions On Decorators for full details.

Post a Comment for "Python Decorator @func().attribute Syntax Error"