grumpyhome / grumpy

Grumpy is a Python to Go source code transcompiler and runtime.
Apache License 2.0
420 stars 18 forks source link

not all go modules works #150

Open xukku opened 4 years ago

xukku commented 4 years ago

from 'go/math' import Pi print Pi

this works and output

grumpy run test.py 3.14159265359

but this not works


 import "__go__/encoding/hex"
 print hex.Dump('foobar')

output error grumpy run test.py

/tmp/tmp8Y9Chnpycache/gopath/src/python/main/module.go:4:2: cannot find package "python/go/encoding/hex" in any of: /usr/lib/go/src/python/go/encoding/hex (from $GOROOT) /tmp/tmp8Y9Chnpycache/gopath/src/python/go/encoding/hex (from $GOPATH) /home/user/.local/lib/python2.7/site-packages/grumpy_runtime/data/gopath/src/python/go/encoding/hex

Originally posted by @6umpukc-uHKBu3umop in https://github.com/grumpyhome/grumpy/issues/148#issuecomment-569084277

xukku commented 4 years ago

is there any working example

with modules in example https://golang.org/pkg/net/http/

?

alanjds commented 4 years ago

This I never tested but had feedback of being working. For more examples of working code grep __go__ on lib folder.

Examples: This uses lots of Go native modules, including reflection and syscalls

xukku commented 4 years ago

https://github.com/grumpyhome/grumpy/issues/148#issuecomment-569414322

found some go lib wrapers - but not all are implemented

so i should write go file wrapers for other go standart libs manually ? or is there some script for automating this task?

alanjds commented 4 years ago

On https://github.com/grumpyhome/grumpy/blob/master/grumpy-runtime-src/tools/pkgc.go is the code that takes from '__go__/whatever' import Something and automatically creates the glue Go files. You can start looking there.

xukku commented 4 years ago

is the code that takes from 'go/whatever' import Something and automatically creates the glue Go files

so this should work autmatically - then when? or i must run it for preparing wrapper of each go package?

alanjds commented 4 years ago

Yes, it should work automatically. I do not know why is not working in your case.

Let me say that this code is wrote by Google (Youtube mainly) and I just made some maintenance on this exac file.

alanjds commented 4 years ago

so this should work autmatically - then when?

When you grumpy run your files are parsed and transpiled. Imports from __go__ are transpiled as glue I guess. Then all transpiled modules (Py and __go__ imports) are added to GOPATH and at the end there is a go run or go build.

I suggest you to run grumpy -v debug myscript.py that imports bunch of stdlib first, then follow the debug logs to get a grip on how the sausage is done.

xukku commented 4 years ago

for some reasons this does not work automatically

simple example of file gostrconv.py

# grumpy -v warning --keep-main gostrconv.py
# find . -type f -exec cat {} \;

import "__go__/strconv"
print repr(strconv.Itoa(-42))

grumpy -v warning --keep-main gostrconv.py


/tmp/tmpsxuDmA__pycache__/gopath/src/__python__/__main__/module.go:4:2: cannot find package "__python__/__go__/strconv" in any of:
    /usr/lib/go/src/__python__/__go__/strconv (from $GOROOT)
    /tmp/tmpsxuDmA__pycache__/gopath/src/__python__/__go__/strconv (from $GOPATH)
    /home/user/.local/lib/python2.7/site-packages/grumpy_runtime/data/gopath/src/__python__/__go__/strconv
warning: not cleaning the temporary pycache folder: /tmp/tmpsxuDmA__pycache__

grumpy -v debug gostrconv.py

info: GOPATH: /home/user/.local/lib/python2.7/site-packages/grumpy_runtime/data/gopath
info: __main__ pycache folder: /tmp/tmpkpywJE__pycache__
debug: Should transpile '__main__'
debug: Dependencies file regenerated
info: `go run` GOPATH=/tmp/tmpkpywJE__pycache__/gopath:/home/user/.local/lib/python2.7/site-packages/grumpy_runtime/data/gopath
debug: Starting subprocess: `go run /tmp/tmpkpywJE__pycache__/gopath/src/__python__/main.go`
/tmp/tmpkpywJE__pycache__/gopath/src/__python__/__main__/module.go:4:2: cannot find package "__python__/__go__/strconv" in any of:
    /usr/lib/go/src/__python__/__go__/strconv (from $GOROOT)
    /tmp/tmpkpywJE__pycache__/gopath/src/__python__/__go__/strconv (from $GOPATH)
    /home/user/.local/lib/python2.7/site-packages/grumpy_runtime/data/gopath/src/__python__/__go__/strconv

generated files

find . -type f

./checksum-__main__.sha1
./dependencies-__main__.pkl
./__main__.py
./gopath/src/__python__/main.go
./gopath/src/__python__/__main__/module.go

main.go

package main
import (
    "os"
    "grumpy"
    mod "__python__/__main__"
    _ "__python__/traceback"

)
func main() {
    grumpy.ImportModule(grumpy.NewRootFrame(), "traceback")
    os.Exit(grumpy.RunMain(mod.Code))
}

module.go

package __main__
import (
    πg "grumpy"
    _ "__python__/__go__/strconv"
)
var Code *πg.Code
func init() {
    Code = πg.NewCode("<module>", "/home/user/work/grumpy-example-currency-parser/__main__.py", nil, 0, func(πF *πg.Frame, _ []*πg.Object) (*πg.Object, *πg.BaseException) {
        var πR *πg.Object; _ = πR
        var πE *πg.BaseException; _ = πE
        ßItoa := πg.InternStr("Itoa")
        ßrepr := πg.InternStr("repr")
        ßstrconv := πg.InternStr("strconv")
        var πTemp001 *πg.Object
        _ = πTemp001
        var πTemp002 []*πg.Object
        _ = πTemp002
        var πTemp003 []*πg.Object
        _ = πTemp003
        var πTemp004 []*πg.Object
        _ = πTemp004
        var πTemp005 *πg.Object
        _ = πTemp005
        for ; πF.State() >= 0; πF.PopCheckpoint() {
            switch πF.State() {
            case 0:
            default: panic("unexpected function state")
            }
            // line 5: import "__go__/strconv"
            πF.SetLineno(5)
            if πTemp002, πE = πg.ImportModule(πF, "__go__/strconv"); πE != nil {
                continue
            }
            πTemp001 = πTemp002[0]
            if πE = πF.Globals().SetItem(πF, ßstrconv.ToObject(), πTemp001); πE != nil {
                continue
            }
            // line 6: print repr(strconv.Itoa(-42))
            πF.SetLineno(6)
            πTemp002 = make([]*πg.Object, 1)
            πTemp003 = πF.MakeArgs(1)
            πTemp004 = πF.MakeArgs(1)
            if πTemp001, πE = πg.Neg(πF, πg.NewInt(42).ToObject()); πE != nil {
                continue
            }
            πTemp004[0] = πTemp001
            if πTemp001, πE = πg.ResolveGlobal(πF, ßstrconv); πE != nil {
                continue
            }
            if πTemp005, πE = πg.GetAttr(πF, πTemp001, ßItoa, nil); πE != nil {
                continue
            }
            if πTemp001, πE = πTemp005.Call(πF, πTemp004, nil); πE != nil {
                continue
            }
            πF.FreeArgs(πTemp004)
            πTemp003[0] = πTemp001
            if πTemp001, πE = πg.ResolveGlobal(πF, ßrepr); πE != nil {
                continue
            }
            if πTemp005, πE = πTemp001.Call(πF, πTemp003, nil); πE != nil {
                continue
            }
            πF.FreeArgs(πTemp003)
            πTemp002[0] = πTemp005
            if πE = πg.Print(πF, πTemp002, true); πE != nil {
                continue
            }
        }
        return nil, πE
    })
    πg.RegisterModule("__main__", Code)
}
xukku commented 4 years ago

checked the repository code and did not find where is pkgc utility launch so i think i should run it manually for go packages which i used

alanjds commented 4 years ago

You may be right. Maybe what is available is whitelisted on the makefiles of grumpy-ru time.

The build process is a bit convoluted as it creates at least one makefile dynamically and calls it from the main makefile.

I searched for a place where it is whitelisted but now I think it does some reflection (or list folder/files at least)