From 222231401ce856c8963fb89caf77f8b3cfbbb381 Mon Sep 17 00:00:00 2001 From: Thirumalai-Shaktivel Date: Thu, 17 Nov 2022 10:02:39 +0530 Subject: [PATCH 1/2] Add set_module_symbol function To set the correct module name to be imported. Also, set the correct import path --- src/lpython/semantics/python_ast_to_asr.cpp | 105 ++++++++++---------- src/lpython/utils.cpp | 2 +- src/lpython/utils.h | 2 +- 3 files changed, 55 insertions(+), 54 deletions(-) diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index b079564010..fc01941b90 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -3397,6 +3397,57 @@ class SymbolTableVisitor : public CommonVisitor { } } + void set_module_symbol(std::string &mod_sym, std::vector &paths) { + if (mod_sym != "ltypes") { + // Check for the import path and mod_sym not in runtime library + if (import_path != "" && + !path_exists(paths[0] + '/' + mod_sym + ".py")) { + paths = {import_path}; + if (parent_dir != "") paths[0] += '/' + parent_dir; + if(path_exists(paths[0])) { + // Check for the nested modules with "." + // Example: from x.y import z + if (mod_sym.find(".") != std::string::npos) { + mod_sym.replace(mod_sym.find("."), 1, "/"); + if(is_directory(paths[0] + "/" + mod_sym)) { + // Directory i.e., x/y/__init__.py + paths[0] += '/' + mod_sym; + mod_sym = "__init__"; + } else { + // File i.e., x/y.py + paths[0] += '/' + mod_sym.substr(0, + mod_sym.find_last_of('/')); + mod_sym = mod_sym.substr(mod_sym.find_last_of('/') + 1, + mod_sym.size() - 1); + } + } else if(is_directory(paths[0] + "/" + mod_sym)) { + // Directory i.e., x/__init__.py + paths[0] += '/' + mod_sym; + mod_sym = "__init__"; + } + } + } else if (mod_sym.find(".") != std::string::npos) { + // Check for the nested modules with "." + // Example: from x.y import z + mod_sym.replace(mod_sym.find("."), 1, "/"); + if(is_directory(paths[1] + "/" + mod_sym)) { + if (parent_dir != "") paths[1] += "/"; + paths[1] += mod_sym; + mod_sym = "__init__"; + } + } else if (parent_dir != "" + && is_directory(paths[1] + '/' + mod_sym)) { + // Directory i.e., parent_dir/x/__init__.py + paths[1] += '/' + mod_sym; + mod_sym = "__init__"; + } else if (is_directory(mod_sym)) { + // Directory i.e., x/__init__.py + paths.push_back(mod_sym); + mod_sym = "__init__"; + } + } + } + void visit_ImportFrom(const AST::ImportFrom_t &x) { if (!x.m_module) { throw SemanticError("Not implemented: The import statement must currently specify the module name", x.base.base.loc); @@ -3417,32 +3468,7 @@ class SymbolTableVisitor : public CommonVisitor { st = st->parent; } bool ltypes, enum_py; - if (msym != "ltypes") { - if (import_path != "" && - !path_exits(paths[0] + '/' + msym + ".py")) { - paths = {import_path}; - if (parent_dir != "") paths[0] += '/' + parent_dir; - if(is_directory(paths[0])) { - if (msym.find(".") != std::string::npos) { - msym.replace(msym.find("."), 1, "/"); - } - paths[0] += '/' + msym; - msym = "__init__"; - } - } else if (msym.find(".") != std::string::npos) { - msym.replace(msym.find("."), 1, "/"); - if (parent_dir != "") paths[1] += "/"; - paths[1] += msym; - msym = "__init__"; - } else if (is_directory(msym)) { - paths = {rl_path, msym}; - msym = "__init__"; - } else if (paths[1] != "" - && is_directory(paths[1] + '/' + msym)) { - paths[1] += '/' + msym; - msym = "__init__"; - } - } + set_module_symbol(msym, paths); t = (ASR::symbol_t*)(load_module(al, st, msym, x.base.base.loc, false, paths, ltypes, enum_py, [&](const std::string &msg, const Location &loc) { throw SemanticError(msg, loc); }, @@ -3488,32 +3514,7 @@ class SymbolTableVisitor : public CommonVisitor { } for (auto &mod_sym : mods) { bool ltypes, enum_py; - if (mod_sym != "ltypes") { - if (import_path != "" && - !path_exits(paths[0] + '/' + mod_sym + ".py")) { - paths = {import_path}; - if (parent_dir != "") paths[0] += '/' + parent_dir; - if(is_directory(paths[0])) { - if (mod_sym.find(".") != std::string::npos) { - mod_sym.replace(mod_sym.find("."), 1, "/"); - } - paths[0] += '/' + mod_sym; - mod_sym = "__init__"; - } - } else if (mod_sym.find(".") != std::string::npos) { - mod_sym.replace(mod_sym.find("."), 1, "/"); - if (parent_dir != "") paths[1] += "/"; - paths[1] += mod_sym; - mod_sym = "__init__"; - } else if (is_directory(mod_sym)) { - paths = {rl_path, mod_sym}; - mod_sym = "__init__"; - } else if (paths[1] != "" - && is_directory(paths[1] + '/' + mod_sym)) { - paths[1] += '/' + mod_sym; - mod_sym = "__init__"; - } - } + set_module_symbol(mod_sym, paths); t = (ASR::symbol_t*)(load_module(al, st, mod_sym, x.base.base.loc, false, paths, ltypes, enum_py, [&](const std::string &msg, const Location &loc) { throw SemanticError(msg, loc); }, diff --git a/src/lpython/utils.cpp b/src/lpython/utils.cpp index 874b5268fc..ad1a8097b3 100644 --- a/src/lpython/utils.cpp +++ b/src/lpython/utils.cpp @@ -94,7 +94,7 @@ bool is_directory(std::string path) { return false; } -bool path_exits(std::string path) { +bool path_exists(std::string path) { struct stat buffer; if (stat(path.c_str(), &buffer) == 0) { return true; diff --git a/src/lpython/utils.h b/src/lpython/utils.h index 4fadfe7140..bcf010eff2 100644 --- a/src/lpython/utils.h +++ b/src/lpython/utils.h @@ -10,7 +10,7 @@ void get_executable_path(std::string &executable_path, int &dirname_length); std::string get_runtime_library_dir(); std::string get_runtime_library_header_dir(); bool is_directory(std::string path); -bool path_exits(std::string path); +bool path_exists(std::string path); } // LFortran From 9088078a79c4622fb3d71e5e83959a0544548996 Mon Sep 17 00:00:00 2001 From: Thirumalai-Shaktivel Date: Thu, 17 Nov 2022 10:10:05 +0530 Subject: [PATCH 2/2] Register tests in CMakeLists --- integration_tests/CMakeLists.txt | 1 + integration_tests/test_import_01.py | 3 +-- integration_tests/test_import_03.py | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 integration_tests/test_import_03.py diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index 391e2ab6a7..059bbe59cd 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -240,6 +240,7 @@ RUN(NAME modules_01 LABELS cpython llvm wasm wasm_x86) RUN(NAME modules_02 LABELS cpython llvm wasm wasm_x86) RUN(NAME test_import_01 LABELS cpython llvm) RUN(NAME test_import_02 LABELS cpython llvm) +RUN(NAME test_import_03 LABELS cpython llvm) RUN(NAME test_math LABELS cpython llvm) RUN(NAME test_numpy_01 LABELS cpython llvm c) RUN(NAME test_numpy_02 LABELS cpython llvm c) diff --git a/integration_tests/test_import_01.py b/integration_tests/test_import_01.py index e2bcccc9ac..21750fdd80 100644 --- a/integration_tests/test_import_01.py +++ b/integration_tests/test_import_01.py @@ -1,6 +1,5 @@ import test_import -from test_import import print_a -print(print_a()) +print(test_import.print_a()) print(test_import.print_b()) print(test_import.print_c()) diff --git a/integration_tests/test_import_03.py b/integration_tests/test_import_03.py new file mode 100644 index 0000000000..1b17f8e610 --- /dev/null +++ b/integration_tests/test_import_03.py @@ -0,0 +1,5 @@ +from test_import import print_a +from test_import.test_import_1 import print_b + +print(print_a()) +print(print_b())