Published On: 1970-01-01|Last Updated: 1970-01-01|Categories: Uncategorized|
Python で compile などによって得られた code object を module に変換するには以下のようにします。

PyImport_ExecCodeModuleEx を Python で書き直したようなものです。

import sys
import imp
def codeimport(dottedname, code, filename = ''):
if not isinstance(code, type(compile('None', '', 'eval'))):
raise ValueError, 'The argument \'code\' is not code object.'
if not dottedname and not isinstance(dottedname, str):
raise ValueError, 'The argument \'dottedname\' is invalid.'
if dottedname in sys.modules:
module = sys.modules[dottedname]
else:
module = imp.new_module(dottedname)
sys.modules[dottedname] = module
if '__builtins__' not in module.__dict__:
module.__dict__['__builtins__'] = sys.modules['__builtin__']
if not filename:
filename = code.co_filename
module.__file__ = filename
exec code in module.__dict__
return module

キモは exec code in module.__dict__ で module.__dict__ という名前空間に code で実行した結果がバインドされる、みたいな感じです。

モジュールの内部空間を書き換え放題なわけが分かりました。

code object は compile したり、トレースバックから取得したり、.pyc から 8 バイト読み飛ばして marshal.loads したりすれば出てきます。

関連