@@ -1264,28 +1264,66 @@ def code2parts(code):
12641264 else :
12651265 return [unparse (ast1 .body [:- 1 ]), expr ]
12661266
1267+ from collections import defaultdict
12671268
1268- def _make_codepod ():
1269- d = {}
1269+ d = {}
12701270
1271- def getmod (ns ):
1272- if ns not in d :
1273- d [ns ] = types .ModuleType (ns )
1274- # for testing purpose
1275- d [ns ].__dict__ ["CODEPOD_GETMOD" ] = getmod
1276- return d [ns ]
1271+ """
1272+ here's the new plan for python's eval
12771273
1278- def eval_func (code , ns ):
1279- # the codepod(code) is the program sent to backend
1280- # codepod is defined on the kernel
1281- mod = getmod (ns )
1282- [stmt , expr ] = code2parts (code )
1283- if stmt :
1284- exec (stmt , mod .__dict__ )
1285- if expr :
1286- return eval (expr , mod .__dict__ )
1274+ Python's module is closely bound to the file system, so it is not possible to use that.
12871275
1288- return eval_func , getmod
1276+ I have to use my own globals and locals during exec/eval.
12891277
1278+ Then, I'll just record the calling relationships for the modules. When evaluating, I'll:
12901279
1291- CODEPOD_EVAL , CODEPOD_GETMOD = _make_codepod ()
1280+ 1. eval_func(code, nses)
1281+ - nses is a list of namespaces in order, the last one is this ns
1282+ - that should be it. The question is where to compute nses. I would
1283+ 1. compute it when powerRunTree
1284+ 2. let the kernel knows it by using CODEPOD_ADD_IMPORT. The kernel will record this.
1285+ """
1286+
1287+ # from ns to nses that should imported
1288+ import_d = defaultdict (set )
1289+ # from ns to exported names
1290+ export_d = defaultdict (set )
1291+ # from ns to subdeck nses
1292+ export_sub_d = defaultdict (set )
1293+
1294+ def CODEPOD_GETMOD (ns ):
1295+ if ns not in d :
1296+ d [ns ] = types .ModuleType (ns )
1297+ return d [ns ]
1298+
1299+ def merge_dicts (dicts ):
1300+ """
1301+ Given any number of dictionaries, shallow copy and merge into a new dict,
1302+ precedence goes to key-value pairs in latter dictionaries.
1303+ """
1304+ result = {}
1305+ for dictionary in dicts :
1306+ result .update (dictionary )
1307+ return result
1308+
1309+ def CODEPOD_ADD_IMPORT (FROM , TO ):
1310+ import_d [TO ].add (FROM )
1311+ def CODEPOD_REMOVE_IMPORT (FROM , TO ):
1312+ if FROM in import_d [TO ]:
1313+ import_d [TO ].remove (FROM )
1314+ def CODEPOD_SET_EXPORT (ns , exports ):
1315+ export_d [ns ] = exports
1316+ def CODEPOD_SET_EXPORT_SUB (ns , nses ):
1317+ export_sub_d [ns ] = nses
1318+
1319+ def CODEPOD_EVAL (code , ns ):
1320+ # the codepod(code) is the program sent to backend
1321+ # codepod is defined on the kernel
1322+ mod = CODEPOD_GETMOD (ns )
1323+ [stmt , expr ] = code2parts (code )
1324+ _dict = merge_dicts ([{k :v for k ,v in CODEPOD_GETMOD (x ).__dict__ .items () if k in export_d [x ]} for x in import_d [ns ]]
1325+ + [{k :v for k ,v in CODEPOD_GETMOD (x ).__dict__ .items () if k in export_d [x ]} for ns1 in export_sub_d [ns ] for x in import_d [ns1 ]])
1326+ if stmt :
1327+ exec (stmt , _dict , mod .__dict__ )
1328+ if expr :
1329+ return eval (expr , _dict , mod .__dict__ )
0 commit comments