diff --git a/odoo/modules/module.py b/odoo/modules/module.py index 959019d56e815913d1b56f68bf9bd9854073a781..f545a72010980407620c5e7e461658b20b4aa8ff 100644 --- a/odoo/modules/module.py +++ b/odoo/modules/module.py @@ -8,10 +8,13 @@ import inspect import itertools import logging import os +import pkg_resources +import re import sys import time import unittest import threading +import warnings from os.path import join as opj import odoo @@ -24,9 +27,76 @@ README = ['README.rst', 'README.md', 'README.txt'] _logger = logging.getLogger(__name__) +# addons path as a list +# ad_paths is a deprecated alias, please use odoo.addons.__path__ +@tools.lazy +def ad_paths(): + warnings.warn( + '"odoo.modules.module.ad_paths" is a deprecated proxy to ' + '"odoo.addons.__path__".', DeprecationWarning, stacklevel=2) + return odoo.addons.__path__ + # Modules already loaded loaded = [] +class AddonsHook(object): + """ Makes modules accessible through openerp.addons.* """ + + def find_module(self, name, path=None): + if name.startswith('openerp.addons.') and name.count('.') == 2: + warnings.warn( + '"openerp.addons" is a deprecated alias to "odoo.addons".', + DeprecationWarning, stacklevel=2) + return self + + def load_module(self, name): + assert name not in sys.modules + + odoo_name = re.sub(r'^openerp.addons.(\w+)$', r'odoo.addons.\g<1>', name) + + odoo_module = sys.modules.get(odoo_name) + if not odoo_module: + odoo_module = importlib.import_module(odoo_name) + + sys.modules[name] = odoo_module + + return odoo_module + +# need to register loader with setuptools as Jinja relies on it when using +# PackageLoader +pkg_resources.register_loader_type(AddonsHook, pkg_resources.DefaultProvider) + +class OdooHook(object): + """ Makes odoo package also available as openerp """ + + def find_module(self, name, path=None): + # openerp.addons.<identifier> should already be matched by AddonsHook, + # only framework and subdirectories of modules should match + if re.match(r'^openerp\b', name): + warnings.warn( + 'openerp is a deprecated alias to odoo.', + DeprecationWarning, stacklevel=2) + return self + + def load_module(self, name): + assert name not in sys.modules + + canonical = re.sub(r'^openerp(.*)', r'odoo\g<1>', name) + + if canonical in sys.modules: + mod = sys.modules[canonical] + else: + # probable failure: canonical execution calling old naming -> corecursion + mod = importlib.import_module(canonical) + + # just set the original module at the new location. Don't proxy, + # it breaks *-import (unless you can find how `from a import *` lists + # what's supposed to be imported by `*`, and manage to override it) + sys.modules[name] = mod + + return sys.modules[name] + + def initialize_sys_path(): """ Setup the addons path ``odoo.addons.__path__`` with various defaults @@ -67,6 +137,12 @@ def initialize_sys_path(): sys.modules["odoo.addons.base.maintenance"] = maintenance_pkg sys.modules["odoo.addons.base.maintenance.migrations"] = upgrade + # hook deprecated module alias from openerp to odoo and "crm"-like to odoo.addons + if getattr(initialize_sys_path, 'called', False): # only initialize once + sys.meta_path.insert(0, OdooHook()) + sys.meta_path.insert(0, AddonsHook()) + + def get_module_path(module, downloaded=False, display_warning=True): """Return the path of the given module.