[IMP] module: use the `openerp.addons.` namespace to load addons.
authorVo Minh Thu <vmt@openerp.com>
Mon, 9 Jan 2012 12:31:23 +0000 (13:31 +0100)
committerVo Minh Thu <vmt@openerp.com>
Mon, 9 Jan 2012 12:31:23 +0000 (13:31 +0100)
(openerp.modules will be changed in openerp.addons in the next commit).

bzr revid: vmt@openerp.com-20120109123123-jt3canjbg0ozs05j

openerp-server
openerp/modules/module.py

index 641bc7e..44ba179 100755 (executable)
@@ -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 <module>` 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>.`.""" % (module_name, path))
+                    return
+                except ImportError, e:
+                    # Using `import <module_name>` instead of
+                    # `import openerp.modules.<module_name>` 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 <module_name>` instead of
-                    # `import openerp.modules.<module_name>` 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 <module_name>` instead of
+                # `import openerp.modules.<module_name>` 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
 
index 936c798..a5c4327 100644 (file)
@@ -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)