Giter VIP home page Giter VIP logo

pytago's Issues

looping over lines of a file object does not translate correctly

Hi there! Cool project. I gave it a play with some simple example code and noticed that looping over the lines of an open file object does not translate properly yet, so I thought I would leave this bug report here.

def main():
	fh = open("file.txt")
	for line in fh:
		print(lin)
	fh.close()
  
	with open("file2.txt") as fh2:
		for line in fh2:
			print(line)

if __name__ == '__main__':
  main()

Currently translates to:

package main

import "fmt"

func main() {
	fh := open("file.txt")
	for _, line := range fh {
		fmt.Println(lin)
	}
	fh.close()
	func() {
		fh2 := open("file2.txt")
		defer func() {
			if err := fh2.Close(); err != nil {
				panic(err)
			}
		}()
		for _, line := range fh2 {
			fmt.Println(line)
		}
	}()
}

python unpack convert error

Describe the bug
A clear and concise description of what the bug is.

tuple unpack

Python code example
The simplest possible Python code example to demonstrate the bug.

def main():
  zz,*x = (0,0,0,0)
  print(zz,x)

if __name__ == '__main__':
  main()

Current behavior
What the program currently outputs for the code example.

package main

import "fmt"

func main() {
	zz, x := 0, 0, 0, 0
	fmt.Println(zz, x)
}

Expected behavior
A clear and concise description of what you expected to happen.

x becomes a tuple.

Go code example
Optional. An example of a satisfactory Go code output for the Python example.

this may helps

https://stackoverflow.com/questions/19832189/unpack-slices-on-assignment

map(int,["1","2"]) convert wrong

Describe the bug
A clear and concise description of what the bug is.

map(int,["1","2"]) convert wrong

Python code example
The simplest possible Python code example to demonstrate the bug.

def main():
  x=map(int,["1","2"])
  print(x)

if __name__ == '__main__':
  main()

Current behavior
What the program currently outputs for the code example.

package main

import "fmt"

func main() {
	x := func() func() <-chan int {
		wait := make(chan struct{})
		yield := make(chan int)
		go func() {
			defer close(yield)
			<-wait
			for _, x := range []string{"1", "2"} {
				yield <- int(x)
				<-wait
			}
		}()
		return func() <-chan int {
			wait <- struct{}{}
			return yield
		}
	}()
	fmt.Println(x)
}

Expected behavior
A clear and concise description of what you expected to happen.

int should be translated.

Go code example
Optional. An example of a satisfactory Go code output for the Python example.

def main():
  print(int("1"))
if __name__ == '__main__':
  main()

this returns a good result.

package main

import (
	"fmt"
	"strconv"
)

func main() {
	fmt.Println(func() int {
		i, err := strconv.ParseInt("1", 10, 64)
		if err != nil {
			panic(err)
		}
		return int(i)
	}())
}

Use problem. help

usage: Pytago [-h] [-o OUTFILE] INFILE

pytago -o test.go test.py
It output an error when using the above command.

D:\PythonProject>pytago test.py  
Traceback (most recent call last):  
  File "D:\Python\Python310\lib\runpy.py", line 196, in _run_module_as_main  
    return _run_code(code, main_globals, None,  
  File "D:\Python\Python310\lib\runpy.py", line 86, in _run_code  
    exec(code, run_globals)  
  File "D:\Python\Python310\Scripts\pytago.exe\__main__.py", line 7, in <module>  
  File "D:\Python\Python310\lib\site-packages\pytago\cmd.py", line 14, in main  
    go = python_to_go(f.read(), debug=False)  
  File "D:\Python\Python310\lib\site-packages\pytago\core.py", line 31, in python_to_go  
    return go_ast.unparse(go_tree, debug=debug)  
  File "D:\Python\Python310\lib\site-packages\pytago\go_ast\parsing.py", line 55, in unparse  
    externally_formatted_code = _golines(_gofumpt(_goimport(code)))  
  File "D:\Python\Python310\lib\site-packages\pytago\go_ast\parsing.py", line 251, in _goimport  
    p = Popen(["goimports"], stdout=PIPE, stderr=PIPE, stdin=PIPE)  
  File "D:\Python\Python310\lib\subprocess.py", line 966, in __init__  
    self._execute_child(args, executable, preexec_fn, close_fds,  
  File "D:\Python\Python310\lib\subprocess.py", line 1435, in _execute_child  
    hp, ht, pid, tid = _winapi.CreateProcess(executable, args,  
FileNotFoundError: [WinError 2]

It looks like it didn't find the file, but it does exist

`time` module does not translate well!

Describe the bug
when using methods from the time module, the only method that is translated properly is time.sleep(), while the others result the same python code in Go.

Python code example

import time

def main():
    print(time.time())
    print(time.time_ns())
    print(time.ctime(time.time()))

if __name__ == '__main__':
    main()

Current behavior
the above three methods are not being translated into Go code but rather written as is in python, and this code is generated. which is not a valid Go code!

package main

import "fmt"

func main() {
	fmt.Println(time.time())
	fmt.Println(time.time_ns())
	fmt.Println(time.ctime(time.time()))
}

Expected behavior

  1. time.time() should be translated into time.Now().Unix() in Go
  2. time.time_ns() should be translated into time.Now().UnixNano() in Go
  3. time.ctime(time.time()) should be translated into time.Now() in Go

Correct Go code example

package main

import (
	"fmt"
	"time"
)

func main() {
	fmt.Println(time.Now().Unix())
	fmt.Println(time.Now().UnixNano())
	fmt.Println(time.Now())
}

math.Pow takes float64, not int

Describe the bug
When the ** operator is used on integers in a list, they are passed to math.Pow as-is. This does not work because math.Pow takes float64 arguments.

Python code example

def main():
	x = [2, 4]
	print(x[0]**x[1])

if __name__ == '__main__':
  main()

This works without a list because an integer literal is an untyped int, which just becomes float64 when used in math.Pow

Current behavior

package main

import (
	"fmt"
	"math"
)

func main() {
	x := []int{2, 4}
	fmt.Println(math.Pow(x[0], x[1]))
}

Expected behavior
I expected there to be a type conversion to float64 before passing the value to math.Pow

Go code example

package main

import (
	"fmt"
	"math"
)

func main() {
	x := []int{2, 4}
	fmt.Println(math.Pow(float64(x[0]), float64(x[1])))
}

`type()` function doesn't translate well!

Describe the bug
when calling the type() function in python it translates as is to the Go code, where it should translate to fmt.Printf("%T", v)

Python code example

def main():
	b: bool = False
	i: int = 12
	c: chr = 'h'    
	f: float = 4.2
	s: str = "bla bla"
	
	print("type(b) = ", type(b))
	print("type(i) = ", type(i))
	print("type(c) = ", type(c))
	print("type(f) = ", type(f))
	print("type(s) = ", type(s))
    
if __name__ == '__main__':
	main()

Current behavior
the python function type() translates as is to Go(which Go doesn't have)

Expected behavior

package main

import "fmt"

func main() {
	var b bool = false
	var i int = 12
	var c uint8 = 'h'
	var f float64 = 4.2
	var s string = "bla bla"
	fmt.Printf("type(b) = %T\n", b)
	fmt.Printf("type(i) = %T\n", i)
	fmt.Printf("type(c) = %T\n", c)
	fmt.Printf("type(f) = %T\n", f)
	fmt.Printf("type(s) = %T\n", s)
}

Go code example

package main

func main() {
	var b bool = false
	var i int = 12
	var c chr = "h" // here's bonus, chr doesn't translate well
	var f float64 = 4.2
	var s string = "bla bla"
	fmt.Println("type(b) = ", type(b))
	fmt.Println("type(i) = ", type(i))
	fmt.Println("type(c) = ", type(c))
	fmt.Println("type(f) = ", type(f))
	fmt.Println("type(s) = ", type(s))
}

as seen the type functions translates as is to Go!

BONUS

python's chr type translates as is, where it should be translated into uint8 or rune if it was unicode!

Converting to bytes

Describe the bug
Converting to bytes in python attempts to run a non-existent function bytes.

Python code example

def main():
	x = bytes("hello", "utf8")
	print(x[0])

if __name__ == '__main__':
  main()

Current behavior

package main

import "fmt"

func main() {
	x := bytes("hello", "utf8")
	fmt.Println(x[0])
}

Expected behavior
I expected the string to be converted to []byte

Go code example

package main

import "fmt"

func main() {
	x := []byte("hello")
	fmt.Println(x[0])
}

Python `__str__` method doesn't translate to go `String()` method

Describe the bug
Python classes have an __str__ method that defines how they are printed. Go structs have a String() method that does the same.

Python code example

print("Hello, World!")

class A:
  a = "huh?"
  
  def __init__(self, val):
    self.a = val
  
  def __str__(self):
    return self.a
 
val = A("ok")
print(val)

Current behavior
(relevant code):

func (self *A) __str__() {
	return self.a
}

Expected behavior

func (self *A) String() {
	return self.a
}

Optional type annotations

Describe the bug
Hi, I would like to transpile Python code with type annotations that include Optional.

Python code example

Here's an example using a parameter, but ideally it would work anywhere type annotations are allowed.

from typing import Optional

def main(x: Optional[int] = None):
    print("Hello world!")

Current behavior

Exception: [(<class 'pytago.go_ast.core.FuncLit'>, NotImplementedError(&ast.Ident { Name: "Optional" })), (<class 'pytago.go_ast.core.FuncType'>, NotImplementedError(&ast.Ident { Name: "Optional" }))]

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/username/pytago/pytago/go_ast/core.py", line 373, in _build_x_list
    result = getattr(x_type, method)(x_node, **kwargs)
  File "/Users/username/pytago/pytago/go_ast/core.py", line 893, in from_FunctionDef
    rhs = build_expr_list([node])
  File "/Users/username/pytago/pytago/go_ast/core.py", line 417, in build_expr_list
    return _build_x_list(_EXPR_TYPES, "Expr", nodes, **kwargs)
  File "/Users/username/pytago/pytago/go_ast/core.py", line 391, in _build_x_list
    raise ValueError(f"No {x_name} type in {x_types} with {method}: "
ValueError: No Expr type in [<class 'pytago.go_ast.core.Expr'>, <class 'pytago.go_ast.core.ArrayType'>, <class 'pytago.go_ast.core.BadExpr'>, <class 'pytago.go_ast.core.BasicLit'>, <class 'pytago.go_ast.core.BinaryExpr'>, <class 'pytago.go_ast.core.Ident'>, <class 'pytago.go_ast.core.CallExpr'>, <class 'pytago.go_ast.core.ChanType'>, <class 'pytago.go_ast.core.CompositeLit'>, <class 'pytago.go_ast.core.Ellipsis'>, <class 'pytago.go_ast.core.FieldList'>, <class 'pytago.go_ast.core.FuncType'>, <class 'pytago.go_ast.core.FuncLit'>, <class 'pytago.go_ast.core.IndexExpr'>, <class 'pytago.go_ast.core.InterfaceType'>, <class 'pytago.go_ast.core.KeyValueExpr'>, <class 'pytago.go_ast.core.MapType'>, <class 'pytago.go_ast.core.ParenExpr'>, <class 'pytago.go_ast.core.SelectorExpr'>, <class 'pytago.go_ast.core.SliceExpr'>, <class 'pytago.go_ast.core.StarExpr'>, <class 'pytago.go_ast.core.StructType'>, <class 'pytago.go_ast.core.TypeAssertExpr'>, <class 'pytago.go_ast.core.UnaryExpr'>, <class 'pytago.go_ast.core.ValueSpec'>] with from_FunctionDef:
\```
def main(x: Optional[int]=None):
    print('Hello world!')
\```

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/username/.pyenv/versions/pytago-venv-3.10.0/bin/pytago", line 33, in <module>
    sys.exit(load_entry_point('pytago', 'console_scripts', 'pytago')())
  File "/Users/username/pytago/pytago/cmd.py", line 14, in main
    go = python_to_go(f.read(), debug=False)
  File "/Users/username/pytago/pytago/core.py", line 30, in python_to_go
    go_tree = go_ast.File.from_Module(py_tree)
  File "/Users/username/pytago/pytago/go_ast/core.py", line 2520, in from_Module
    go_module.Decls[:] = build_decl_list(node.body)
  File "/Users/username/pytago/pytago/go_ast/core.py", line 431, in build_decl_list
    decls.append(FuncDecl.from_global_code(node))
  File "/Users/username/pytago/pytago/go_ast/core.py", line 2708, in from_global_code
    body = from_this(BlockStmt, [node])
  File "/Users/username/pytago/pytago/go_ast/core.py", line 343, in from_this
    result = getattr(cls, from_method(node))(node)
  File "/Users/username/pytago/pytago/go_ast/core.py", line 1280, in from_list
    stmts = build_stmt_list(node_list)
  File "/Users/username/pytago/pytago/go_ast/core.py", line 421, in build_stmt_list
    return _build_x_list(_STMT_TYPES, "Stmt", nodes, **kwargs)
  File "/Users/username/pytago/pytago/go_ast/core.py", line 378, in _build_x_list
    raise type(e)(f"Unhandled exception for {x_name} type in {x_types} with {method}: "
ValueError: Unhandled exception for Stmt type in [<class 'pytago.go_ast.core.Stmt'>, <class 'pytago.go_ast.core.AssignStmt'>, <class 'pytago.go_ast.core.BadStmt'>, <class 'pytago.go_ast.core.BlockStmt'>, <class 'pytago.go_ast.core.BranchStmt'>, <class 'pytago.go_ast.core.CaseClause'>, <class 'pytago.go_ast.core.DeclStmt'>, <class 'pytago.go_ast.core.DeferStmt'>, <class 'pytago.go_ast.core.EmptyStmt'>, <class 'pytago.go_ast.core.ExprStmt'>, <class 'pytago.go_ast.core.ForStmt'>, <class 'pytago.go_ast.core.GoStmt'>, <class 'pytago.go_ast.core.IfStmt'>, <class 'pytago.go_ast.core.IncDecStmt'>, <class 'pytago.go_ast.core.LabeledStmt'>, <class 'pytago.go_ast.core.RangeStmt'>, <class 'pytago.go_ast.core.ReturnStmt'>, <class 'pytago.go_ast.core.SelectStmt'>, <class 'pytago.go_ast.core.SendStmt'>, <class 'pytago.go_ast.core.SwitchStmt'>, <class 'pytago.go_ast.core.TypeSwitchStmt'>] with from_FunctionDef:
\```
def main(x: Optional[int]=None):
    print('Hello world!')
\```

Expected behavior
I expected that it would not raise an exception. In terms of output, perhaps a pointer to the type, an int in this case, would work. This would allow it to be nil.

func main(x *int) {
	fmt.Println("Hello world!")
}

decorator convert wrong

Describe the bug
A clear and concise description of what the bug is.

Python code example
The simplest possible Python code example to demonstrate the bug.

def main():
  def test(f):
    def inner(*args):
      print(args)
      f(*args)
    return inner
  @test
  def x(a,b):
    return a,b
  x(1,2)

if __name__ == '__main__':
  main()

Current behavior
What the program currently outputs for the code example.

package main

import "fmt"

func main() {
	test := func(f interface{}) {
		inner := func() {
			fmt.Println(args)
			f(args...)
		}
		inner
	}
	x := func(a int, b int) [2]int {
		return [2]int{a, b}
	}
	x(1, 2)
}

Expected behavior
A clear and concise description of what you expected to happen.

the decorator changes the function's behavior.

Go code example
Optional. An example of a satisfactory Go code output for the Python example.

pytago local cli run error

Describe the bug
When I use pytago on window 10 to translate hello.py to main.go. the result of main.go is unexpted, what‘s wrong when I do this?

  • System: window 10

  • Python version: 3.10.0

  • Python source code: hello.py:

# For best results, keep your code inside functions
def main():
  print("Hello world!")

if __name__ == '__main__':
  main()
  • comand excuted: pytago -o main.go hello.py

  • result got: main.go

// # command-line-arguments
// C:\Users\ADMINI~1\AppData\Local\Temp\tmp257ukgv_.go:11:177: syntax error: unexpected <, expecting expression
// C:\Users\ADMINI~1\AppData\Local\Temp\tmp257ukgv_.go:11:192: more than one character in rune literal
// warning: -s is deprecated as it is always enabled
  • result expected:
package main

import "fmt"

func main() {
	fmt.Println("Hello world!")
}

macOS Big Sur

It's probably my environment could not find go_ast on macOS?

Installed Go 1.16 and Python 3.10 beta 3 and go get other 2 dependencies:

/Library/Frameworks/Python.framework/Versions/3.10/bin/pytago
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.10/bin/pytago", line 5, in <module>
    from pytago.cmd import main
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/pytago/__init__.py", line 1, in <module>
    from pytago.core import *
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/pytago/core.py", line 3, in <module>
    from pytago import go_ast
ImportError: cannot import name 'go_ast' from partially initialized module 'pytago' (most likely due to a circular import) (/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/pytago/__init__.py)

to-do/feature request: snake case -> camel case

I imagine changing stuff like this isn't within the scope of the project, but having at least an option to change snake_case variables to camel case could be useful to some people, especially those who aren't complete psychopaths.

I'll probably do this on my own time in a PR but I felt like opening this up in case somebody wants to do it instead of me, since it'll likely be awhile before I get around to it.

incompatible with Python 3.11 (?)

I can' get it to work in my environment. Even starting pytago without any arg leads to:

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "C:\Program Files\Python311\Scripts\pytago.exe\__main__.py", line 4, in <module>
  File "C:\Program Files\Python311\Lib\site-packages\pytago\__init__.py", line 1, in <module>
    from pytago.core import *
  File "C:\Program Files\Python311\Lib\site-packages\pytago\core.py", line 24, in <module>
    import astroid
  File "C:\Program Files\Python311\Lib\site-packages\astroid\__init__.py", line 53, in <module>
    from astroid import inference, raw_building
  File "C:\Program Files\Python311\Lib\site-packages\astroid\inference.py", line 33, in <module>
    import wrapt
  File "C:\Program Files\Python311\Lib\site-packages\wrapt\__init__.py", line 10, in <module>
    from .decorators import (adapter_factory, AdapterFactory, decorator,
  File "C:\Program Files\Python311\Lib\site-packages\wrapt\decorators.py", line 34, in <module>
    from inspect import ismethod, isclass, formatargspec
ImportError: cannot import name 'formatargspec' from 'inspect' (C:\Program Files\Python311\Lib\inspect.py)

(and the program aborts; similair Traceback if you try to import pytago).

The python docu for 3.10.11 on inspect.formatargspec() notes:

Deprecated since version 3.5: Use signature() and Signature Object, which provide a better introspecting API for callables.

where the 3.11 docu on inspect does not mention formatargspec().

My environment is:

  • Windows 10, 64bit
  • Python 3.11.3 (64bit)
  • pytago 0.0.12

Lists of inconsistent types

Describe the bug
When using a list of different types, it is implemented as []interface{} as it should, but getting a value does not assert it to the proper type

Python code example

def main():
	x = ["x", 1, 2, 3.0]
	x.append(True)
	print(x[1]+x[2])

if __name__ == '__main__':
  main()

Current behavior

package main

import "fmt"

func main() {
	x := []interface{}{"x", 1, 2, 3.0}
	x = append(x, true)
	fmt.Println(x[1] + x[2])
}

This creates an error because interfaces cannot be added.

Expected behavior
I expected that there would be a type assertion converting the values to int so they could be added

Go code example

package main

import "fmt"

func main() {
	x := []interface{}{"x", 1, 2, 3.0}
	x = append(x, true)
	fmt.Println(x[1].(int) + x[2].(int))
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.