lcompilers / lpython

Python compiler
https://lpython.org/
Other
1.37k stars 157 forks source link

Bug: Expressions with a return value not stored in a variable lead to an exception #2627

Open kmr-srbh opened 3 months ago

kmr-srbh commented 3 months ago
d: dict[str, str] = {"a": "hello", "b": "lpython"}
d.keys()
(base) saurabh-kumar@Awadh:~/Projects/System/lpython$ ./src/bin/lpython ./examples/example.py
Internal Compiler Error: Unhandled exception
Traceback (most recent call last):
  Binary file "/home/saurabh-kumar/Projects/System/lpython/src/bin/lpython", in _start()
  File "./csu/../csu/libc-start.c", line 360, in __libc_start_main_impl()
  File "./csu/../sysdeps/x86/libc-start.c", line 58, in __libc_start_call_main()
  File "/home/saurabh-kumar/Projects/System/lpython/src/bin/lpython.cpp", line 1934, in main()
    err = compile_python_to_object_file(arg_file, tmp_o, runtime_library_dir,
  File "/home/saurabh-kumar/Projects/System/lpython/src/bin/lpython.cpp", line 838, in compile_python_to_object_file()
    !(arg_c && compiler_options.po.disable_main), "__main__", infile);
  File "/home/saurabh-kumar/Projects/System/lpython/src/lpython/semantics/python_ast_to_asr.cpp", line 8253, in LCompilers::LPython::python_ast_to_asr(Allocator&, LCompilers::LocationManager&, LCompilers::SymbolTable*, LCompilers::LPython::AST::ast_t&, LCompilers::diag::Diagnostics&, LCompilers::CompilerOptions&, bool, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool)
    ast_overload, allow_implicit_casting);
  File "/home/saurabh-kumar/Projects/System/lpython/src/lpython/semantics/python_ast_to_asr.cpp", line 8190, in LCompilers::LPython::body_visitor(Allocator&, LCompilers::LocationManager&, LCompilers::LPython::AST::Module_t const&, LCompilers::diag::Diagnostics&, LCompilers::ASR::asr_t*, bool, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::map<int, LCompilers::ASR::symbol_t*, std::less<int>, std::allocator<std::pair<int const, LCompilers::ASR::symbol_t*> > >&, bool)
    b.visit_Module(ast);
  File "/home/saurabh-kumar/Projects/System/lpython/src/lpython/semantics/python_ast_to_asr.cpp", line 4885, in LCompilers::LPython::BodyVisitor::visit_Module(LCompilers::LPython::AST::Module_t const&)
    pass_wrap_global_stmts(al, *unit, pass_options);
LCompilersException: Return type not supported in interactive mode
kmr-srbh commented 3 months ago

The above code is completely valid and executes properly in CPython.

I have 2 suggestions for a fix:

  1. Either we handle all the return types. In the above example, it was a ListConstant, but we are not handling it.
  2. We improve the mechanism which tells the compiler that it is executing in interactive mode.
kmr-srbh commented 2 months ago

The problem does not occur when a local scope is used.

from lpython import i32

def foo():
    d: dict[str, str] = {"a": "hello", "b": "lpython"}
    d.keys()

foo()
Shaikh-Ubaid commented 2 months ago

I think it is related to the return value not being utilised. A workaround for the issue can be to assign the return value to some dummy/temporary variable.

% cat examples/expr2.py    
d: dict[str, str] = {"a": "hello", "b": "lpython"}
a: list[str] = d.keys()
% python examples/expr2.py 
% lpython examples/expr2.py
kmr-srbh commented 2 months ago

I think it is related to the return value not being utilised.

You are right @Shaikh-Ubaid. The code I had shared above is valid in CPython, but in LPython, it causes the compiler to believe it is executing in interactive mode. This does not happen for all the methods with a return value. The following executes normally.

from lpython import i32

l: list[i32] = [1, 2, 3, 4, 5]
l.pop(0)

print(l)