Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optional type annotations #12

Open
jtran opened this issue Dec 27, 2021 · 2 comments
Open

Optional type annotations #12

jtran opened this issue Dec 27, 2021 · 2 comments

Comments

@jtran
Copy link

jtran commented Dec 27, 2021

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!")
}
@IoIxD
Copy link
Contributor

IoIxD commented Jun 22, 2022

That's not exactly how pointers work. If you wanted to use this a substitute for optional parameters, you'd have to modify your code anyways to check if the pointer is nil, dereference it, etc... at the point where you're modifying your go code you might as well just be modifying the python code.

@jtran
Copy link
Author

jtran commented Jun 22, 2022

You're missing the point of the issue. The request isn't to convert optional parameters to pointers; it's to transpile Optional types in a way that makes sense. (Converting to a pointer without also converting if x is not None: and properly dereferencing clearly wouldn't make sense.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants