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

Reply via email to