Using the deprecated module imp
, I can write a custom import hook that modifies the source code of a module on the fly, prior to importation/execution by Python. Given the source code as a string named source
below, the essential code needed to create a module is the following:
module = imp.new_module(name)
sys.modules[name] = module
exec(source, module.__dict__)
Since imp
is deprecated, I would like to do something similar with importlib
. [EDIT: there are other imp
methods that need to be replaced to build a custom import hook - so the answer I am looking for is not simply to replace the above code.]
However, I have not been able to figure out how to do this. The importlib documentation has a function to create modules from "specs" which, as far as I can tell, are objects that include their own loaders with no obvious way to redefine them so as to be able to create a module from a string.
I have created a minimal example to demonstrates this; see the readme file for details.
find_module
andload_module
are both deprecated. You'll need to switch tofind_spec
and (create_module
andexec_module
) module respectively. See theimportlib
documentation for details.You will also need to examine if you want to use a
MetaPathFinder
or aPathEntryFinder
as the system to invoke them is different. That is, the meta path finder goes first and can override builtin modules, whereas the path entry finder works specifically for modules found onsys.path
.The following is a very basic importer that attempts to replace the entire import machinery for. It shows how to use the functions (
find_spec
,create_module
, andexec_module
).Next is a slightly more delicate version that attempts to reuse more of the import machinery. As such, you only need to define how to get the source of the module.