I'm am attempting to setup some import hooks through sys.meta_path
, in a somewhat similar approach to this SO question. For this, I need to define two functions find_module
and load_module
as explained in the link above. Here is my load_module
function,
import imp
def load_module(name, path):
fp, pathname, description = imp.find_module(name, path)
try:
module = imp.load_module(name, fp, pathname, description)
finally:
if fp:
fp.close()
return module
which works fine for most modules, but fails for PyQt4.QtCore
when using Python 2.7:
name = "QtCore"
path = ['/usr/lib64/python2.7/site-packages/PyQt4']
mod = load_module(name, path)
which returns,
Traceback (most recent call last):
File "test.py", line 19, in <module>
mod = load_module(name, path)
File "test.py", line 13, in load_module
module = imp.load_module(name, fp, pathname, description)
SystemError: dynamic module not initialized properly
The same code works fine with Python 3.4 (although imp
is getting deprecated and importlib
should ideally be used instead there).
I suppose this has something to do with the SIP dynamic module initialization. Is there anything else I should try with Python 2.7?
Note: this applies both with PyQt4
and PyQt5
.
Edit: this may be related to this question as indeed,
cd /usr/lib64/python2.7/site-packages/PyQt4
python2 -c 'import QtCore'
fails with the same error. Still I'm not sure what would be a way around it...
Edit2: following @Nikita's request for a concrete use case example, what I am trying to do is to redirect the import, so when one does import A
, what happens is import B
. One could indeed think that for this it would be sufficient to do module renaming in find_spec/find_module
and then use the default load_module
. However, it is unclear where to find a default load_module
implementation in Python 2. The closest implementation I have found of something similar is future.standard_library.RenameImport
. It does not look like there is a backport of the complete implementation of importlib
from Python 3 to 2.
A minimal working example for the import hooks that reproduces this problem can be found in this gist.
__import__('PyQt4.QtCore')
. does it lead to infinite recursion? – Culinarian__import__('A')
, but it is equivalent to usingimport A
. What I want is to change what happens when you do that, and in particular runimport B
, when youimport A
. This can be done with import hooks insys.meta_path
, but they require lower level functions such asimp.load_module
. – Vidavidalimporylib
in Python 2.7 it's written: "This module is a minor subset of what is available in the more full-featured package of the same name from Python 3.1 that provides a complete implementation of import.". There're thoughts about custom imports in PEP302, I'll look at it and share my thoughts in the answer update. – Shaveling