BLUELOVETH před 2 roky
rodič
revize
8a188cff43
3 změnil soubory, kde provedl 25 přidání a 12 odebrání
  1. 13 6
      src/vm.cpp
  2. 6 1
      tests/test1/__init__.py
  3. 6 5
      tests/test2/utils/r.py

+ 13 - 6
src/vm.cpp

@@ -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){
-            if(pending_name == path) ImportError(fmt("circular import ", name.escape()));
-        }
+        // for(Str pending_name: _import_context.pending){
+        //     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));

+ 6 - 1
tests/test1/__init__.py

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

+ 6 - 5
tests/test2/utils/r.py

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