[IMP] import hook: moved to a proper location (openerp.modules.module instead of...
authorVo Minh Thu <vmt@openerp.com>
Mon, 9 Jan 2012 12:52:43 +0000 (13:52 +0100)
committerVo Minh Thu <vmt@openerp.com>
Mon, 9 Jan 2012 12:52:43 +0000 (13:52 +0100)
bzr revid: vmt@openerp.com-20120109125243-qhtr070dvtc3akb5

openerp-server
openerp/modules/module.py

index c44e690..87e75a5 100755 (executable)
@@ -217,90 +217,6 @@ if __name__ == "__main__":
     check_root_user()
     openerp.tools.config.parse_config(sys.argv[1:])
 
-
-    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('.')
-            if len(module_parts) == 3 and module_name.startswith('openerp.addons.'):
-                return self # We act as a loader too.
-
-            # TODO list of loadable modules can be cached instead of always
-            # calling get_module_path().
-            if len(module_parts) == 1 and \
-                openerp.modules.module.get_module_path(module_parts[0],
-                    display_warning=False):
-                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.addons.<module>.`.""" % (module_name, path))
-                    return
-                except ImportError, e:
-                    # Using `import <module_name>` instead of
-                    # `import openerp.addons.<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):
-
-            module_parts = module_name.split('.')
-            if len(module_parts) == 3 and module_name.startswith('openerp.addons.'):
-                module_part = module_parts[2]
-                if module_name in sys.modules:
-                    return sys.modules[module_name]
-
-            if len(module_parts) == 1:
-                module_part = module_parts[0]
-                if module_part in sys.modules:
-                    return sys.modules[module_part]
-
-            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.addons.<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)
-            if not is_shadowing:
-                sys.modules[module_part] = mod
-            sys.modules['openerp.addons.' + module_part] = mod
-            return mod
-
-    openerp.modules.module.initialize_sys_path()
-    sys.meta_path.append(ImportHook())
-
     check_postgres_user()
     openerp.netsvc.init_logger()
     report_configuration()
index 5c50384..1e46d3c 100644 (file)
@@ -56,6 +56,91 @@ loaded = []
 
 logger = netsvc.Logger()
 
+class AddonsImportHook(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.
+
+    Instead of relying on some addons path, an alternative approach would be
+    to use pkg_resources entry points from already installed Python libraries
+    (and install our addons as such). Even when implemented, we would still
+    have to support the addons path approach for backward compatibility.
+    """
+
+    def find_module(self, module_name, package_path):
+        module_parts = module_name.split('.')
+        if len(module_parts) == 3 and module_name.startswith('openerp.addons.'):
+            return self # We act as a loader too.
+
+        # TODO list of loadable modules can be cached instead of always
+        # calling get_module_path().
+        if len(module_parts) == 1 and \
+            get_module_path(module_parts[0],
+                display_warning=False):
+            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.addons.<module>.`.""" % (module_name, path))
+                return
+            except ImportError, e:
+                # Using `import <module_name>` instead of
+                # `import openerp.addons.<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):
+
+        module_parts = module_name.split('.')
+        if len(module_parts) == 3 and module_name.startswith('openerp.addons.'):
+            module_part = module_parts[2]
+            if module_name in sys.modules:
+                return sys.modules[module_name]
+
+        if len(module_parts) == 1:
+            module_part = module_parts[0]
+            if module_part in sys.modules:
+                return sys.modules[module_part]
+
+        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.addons.<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, ad_paths)
+        mod = imp.load_module(module_name, f, path, descr)
+        if not is_shadowing:
+            sys.modules[module_part] = mod
+        sys.modules['openerp.addons.' + module_part] = mod
+        return mod
+
 def initialize_sys_path():
     """ Add all addons paths in sys.path.
 
@@ -68,7 +153,7 @@ def initialize_sys_path():
 
     ad_paths = map(lambda m: os.path.abspath(tools.ustr(m.strip())), tools.config['addons_path'].split(','))
     ad_paths.append(_ad) # for get_module_path
-
+    sys.meta_path.append(AddonsImportHook())
 
 def get_module_path(module, downloaded=False, display_warning=True):
     """Return the path of the given module.