go-python / gpython

gpython is a python interpreter written in go "batteries not included"
BSD 3-Clause "New" or "Revised" License
870 stars 95 forks source link

Annotating types with decorators crashes gpython #203

Open xiaxinmeng opened 1 year ago

xiaxinmeng commented 1 year ago

In the following, we define a class, in this class, we define a decorated function with annotated types "str" that is not consistent with "None. Then gpython crashes. We test the example on the online gpython Go/wasm and Gopherjs provided online.

test.py

class Link(str):
    print_name = None

    @print_name
    def friendly_name(self) -> str:
        return self.print_name or self

Output on GO/wasm(https://gpython.org/?wasm):

>>> class Link(str):
...     print_name = None
...     @print_name
...     def friendly_name(self) -> str:
...         return self.print_name or self
... 
panic: interface conversion: py.Object is py.NoneType, not py.Tuple
goroutine 5 [running]:
github.com/go-python/gpython/vm._make_function(0xc0750a0, 0x8400020000)
    /home/ncw/go/src/github.com/go-python/gpython/vm/eval.go:1445 +0xad
github.com/go-python/gpython/vm.do_MAKE_FUNCTION(0xc0750a0, 0x20000, 0x0, 0x0)
    /home/ncw/go/src/github.com/go-python/gpython/vm/eval.go:1487 +0x2
github.com/go-python/gpython/vm.RunFrame(0xc0d0370, 0x0, 0xc07b3c8, 0x0, 0x0)
    /home/ncw/go/src/github.com/go-python/gpython/vm/eval.go:1785 +0x3f
github.com/go-python/gpython/vm.EvalCodeEx(0xc04c300, 0xc062db0, 0xc063740, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /home/ncw/go/src/github.com/go-python/gpython/vm/eval.go:2162 +0xa3
github.com/go-python/gpython/vm.Run(0xc062db0, 0xc063740, 0xc04c300, 0x0, 0x0, 0x0, 0x0, 0x3733a8, 0xc04bfe0, 0x20de0)
    /home/ncw/go/src/github.com/go-python/gpython/vm/eval.go:2182 +0x2
github.com/go-python/gpython/builtin.builtin___build_class__(0x9d720, 0x3661e8, 0xc09aa50, 0x3, 0x3, 0xc0636e0, 0x3, 0x1f, 0x10890011, 0x341070)
    /home/ncw/go/src/github.com/go-python/gpython/builtin/builtin.go:409 +0x21
github.com/go-python/gpython/py.(*Method).Call(0xc02ab40, 0x9d720, 0x3661e8, 0xc09aa50, 0x3, 0x3, 0x109b0006, 0x3d320, 0x51e80, 0x10b10001)
    /home/ncw/go/src/github.com/go-python/gpython/py/method.go:138 +0x12
github.com/go-python/gpython/py.(*Method).M__call__(0xc02ab40, 0xc09aa50, 0x3, 0x3, 0x0, 0x13200001, 0x36a400, 0x34b507, 0x10b2004f)
    /home/ncw/go/src/github.com/go-python/gpython/py/method.go:238 +0x5
github.com/go-python/gpython/py.Call(0x9d360, 0xc02ab40, 0xc09aa50, 0x3, 0x3, 0x0, 0x20, 0x2b4a0, 0x34b500, 0x6002c932001)
    /home/ncw/go/src/github.com/go-python/gpython/py/internal.go:169 +0x5
github.com/go-python/gpython/vm.callInternal(0x9d360, 0xc02ab40, 0xc09aa50, 0x3, 0x3, 0x0, 0xc0d0210, 0x4bb00, 0x127c0022, 0x10007010c05eee0, ...)
    /home/ncw/go/src/github.com/go-python/gpython/vm/eval.go:1606 +0xd
github.com/go-python/gpython/vm.(*Vm).Call(0xc075030, 0x3, 0x0, 0x0, 0x0, 0x0, 0xc075030, 0x8400000000)
    /home/ncw/go/src/github.com/go-python/gpython/vm/eval.go:1689 +0x4e
github.com/go-python/gpython/vm.do_CALL_FUNCTION(0xc075030, 0x3, 0x0, 0x0)
    /home/ncw/go/src/github.com/go-python/gpython/vm/eval.go:1428 +0x2
github.com/go-python/gpython/vm.RunFrame(0xc0d0210, 0x0, 0xc07bd18, 0x0, 0x0)
    /home/ncw/go/src/github.com/go-python/gpython/vm/eval.go:1785 +0x3f
github.com/go-python/gpython/vm.EvalCodeEx(0xc04c200, 0xc062db0, 0xc062db0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /home/ncw/go/src/github.com/go-python/gpython/vm/eval.go:2162 +0xa3
github.com/go-python/gpython/vm.Run(0xc062db0, 0xc062db0, 0xc04c200, 0x0, 0x0, 0x0, 0x0, 0x1, 0x9d240, 0xc04c200)
    /home/ncw/go/src/github.com/go-python/gpython/vm/eval.go:2182 +0x2
github.com/go-python/gpython/repl.(*REPL).Run(0xc09a6c0, 0x0, 0x0)
    /home/ncw/go/src/github.com/go-python/gpython/repl/repl.go:99 +0x20
main.main.func1(0xc01e9e0, 0x2, 0x2)
    /home/ncw/go/src/github.com/go-python/gpython/repl/web/main.go:82 +0x4
syscall/js.callbackLoop()
    /opt/go/go1.11/src/syscall/js/callback.go:116 +0x7
created by syscall/js.NewCallback.func1
    /opt/go/go1.11/src/syscall/js/callback.go:40 +0x2
...

 

Output on Gopherjs (https://gpython.org/)

Gpython 3.4.0 running in your browser with gopherjs
>>> class Link(str):
...     print_name = None
...     @print_name
...     def friendly_name(self) -> str:
...         return self.print_name or self
... 
[USER]: https://gpython.org/gpython.js: interface conversion: interface is py.NoneType, not py.Tuple
$callDeferred@https://gpython.org/gpython.js:4:22511
$panic@https://gpython.org/gpython.js:4:22957
$assertType@https://gpython.org/gpython.js:4:21361
DD@https://gpython.org/gpython.js:44:77578
DE@https://gpython.org/gpython.js:44:78498
DO@https://gpython.org/gpython.js:44:91592
DU@https://gpython.org/gpython.js:44:107450
DW@https://gpython.org/gpython.js:44:109015
L@https://gpython.org/gpython.js:54:25394
GL.ptr.prototype.Call@https://gpython.org/gpython.js:41:292240
GL.ptr.prototype.M__call__@https://gpython.org/gpython.js:41:301617
FK@https://gpython.org/gpython.js:41:255589
DN@https://gpython.org/gpython.js:44:82459
EE.ptr.prototype.Call@https://gpython.org/gpython.js:44:87109
DC@https://gpython.org/gpython.js:44:77098
DO@https://gpython.org/gpython.js:44:91592
DU@https://gpython.org/gpython.js:44:107450
DW@https://gpython.org/gpython.js:44:109015
G.ptr.prototype.Run@https://gpython.org/gpython.js:56:3575
$b@https://gpython.org/gpython.js:60:3908
$b@https://gpython.org/gpython.js:59:2625
r@https://gpython.org/gpython.js:4:23443
$runScheduled@https://gpython.org/gpython.js:4:24007
$schedule@https://gpython.org/gpython.js:4:24184
$go@https://gpython.org/gpython.js:4:23907
I/$packages["github.com/gopherjs/gopherwasm/js"]<@https://gpython.org/gpython.js:59:2240
$externalizeFunction/e.$externalizeWrapper@https://gpython.org/gpython.js:4:28925
a@https://cdnjs.cloudflare.com/ajax/libs/jquery.terminal/1.23.2/js/jquery.terminal.min.js:40:82615
k@https://cdnjs.cloudflare.com/ajax/libs/jquery.terminal/1.23.2/js/jquery.terminal.min.js:40:83463
ENTER@https://cdnjs.cloudflare.com/ajax/libs/jquery.terminal/1.23.2/js/jquery.terminal.min.js:40:14915
$e@https://cdnjs.cloudflare.com/ajax/libs/jquery.terminal/1.23.2/js/jquery.terminal.min.js:40:28362
dispatch@https://code.jquery.com/jquery-latest.js:4641:9
add/elemData.handle@https://code.jquery.com/jquery-latest.js:4309:28
...
ncw commented 1 year ago

I can confirm this bug in gpython master.

This is due to an unchecked type assertion here

https://github.com/go-python/gpython/blob/6f8e06a4660709ab44398d8b1a18738aa407b1c3/vm/eval.go#L1445

Looks easy to fix if you want to have a go @xiaxinmeng ?