Reputation: 32087
Say I have a package "mylibrary".
I want to make "mylibrary.config" available for import, either as a dynamically created module, or a module imported from an entirely different place that would then basically be "mounted" inside the "mylibrary" namespace.
I.e., I do:
import sys, types
sys.modules['mylibrary.config'] = types.ModuleType('config')
Given that setup:
>>> import mylibrary.config # -> works
>>> from mylibrary import config
<type 'exceptions.ImportError'>: cannot import name config
Even stranger:
>>> import mylibrary.config as X
<type 'exceptions.ImportError'>: cannot import name config
So it seems that using the direct import works, the other forms do not. Is it possible to make those work as well?
Upvotes: 11
Views: 2235
Reputation: 8381
As well as the following:
import sys, types
config = types.ModuleType('config')
sys.modules['mylibrary.config'] = config
You also need to do:
import mylibrary
mylibrary.config = config
Upvotes: 2
Reputation: 37664
You can try something like this:
class VirtualModule(object):
def __init__(self, modname, subModules):
try:
import sys
self._mod = __import__(modname)
sys.modules[modname] = self
__import__(modname)
self._modname = modname
self._subModules = subModules
except ImportError, err:
pass # please signal error in some useful way :-)
def __repr__(self):
return "Virtual module for " + self._modname
def __getattr__(self, attrname):
if attrname in self._subModules.keys():
import sys
__import__(self._subModules[attrname])
return sys.modules[self._subModules[attrname]]
else:
return self._mod.__dict__[attrname]
VirtualModule('mylibrary', {'config': 'actual_module_for_config'})
import mylibrary
mylibrary.config
mylibrary.some_function
Upvotes: 1
Reputation: 127527
You need to monkey-patch the module not only into sys.modules, but also into its parent module:
>>> import sys,types,xml
>>> xml.config = sys.modules['xml.config'] = types.ModuleType('xml.config')
>>> import xml.config
>>> from xml import config
>>> from xml import config as x
>>> x
<module 'xml.config' (built-in)>
Upvotes: 14