From 0a96e7b90c0b1e5ba0bf25b0e2aed7b565d69114 Mon Sep 17 00:00:00 2001 From: Alvaro Fuentes Date: Fri, 16 Apr 2021 10:28:30 +0000 Subject: [PATCH] [FIX] core: correct imports from `odoo.addons.base.maintenance.migrations` This legacy package was supposed to be an alias to `odoo.upgrade`. However, depending on how your import its sub-packages (and in which order), we were ending with the module being loaded multiple times, breaking the expectation of a singleton. ```python In [1]: from odoo.addons.base.maintenance.migrations import util as m1 In [2]: import odoo.addons.base.maintenance.migrations.util as m2 In [3]: m1 Out[3]: In [4]: m2 Out[4]: In [5]: from odoo.addons.base.maintenance.migrations import util as m3 In [6]: m3 Out[6]: In [7]: m2 == m3 Out[7]: True In [8]: m1 == m3 Out[8]: False In [9]: ``` Now, with this import hook, we ensure that the modules imported from `odoo.addons.base.maintenance.migrations` are aliases to ones imported from `odoo.upgrade`. ```python In [1]: import odoo.addons.base.maintenance.migrations.util as m2 In [2]: m2.__name__ Out[2]: 'odoo.upgrade.util' ``` closes odoo/odoo#71351 X-original-commit: 0d0458a0f370f872caacac26361f2c4730c2cbba Signed-off-by: Christophe Simonis Co-authored-by: Christophe Simonis --- odoo/modules/module.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/odoo/modules/module.py b/odoo/modules/module.py index 6fcee0700dc..3d10d70ee8d 100644 --- a/odoo/modules/module.py +++ b/odoo/modules/module.py @@ -88,6 +88,32 @@ class OdooHook(object): return sys.modules[name] +class UpgradeHook(object): + """Makes the legacy `migrations` package being `odoo.upgrade`""" + + def find_module(self, name, path=None): + if re.match(r"^odoo.addons.base.maintenance.migrations\b", name): + # We can't trigger a DeprecationWarning in this case. + # In order to be cross-versions, the multi-versions upgrade scripts (0.0.0 scripts), + # the tests, and the common files (utility functions) still needs to import from the + # legacy name. + return self + + def load_module(self, name): + assert name not in sys.modules + + canonical_upgrade = name.replace("odoo.addons.base.maintenance.migrations", "odoo.upgrade") + + if canonical_upgrade in sys.modules: + mod = sys.modules[canonical_upgrade] + else: + mod = importlib.import_module(canonical_upgrade) + + sys.modules[name] = mod + + return sys.modules[name] + + def initialize_sys_path(): """ Setup the addons path ``odoo.addons.__path__`` with various defaults @@ -126,6 +152,7 @@ def initialize_sys_path(): # hook deprecated module alias from openerp to odoo and "crm"-like to odoo.addons if not getattr(initialize_sys_path, 'called', False): # only initialize once + sys.meta_path.insert(0, UpgradeHook()) sys.meta_path.insert(0, OdooHook()) sys.meta_path.insert(0, AddonsHook()) initialize_sys_path.called = True