<div dir="ltr">I've been thinking about what it takes to replace imp and I realized that imp.load_module() is the hardest to replace for two reasons. One issue is that importlib.abc.create_module() can -- and does -- return None. This means that if someone wanted to replicate the imp.find_module()/imp.load_module() dance in a PEP 451 world it takes::<div>

<br></div><div>  spec = importlib.find_spec(name)</div><div>  try:</div><div>    module = spec.loader.create_module(spec)</div><div>  except AttributeError:</div><div>    module = None</div><div>  if module is None:</div>

<div>    module = types.ModuleType(<a href="http://spec.name">spec.name</a>)</div><div>  # No clear way to set import-related attributes.</div><div>  spec.loader.exec_module(module)</div><div><br></div><div>It took 6 lines to get a module. That seems a bit excessive and ripe to either have an importlib.util function that handles this all correctly or simply make create_module() a required method on a loader and have importlib.abc.create_module() return types.ModuleType(<a href="http://spec.name">spec.name</a>).</div>

<div><br></div><div>The second annoyance is that we have not exposed _SpecMethod.init_module_attrs() in any way. That can either come through in importlib.util or we can make types.ModuleType grow a method that takes a spec and then sets all the appropriate attributes. If we go with the former we should make sure that in importlib we always prefer __spec__ over any module-level values and that one can pass in a spec to types.ModuleType to set __spec__ so that in the distant Python 4 future we can deprecate all module-level attributes and just work off of __spec__.</div>

<div><br></div><div>I think if we can get these two bits cleaned up we can tell people who use imp.load_module() directly that they can::</div><div><br></div><div>  # Assume proper loader chosen.</div><div>  spec = importlib.util.spec_from_loader(loader)</div>

<div>  module = some_newfangled_way_of_doing_this()</div><div>  somehow_init_module_attrs(module)</div><div>  loader.exec_module(module)</div><div><br></div><div>which isn't that bad for something they probably should be avoiding as much as possible to begin with.</div>

<div><br></div><div>Or we take the easiest option and simply ignore all of these issues and just say that working outside of import is not something we want to worry about in the stdlib and let PyPI come up with some utility code that does all of this for you if you really want it. The code maintainer in me is liking this idea + making it easier to set __spec__ on a module through its constructor.</div>

</div>