Skip to content

Optional type annotations #12

Open
@jtran

Description

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!")
}

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions