diff --git a/include/pocketpy/str.h b/include/pocketpy/str.h index a9faafbe..caaaf4a8 100644 --- a/include/pocketpy/str.h +++ b/include/pocketpy/str.h @@ -188,6 +188,7 @@ const StrName __exit__ = StrName::get("__exit__"); const StrName __name__ = StrName::get("__name__"); const StrName __all__ = StrName::get("__all__"); const StrName __package__ = StrName::get("__package__"); +const StrName __path__ = StrName::get("__path__"); const StrName pk_id_add = StrName::get("add"); const StrName pk_id_set = StrName::get("set"); diff --git a/include/pocketpy/vm.h b/include/pocketpy/vm.h index 40db61cd..6b28523a 100644 --- a/include/pocketpy/vm.h +++ b/include/pocketpy/vm.h @@ -430,7 +430,7 @@ public: }; ImportContext _import_context; - PyObject* py_import(Str path, PyObject* _module); + PyObject* py_import(Str path, bool throw_err=true); ~VM(); #if PK_DEBUG_CEVAL_STEP diff --git a/src/ceval.cpp b/src/ceval.cpp index 8023d7c5..403227d8 100644 --- a/src/ceval.cpp +++ b/src/ceval.cpp @@ -592,7 +592,7 @@ __NEXT_STEP:; /*****************************************/ TARGET(IMPORT_PATH) _0 = co_consts[byte.arg]; - PUSH(py_import(CAST(Str&, _0), frame->_module)); + PUSH(py_import(CAST(Str&, _0))); DISPATCH(); TARGET(POP_IMPORT_STAR) { _0 = POPX(); // pop the module diff --git a/src/pocketpy.cpp b/src/pocketpy.cpp index d30fe3b9..ddd4af29 100644 --- a/src/pocketpy.cpp +++ b/src/pocketpy.cpp @@ -182,7 +182,7 @@ void init_builtins(VM* _vm) { return vm->_modules[name]; } } - return vm->py_import(name, vm->top_frame()->_module); + return vm->py_import(name); }); _vm->bind_builtin_func<2>("divmod", [](VM* vm, ArgsView args) { @@ -1227,10 +1227,8 @@ void init_builtins(VM* _vm) { }); _vm->bind__repr__(_vm->tp_module, [](VM* vm, PyObject* obj) { - const Str& package = CAST(Str&, obj->attr(__package__)); - Str name = CAST(Str&, obj->attr(__name__)); - if(!package.empty()) name = package + "." + name; - return VAR(fmt("")); + const Str& path = CAST(Str&, obj->attr(__path__)); + return VAR(fmt("")); }); /************ property ************/ diff --git a/src/vm.cpp b/src/vm.cpp index 0771b616..848c07b4 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -215,9 +215,9 @@ namespace pkpy{ return call_method(obj, __next__); } - PyObject* VM::py_import(Str path, PyObject* _module){ + PyObject* VM::py_import(Str path, bool throw_err){ if(path.empty()) vm->ValueError("empty module name"); - + auto f_join = [](const std::vector& cpnts){ std::stringstream ss; for(int i=0; isecond; @@ -501,6 +504,7 @@ PyObject* VM::new_module(Str name, Str package) { if(_modules.contains(name)) throw std::runtime_error("module already exists"); // convert to fullname and set it into _modules if(!package.empty()) name = package + "." + name; + obj->attr().set(__path__, VAR(name)); _modules.set(name, obj); return obj; } @@ -940,8 +944,15 @@ PyObject* VM::getattr(PyObject* obj, StrName name, bool throw_err){ return cls_var; } - // if(is_non_tagged_type(obj, tp_module)){ - // } + if(is_non_tagged_type(obj, tp_module)){ + Str path = CAST(Str&, obj->attr(__path__)); + path = path + "." + name.sv(); + PyObject* mod = py_import(path, false); + if(mod != nullptr){ + obj->attr().set(name, mod); + return mod; + } + } if(throw_err) AttributeError(obj, name); return nullptr; diff --git a/tests/80_linalg.py b/tests/80_linalg.py index cbfd2646..16490b78 100644 --- a/tests/80_linalg.py +++ b/tests/80_linalg.py @@ -3,6 +3,8 @@ import random import sys import math +assert repr(math) == "" + # 出于对精度转换的考虑,在本测试中具体将采用str(floating_num)[:6]来比较两个浮点数是否相等 # test vec2--------------------------------------------------------------------