New submission from David Beazley: I have been investigating some of the new importlib machinery and the addition of ModuleSpec objects. I am a little curious about the intended handling of C Extension modules going forward.
Backing up for a moment, consider a pure Python module. It seems that I can do things like this to bring a module into existence (some steps involving sys.modules omitted). >>> from importlib.util import find_spec, module_from_spec >>> spec = find_spec('socket') >>> socket = module_from_spec(spec) >>> spec.loader.exec_module(socket) >>> However, it all gets "weird" with C extension modules. For example, you can perform the first few steps: >>> spec = find_spec('math') >>> spec ModuleSpec(name='math', loader=<_frozen_importlib.ExtensionFileLoader object at 0x1012122b0>, origin='/usr/local/lib/python3.5/lib-dynload/math.so') >>> math = module_from_spec(spec) >>> math <module 'math' from '/usr/local/lib/python3.5/lib-dynload/math.so'> >>> dir(math) ['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__'] As you can see, you get a fresh "unloaded" module here. However, if you try to bring in the module contents, things get screwy. >>> spec.loader.exec_module(math) Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'ExtensionFileLoader' object has no attribute 'exec_module' >>> Yes, this is the old legacy interface in action--there is no exec_module() method. You can always fall back to load_module() like this: >>> spec.loader.load_module(spec.name) <module 'math' from '/usr/local/lib/python3.5/lib-dynload/math.so'> >>> The problem here is that it creates a brand new module and ignores the one that was previously created by module_from_spec(). That module is still empty: >>> dir(math) ['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__'] >>> I realize that I'm treading into a swamp of legacy interfaces and some pretty complex machinery here. However, here's my question: are C extension modules always going to be a special case that need to be considered code that interacts with the import system. Specifically, will it need to be special-cased to use load_module() instead of the module_from_spec()/exec_module() combination? I suppose the question might also apply to built-in and frozen modules as well (although I haven't investigated that so much). Mainly, I'm just trying to gain some insight from the devs as to the overall direction where the import implementation is going with this. P.S. ModuleSpecs are cool. +1 ---------- components: Interpreter Core messages: 237872 nosy: dabeaz priority: normal severity: normal status: open title: Interaction of ModuleSpec and C Extension Modules type: behavior versions: Python 3.5 _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue23642> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com