Skip to content

Commit 99c3f74

Browse files
committed
compile: make decorators for functions work
1 parent 7686a57 commit 99c3f74

File tree

3 files changed

+143
-0
lines changed

3 files changed

+143
-0
lines changed

compile/compile.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,10 +459,21 @@ func (c *compiler) compileFunc(Ast ast.Ast, Args *ast.Arguments, DecoratorList [
459459
c.LoadConst(annotations)
460460
}
461461

462+
// Load decorators onto stack
463+
for _, expr := range DecoratorList {
464+
c.Expr(expr)
465+
}
466+
467+
// Make function or closure, leaving it on the stack
462468
posdefaults := uint32(len(Args.Defaults))
463469
kwdefaults := uint32(len(Args.KwDefaults))
464470
args := uint32(posdefaults + (kwdefaults << 8) + (num_annotations << 16))
465471
c.makeClosure(code, args, newC)
472+
473+
// Call decorators
474+
for _ = range DecoratorList {
475+
c.OpArg(vm.CALL_FUNCTION, 1) // 1 positional, 0 keyword pair
476+
}
466477
}
467478

468479
// Compile statement

compile/compile_data_test.go

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2576,4 +2576,119 @@ var compileTestData = []struct {
25762576
Firstlineno: 1,
25772577
Lnotab: "",
25782578
}, nil, ""},
2579+
{"@wrap\ndef fn(o):\n return o", "exec", &py.Code{
2580+
Argcount: 0,
2581+
Kwonlyargcount: 0,
2582+
Nlocals: 0,
2583+
Stacksize: 3,
2584+
Flags: 64,
2585+
Code: "\x65\x00\x00\x64\x00\x00\x64\x01\x00\x84\x00\x00\x83\x01\x00\x5a\x01\x00\x64\x02\x00\x53",
2586+
Consts: []py.Object{&py.Code{
2587+
Argcount: 1,
2588+
Kwonlyargcount: 0,
2589+
Nlocals: 1,
2590+
Stacksize: 1,
2591+
Flags: 67,
2592+
Code: "\x7c\x00\x00\x53",
2593+
Consts: []py.Object{py.None},
2594+
Names: []string{},
2595+
Varnames: []string{"o"},
2596+
Freevars: []string{},
2597+
Cellvars: []string{},
2598+
Filename: "<string>",
2599+
Name: "fn",
2600+
Firstlineno: 1,
2601+
Lnotab: "\x00\x02",
2602+
}, py.String("fn"), py.None},
2603+
Names: []string{"wrap", "fn"},
2604+
Varnames: []string{},
2605+
Freevars: []string{},
2606+
Cellvars: []string{},
2607+
Filename: "<string>",
2608+
Name: "<module>",
2609+
Firstlineno: 1,
2610+
Lnotab: "",
2611+
}, nil, ""},
2612+
{"@wrap1\n@wrap2(\"potato\", 2)\n@wrap3(\"sausage\")\n@wrap4\ndef fn(o):\n return o", "exec", &py.Code{
2613+
Argcount: 0,
2614+
Kwonlyargcount: 0,
2615+
Nlocals: 0,
2616+
Stacksize: 6,
2617+
Flags: 64,
2618+
Code: "\x65\x00\x00\x65\x01\x00\x64\x00\x00\x64\x01\x00\x83\x02\x00\x65\x02\x00\x64\x02\x00\x83\x01\x00\x65\x03\x00\x64\x03\x00\x64\x04\x00\x84\x00\x00\x83\x01\x00\x83\x01\x00\x83\x01\x00\x83\x01\x00\x5a\x04\x00\x64\x05\x00\x53",
2619+
Consts: []py.Object{py.String("potato"), py.Int(2), py.String("sausage"), &py.Code{
2620+
Argcount: 1,
2621+
Kwonlyargcount: 0,
2622+
Nlocals: 1,
2623+
Stacksize: 1,
2624+
Flags: 67,
2625+
Code: "\x7c\x00\x00\x53",
2626+
Consts: []py.Object{py.None},
2627+
Names: []string{},
2628+
Varnames: []string{"o"},
2629+
Freevars: []string{},
2630+
Cellvars: []string{},
2631+
Filename: "<string>",
2632+
Name: "fn",
2633+
Firstlineno: 1,
2634+
Lnotab: "\x00\x05",
2635+
}, py.String("fn"), py.None},
2636+
Names: []string{"wrap1", "wrap2", "wrap3", "wrap4", "fn"},
2637+
Varnames: []string{},
2638+
Freevars: []string{},
2639+
Cellvars: []string{},
2640+
Filename: "<string>",
2641+
Name: "<module>",
2642+
Firstlineno: 1,
2643+
Lnotab: "\x03\x01\x0c\x01\x09\x01",
2644+
}, nil, ""},
2645+
{"def outer(o):\n @wrap1\n @wrap2(\"potato\", o)\n def inner(i):\n return o+i", "exec", &py.Code{
2646+
Argcount: 0,
2647+
Kwonlyargcount: 0,
2648+
Nlocals: 0,
2649+
Stacksize: 2,
2650+
Flags: 64,
2651+
Code: "\x64\x00\x00\x64\x01\x00\x84\x00\x00\x5a\x00\x00\x64\x02\x00\x53",
2652+
Consts: []py.Object{&py.Code{
2653+
Argcount: 1,
2654+
Kwonlyargcount: 0,
2655+
Nlocals: 2,
2656+
Stacksize: 5,
2657+
Flags: 3,
2658+
Code: "\x74\x00\x00\x74\x01\x00\x64\x01\x00\x88\x00\x00\x83\x02\x00\x87\x00\x00\x66\x01\x00\x64\x02\x00\x64\x03\x00\x86\x00\x00\x83\x01\x00\x83\x01\x00\x7d\x01\x00\x64\x00\x00\x53",
2659+
Consts: []py.Object{py.None, py.String("potato"), &py.Code{
2660+
Argcount: 1,
2661+
Kwonlyargcount: 0,
2662+
Nlocals: 1,
2663+
Stacksize: 2,
2664+
Flags: 19,
2665+
Code: "\x88\x00\x00\x7c\x00\x00\x17\x53",
2666+
Consts: []py.Object{py.None},
2667+
Names: []string{},
2668+
Varnames: []string{"i"},
2669+
Freevars: []string{"o"},
2670+
Cellvars: []string{},
2671+
Filename: "<string>",
2672+
Name: "inner",
2673+
Firstlineno: 2,
2674+
Lnotab: "\x00\x03",
2675+
}, py.String("outer.<locals>.inner")},
2676+
Names: []string{"wrap1", "wrap2"},
2677+
Varnames: []string{"o", "inner"},
2678+
Freevars: []string{},
2679+
Cellvars: []string{"o"},
2680+
Filename: "<string>",
2681+
Name: "outer",
2682+
Firstlineno: 1,
2683+
Lnotab: "\x00\x01\x03\x01",
2684+
}, py.String("outer"), py.None},
2685+
Names: []string{"outer"},
2686+
Varnames: []string{},
2687+
Freevars: []string{},
2688+
Cellvars: []string{},
2689+
Filename: "<string>",
2690+
Name: "<module>",
2691+
Firstlineno: 1,
2692+
Lnotab: "",
2693+
}, nil, ""},
25792694
}

compile/make_compile_test.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,23 @@ def inner2(s):
193193
def outer(o):
194194
x = 17
195195
return lambda a,b=42,*args,**kw: a*b*args*kw*x*o''', "exec"),
196+
('''\
197+
@wrap
198+
def fn(o):
199+
return o''', "exec"),
200+
('''\
201+
@wrap1
202+
@wrap2("potato", 2)
203+
@wrap3("sausage")
204+
@wrap4
205+
def fn(o):
206+
return o''', "exec"),
207+
('''\
208+
def outer(o):
209+
@wrap1
210+
@wrap2("potato", o)
211+
def inner(i):
212+
return o+i''', "exec"),
196213
]
197214

198215
def string(s):

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy