From 1560538f8a336e9e44c35bc8fd9b48b7bc2a2d82 Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Mon, 9 Jan 2012 13:31:23 +0100 Subject: [PATCH] [IMP] module: use the `openerp.addons.` namespace to load addons. (openerp.modules will be changed in openerp.addons in the next commit). bzr revid: vmt@openerp.com-20120109123123-jt3canjbg0ozs05j --- openerp-server | 61 ++++++++++++++++++++++++++++++--------- openerp/modules/module.py | 2 +- 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/openerp-server b/openerp-server index 641bc7e97e2..44ba179830d 100755 --- a/openerp-server +++ b/openerp-server @@ -219,6 +219,28 @@ if __name__ == "__main__": class ImportHook(object): + """ + Import hook to load OpenERP addons from multiple paths. + + OpenERP implements its own import-hook to load its addons. OpenERP + addons are Python modules. Originally, they were each living in their + own top-level namespace, e.g. the sale module, or the hr module. For + backward compatibility, `import ` is still supported. Now they + are living in `openerp.addons`. The good way to import such modules is + thus `import openerp.addons.module`. + + For backward compatibility, loading an addons puts it in `sys.modules` + under both the legacy (short) name, and the new (longer) name. This + ensures that + import hr + import openerp.addons.hr + loads the hr addons only once. + + When an OpenERP addons name clashes with some other installed Python + module (for instance this is the case of the `resource` addons), + obtaining the OpenERP addons is only possible with the long name. The + short name will give the expected Python module. + """ def find_module(self, module_name, package_path): module_parts = module_name.split('.') @@ -230,7 +252,20 @@ if __name__ == "__main__": if len(module_parts) == 1 and \ openerp.modules.module.get_module_path(module_parts[0], display_warning=False): - return self # We act as a loader too. + try: + # Check if the bare module name clashes with another module. + f, path, descr = imp.find_module(module_parts[0]) + logger = logging.getLogger('init') + logger.warning(""" + Ambiguous import: the OpenERP module `%s` is shadowed by another + module (available at %s). + To import it, use `import openerp.modules..`.""" % (module_name, path)) + return + except ImportError, e: + # Using `import ` instead of + # `import openerp.modules.` is ugly but not harmful + # and kept for backward compatibility. + return self # We act as a loader too. def load_module(self, module_name): @@ -245,21 +280,21 @@ if __name__ == "__main__": if module_part in sys.modules: return sys.modules[module_part] - try: - # Check if the bare module name clashes with another module. - f, path, descr = imp.find_module(module_part) - logger = logging.getLogger('init') - logger.warning(""" - Ambiguous import: the OpenERP module `%s` is shadowing another module - (available at %s).""" % (module_name, path)) - except ImportError, e: - # Using `import ` instead of - # `import openerp.modules.` is ugly but not harmful. - pass + try: + # Check if the bare module name shadows another module. + f, path, descr = imp.find_module(module_part) + is_shadowing = True + except ImportError, e: + # Using `import ` instead of + # `import openerp.modules.` is ugly but not harmful + # and kept for backward compatibility. + is_shadowing = False + # Note: we don't support circular import. f, path, descr = imp.find_module(module_part, openerp.modules.module.ad_paths) mod = imp.load_module(module_name, f, path, descr) - sys.modules[module_part] = mod + if not is_shadowing: + sys.modules[module_part] = mod sys.modules['openerp.modules.' + module_part] = mod return mod diff --git a/openerp/modules/module.py b/openerp/modules/module.py index 936c798767a..a5c432722ea 100644 --- a/openerp/modules/module.py +++ b/openerp/modules/module.py @@ -314,7 +314,7 @@ def register_module_classes(m): try: zip_mod_path = mod_path + '.zip' if not os.path.isfile(zip_mod_path): - __import__(m) + __import__('openerp.modules.' + m) else: zimp = zipimport.zipimporter(zip_mod_path) zimp.load_module(m)