Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions integration_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 1 addition & 2 deletions integration_tests/test_import_01.py
Original file line number Diff line number Diff line change
@@ -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())
5 changes: 5 additions & 0 deletions integration_tests/test_import_03.py
Original file line number Diff line number Diff line change
@@ -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())
105 changes: 53 additions & 52 deletions src/lpython/semantics/python_ast_to_asr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3397,6 +3397,57 @@ class SymbolTableVisitor : public CommonVisitor<SymbolTableVisitor> {
}
}

void set_module_symbol(std::string &mod_sym, std::vector<std::string> &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);
Expand All @@ -3417,32 +3468,7 @@ class SymbolTableVisitor : public CommonVisitor<SymbolTableVisitor> {
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); },
Expand Down Expand Up @@ -3488,32 +3514,7 @@ class SymbolTableVisitor : public CommonVisitor<SymbolTableVisitor> {
}
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); },
Expand Down
2 changes: 1 addition & 1 deletion src/lpython/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/lpython/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down