Ok but figuring out what executes code might require executing code: consider non trivial use of meta classes, where an inconspicuous subclass actually invokes e.g. A registration process like a Django model class.
In any case, given your points, it seems like a future Python version ought to introduce a new version of the import statement with lazy semantics (which, besides eliminating dead code, is also IMO the more correct/explicit behavior when importing symbols).
class LazyModule:
def __init__(self, name):
self.name = name
def __getattr__(self, key):
mod = {}
exec('import %s as mod', mod)
self.mod = mod['mod']
return getattr(self.mod, key)
class LazyImporter:
def get_module(self, name):
return LazyModule(name)