basic online import support

This commit is contained in:
pmp-p 2019-08-08 00:27:01 +02:00
parent f61cc8fa82
commit a15319c68f
7 changed files with 46 additions and 58 deletions

View File

@ -2,6 +2,9 @@ import sys
import builtins
import types
# keep the builtin function accessible in this module and via imp.__import__
__import__ = __import__
# Deprecated since version 3.4: Use types.ModuleType instead.
# but micropython aims toward full 3.4
@ -10,50 +13,16 @@ def new_module(name):
return types.ModuleType(name)
def load_module(module, *argv):
m = new_module(module)
if m:
import embed
file = '/assets/%s.py' % module
mroot = module.split('.')[0]
m = sys.modules[mroot]
runf(file, module=embed.vars(m), patch='\n\n__file__=%r\n' % file )
globals()[mroot] = m
return m
try:
vars
except:
#wasm port
import embed
builtins.vars = embed.vars
try:
vars
except:
print(""" This could provide a workaround for :\r
https://github.com/pmp-p/micropython-ports-wasm/issues/5\r
use imp.load_module(modulename) to load modules from /assets/*.py
""")
raise ImportError("ERROR: this build has no vars() support at all")
# keep the builtin function accessible in this module and from imp.__import__
__import__ = __import__
def importer(name,*argv):
# not spaghetti
def importer(name,*argv,**kw):
global __import__
if sys.modules.get(name,None) is None:
print("import %s" % name,argv)
try:
return __import__(name,*argv)
except ImportError:
pass
file = ':{0}.py'.format(name)
print("trying to go online for",file)
print("INFO: getting online version of",file)
# todo open the file via open() or raise importerror
try:
code = open(file,'r').read()
@ -73,7 +42,12 @@ def importer(name,*argv):
raise
# execute it in its own empty namespace.
try:
ns = vars(mod)
except:
print("WARNING: this python implementation lacks vars()")
ns = mod.__dict__
try:
exec( code, ns, ns)
@ -86,14 +60,6 @@ def importer(name,*argv):
sys.modules[name] = mod
return mod
def reload(name):
if sys.modules.get(name,None):
del sys.modules[name]
return importError(name)
# install hook
builtins.__import__ = importer
print("__import__ is now", importer)

View File

@ -0,0 +1 @@
__dict__ = globals()

View File

@ -0,0 +1,5 @@
__name__ = imp.pivot_name
__file__ = imp.pivot_file
print('pivot',__name__,__file__, globals())
exec( compile( imp.pivot_code, __file__, 'exec') , globals(), globals() )

View File

@ -0,0 +1,10 @@
import sys
import builtins
for name in ("sys", "__main__", "builtins"):
sys.modules[name] = __import__(name)
import imp
builtins.imp = imp

View File

@ -1,4 +1,5 @@
import sys
import imp
# not thread safe
@ -9,11 +10,13 @@ def ModuleType(name):
return sys.modules[name]
# get a new fresh module
import imp_empty_pivot_module as pivot
# be sure to use the builtin func
pivot = imp.__import__('imp_empty_pivot_module') #
# low risk, who would call his module like that ?
del sys.modules['imp_empty_pivot_module']
#still unknown at this time
if hasattr(pivot,'__file__'):
del pivot.__file__
pivot.__name__ = name

View File

@ -208,15 +208,8 @@ STATIC mp_obj_t resource_stream(mp_obj_t package_in, mp_obj_t path_in) {
// package parameter being None, the path_in is interpreted as a
// raw path.
if (package_in != mp_const_none) {
mp_obj_t args[5];
args[0] = package_in;
args[1] = mp_const_none; // TODO should be globals
args[2] = mp_const_none; // TODO should be locals
args[3] = mp_const_true; // Pass sentinel "non empty" value to force returning of leaf module
args[4] = MP_OBJ_NEW_SMALL_INT(0);
// TODO lookup __import__ and call that instead of going straight to builtin implementation
mp_obj_t pkg = mp_builtin___import__(5, args);
// Pass "True" as sentinel value in fromlist to force returning of leaf module
mp_obj_t pkg = mp_import_name(mp_obj_str_get_qstr(package_in), mp_const_true, MP_OBJ_NEW_SMALL_INT(0));
mp_obj_t dest[2];
mp_load_method_maybe(pkg, MP_QSTR___path__, dest);

View File

@ -1335,7 +1335,17 @@ mp_obj_t mp_import_name(qstr name, mp_obj_t fromlist, mp_obj_t level) {
args[3] = fromlist;
args[4] = level;
// TODO lookup __import__ and call that instead of going straight to builtin implementation
#if MICROPY_CAN_OVERRIDE_BUILTINS
// Lookup __import__ and call that if it exists
mp_obj_dict_t *bo_dict = MP_STATE_VM(mp_module_builtins_override_dict);
if (bo_dict != NULL) {
mp_map_elem_t *import = mp_map_lookup(&bo_dict->map, MP_OBJ_NEW_QSTR(MP_QSTR___import__), MP_MAP_LOOKUP);
if (import != NULL) {
return mp_call_function_n_kw(import->value, 5, 0, args);
}
}
#endif
return mp_builtin___import__(5, args);
}