get_imports(globals) | Return (__all__, __doc__, __imports) describing the dynamically generated list of imports. |
Tools for writing automatic __init__.py files.
This allows modules to define a minimal __init__.py file with some flexibility for delaying imports (for performance) and automatically deducing the local modules. The function get_imports() does all the work and assumes that the module has the following structure:
mod/__init__.py
_mod.py
mod1.py
...
mod2/__init__.py
...
...
_mod3/...
tests/...
These are treated as follows:
- __init__.py :
Should be based on the following skeleton:
from mmf.utils.init import get_imports as __get_imports __delay__ = set([]) # Add modules to delay here. __all__, __doc__, __imports = __get_imports(globals()) exec(__imports) # Remove this to delay everything. del __get_imports, __imports, __delay__If you want to suppress loading of modules (typically for performance) until they are explicitly requested, then add them to the __delay__ set. If you want to suppress the loading of all sub modules, then add the string ‘__all__’ to __delay__: this will still import everything in _mod.py. If you want to suppress this also, then don’t execute __imports and directly import the modules you want.
- _mod.py :
This defines all the members directly defined in the module. The following special attributes are used to control the behaviour of __imports returned by get_imports():
- __all__ :
- If provided, then this is used to define the exported names. Only these names will be imported into the module mod when __imports is executed.
- __dict__ :
- Used if __all__ is not provided. This is consistent with the default behaviour of from mod_ import *.
- __doc__ :
- The docstring for the module is also obtained from the docstring of this file. Note that some automatic documentation is added to the bottom of this for the members that are explicitly included.
- __delay__ :
- If this list is defined, these modules are not explicitly imported. May also contain the special symbol ‘__all__’ which suppress loading all submodules.
The file _mod is not intended to be exported on it’s own, which is why we give a “private” name. If you need access to the private module, you can get it from sys.modules[‘mod._mod’] or set the module flag _INCLUDE_PRIVATE_MODS to True. (This behaviour is implemented by first importing mod._mod and then selectively deleting or keeping the attribute _mod.
The module _mod will be reloaded if the top-level module is reloaded. Thus calling reload(mod) will trigger a call to reload(mod._mod) even though this cannot be effected by the user (since _mod is not in the mod namespace).
- mod1, mod2, ... :
- These are standard modules and will imported in the usual way as import mod1 etc. when __imports is executed unless included in __delay__.
- _mod3 :
- Names stating with an underscore are private and will be ignored unless explicitly included in __all__. Also ignored are names with ‘~’ and ‘#’ which represent temporary files.
- tests :
- These will be ignored.
Specifies whether or not the private module ‘_mod’ is included in the module or not. if True, then it is accessible as mod._mod and the __imports will include:
import _mod
from _mod import *
If False, then only the second line is used and _mod is not part of the module (however, it will be accessible from sys.modules[‘mod._mod’] with a fully qualified module name.
Return (__all__, __doc__, __imports) describing the dynamically generated list of imports. The __init__.py should look like:
from mmf.utils.init import get_imports as __get_imports
__delay__ = set([])
__all__, __doc__, __imports = __get_imports(globals())
exec(__imports) # Remove this to delay everything.
del __get_imports, __imports, __delay__
Parameters : | globals : dict
|
---|---|
Returns : | __all__ : [str]
__doc__ : str
__imports : str
|
Notes
This assumes the following structure:
mod/__init__.py
_mod.py
mod1.py
...
mod2/__init__.py
...
...
_mod3/...
tests/...
These are treated as follows
This defines all the members directly defined in the module. The following special methods are used:
It is not intended to be exported on it’s own, which is why we give a “private” name. If you need access to the private module, you need to get it from sys.modules (or set the module flag _INCLUDE_PRIVATE_MODS to True).
This module will be reloaded if the top-level module is reloaded. Thus calling reload(mod) will trigger a call to reload(mod._mod) even though this cannot be effected by the user (since _mod is not in the mod namespace).