This commit is contained in:
BLUELOVETH 2023-08-28 13:17:58 +08:00
parent 8b47a2001f
commit 8a188cff43
3 changed files with 25 additions and 12 deletions

View File

@ -217,6 +217,8 @@ namespace pkpy{
PyObject* VM::py_import(Str path, bool throw_err){ PyObject* VM::py_import(Str path, bool throw_err){
if(path.empty()) vm->ValueError("empty module name"); if(path.empty()) vm->ValueError("empty module name");
// std::cout << ">> py_import(" << path.escape() << ")" << std::endl;
auto f_join = [](const std::vector<std::string_view>& cpnts){ auto f_join = [](const std::vector<std::string_view>& cpnts){
std::stringstream ss; std::stringstream ss;
@ -243,18 +245,21 @@ namespace pkpy{
if(prefix > cpnts.size()) ImportError("attempted relative import beyond top-level package"); if(prefix > cpnts.size()) ImportError("attempted relative import beyond top-level package");
path = path.substr(prefix); // remove prefix path = path.substr(prefix); // remove prefix
for(int i=(int)curr_is_init; i<prefix; i++) cpnts.pop_back(); for(int i=(int)curr_is_init; i<prefix; i++) cpnts.pop_back();
cpnts.push_back(path.sv()); if(!path.empty()) cpnts.push_back(path.sv());
path = f_join(cpnts); path = f_join(cpnts);
} }
// std::cout << "py_import(" << path.escape() << ")" << std::endl; // std::cout << ".. py_import(" << path.escape() << ")" << std::endl;
PK_ASSERT(path.begin()[0] != '.');
PK_ASSERT(path.end()[-1] != '.');
StrName name(path); // path to StrName StrName name(path); // path to StrName
// check circular import // check circular import
for(Str pending_name: _import_context.pending){ // for(Str pending_name: _import_context.pending){
if(pending_name == path) ImportError(fmt("circular import ", name.escape())); // if(pending_name == path) ImportError(fmt("circular import ", name.escape()));
} // }
PyObject* ext_mod = _modules.try_get(name); PyObject* ext_mod = _modules.try_get(name);
if(ext_mod != nullptr) return ext_mod; if(ext_mod != nullptr) return ext_mod;
@ -501,7 +506,9 @@ PyObject* VM::new_module(Str name, Str package) {
obj->attr().set(__package__, VAR(package)); obj->attr().set(__package__, VAR(package));
// we do not allow override in order to avoid memory leak // we do not allow override in order to avoid memory leak
// it is because Module objects are not garbage collected // it is because Module objects are not garbage collected
if(_modules.contains(name)) throw std::runtime_error("module already exists"); if(_modules.contains(name)){
throw std::runtime_error(fmt("module ", name.escape(), " already exists"));
}
// convert to fullname and set it into _modules // convert to fullname and set it into _modules
if(!package.empty()) name = package + "." + name; if(!package.empty()) name = package + "." + name;
obj->attr().set(__path__, VAR(name)); obj->attr().set(__path__, VAR(name));

View File

@ -1 +1,6 @@
from ._a import add from . import _a
add = _a.add
from ._a import add as add2
assert add is add2

View File

@ -1,7 +1,8 @@
value = '123' value = '123'
try: # try:
from test2.a import g # from test2.a import g
except ImportError: # exit(1)
# circular import # except ImportError:
pass # # circular import
# pass