In Python, it is easy to check if an object is a module with isinstance(obj, types.ModuleType)
. We can also programmatically generate modules. I am however interested in going the other way around - generating code that would have created an import resulting in the module being added the globals/locals namespace. Basically a function assemble_import
like this:
def assemble_import(module: types.ModuleType, name: str) -> str:
pass
Roughly satisfying following conditions:
import statistics
assert assemble_import(statistics, 'statistics') = 'import statistics'
from os import path
assert assemble_import(path, 'path') = 'from os import path'
import collections.abc
abc = collections.abc
assert assemble_import(abc, 'abc') = 'from collections import abc'
import abc as xyz
assert assemble_import(xyz, 'xyz') = 'import abc as xyz'
I would not want it to use the abstract syntax tree, but rather the module object itself. What I have tried to so far:
module.__spec__
- it returnsModuleSpec
with the name attributemodule.__package__
- not sure why but is empty most of the timemodule.__loader__
- usuallySourceFileLoader
, also has the name attribute
the problem with the name attribute is that it is 'posixpath' for os.path
, while from os import posixpath
clearly does not work. Also, I do not see how to get the parent module (os
in the os.path
example).
Is achieving a workable (though not necessarily a production-ready/bulletproof) solution possible in Python? In other words, is the information about packages structure needed to recreate the imports code preserved/accessible?