[Python-Dev] Decorator order implemented backwards?

Phillip J. Eby pje at telecommunity.com
Tue Aug 17 18:52:59 CEST 2004


At 09:40 AM 8/17/04 -0700, Michael Chermside wrote:
>Mark writes:
> > Your patch results in the evaluation order:
> >
> >     evalname1 evalargs1 makedec1
> >     evalname2 evalargs2 makedec2
> >     evalname3 evalargs3 makedec3
> >     calldec3 calldec2 calldec1
> >
> > Mine (#1009560) gives:
> >
> >     evalname3 evalargs3 makedec3 calldec3
> >     evalname2 evalargs2 makedec2 calldec2
> >     evalname1 evalargs1 makedec1 calldec1
>
>Guido writes:
> > Since Mark ended up agreeing with your order, the OK is given by
> > default. :-)
>
>Wait... I'm confused. What was the final decision? I favor
>
>      evalname1 evalargs1 makedec1
>      evalname2 evalargs2 makedec2
>      evalname3 evalargs3 makedec3
>      calldec3 calldec2 calldec1
>
>becase of left-to-right-top-to-bottom evaluation. Is this what it
>actually does? I imagine this:

Hm.  Consider this code:

     func = a(b)(c(d)(e(func)))

Per the PEP, it's the equivalent of:

     @a(b)
     @c(d)
     @e
     def func(...):
         ...

Here's an annotated disassembly:

 >>> dis.dis(lambda: a(b)(c(d)(e(func))))
           0 SET_LINENO               1
           3 LOAD_GLOBAL              0 (a)  #evalname1
           6 LOAD_GLOBAL              1 (b)  #evalargs1
           9 CALL_FUNCTION            1      #makedec1
          12 LOAD_GLOBAL              2 (c)  #evalname2
          15 LOAD_GLOBAL              3 (d)  #evalargs2
          18 CALL_FUNCTION            1      #makedec2
          21 LOAD_GLOBAL              4 (e)  #evalname3
          24 LOAD_GLOBAL              5 (func)#defun
          27 CALL_FUNCTION            1       #calldec3
          30 CALL_FUNCTION            1       #calldec2
          33 CALL_FUNCTION            1       #calldec1
          36 RETURN_VALUE

Therefore, this is the evaluation order currently prescribed by the PEP.



More information about the Python-Dev mailing list