[FIX] base: mark modules as uninstalled before gutting them

Before this, uninstalling the `payment` module (or any of its
dependencies) is broken: as payment.provider has a dependency on
ir.module.module.state, marking the modules causes a lookup of the
payment provides to update, but the table was removed by
`_module_data_uninstall`, so the lookup blows up.

This is a consequence of odoo/odoo#111651 which improved and optimised
triggers but dropped the in-place cleanup of the triggers tree.

Thus while the columns & tables get removed from the database the
in-memory structures (registry, models, fields, ..., as well as the
trigger and dependency caches) are not so the python side will happily
try to look up stuff which has been nuked if accessed at the wrong
moment (which is any moment between the start of
`_module_data_uninstall` and the creation of a new registry, really).

As `_module_data_uninstall` is nothing but a giant pile of dodgy state
anyway, making modules as uninstalled before it executes doesn't seem
like a huge deal. It may cause unnecessary extra recomputation for the
few models which depend on modules, but that doesn't seem like a major
issue, at worst it makes uninstallation a touch slower but they're not
a huge performance concern at the moment (they're more of a
correctness one).

closes odoo/odoo#118959

X-original-commit: 460efeb623ec62c980d187710bd4e7614af0e7bd
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
This commit is contained in:
Xavier Morel
2023-04-19 12:13:32 +02:00
parent 1902beb621
commit 98b5505305
+1 -1
View File
@@ -483,9 +483,9 @@ class Module(models.Model):
tables, columns, constraints, etc.
"""
modules_to_remove = self.mapped('name')
self.env['ir.model.data']._module_data_uninstall(modules_to_remove)
# we deactivate prefetching to not try to read a column that has been deleted
self.with_context(prefetch_fields=False).write({'state': 'uninstalled', 'latest_version': False})
self.env['ir.model.data']._module_data_uninstall(modules_to_remove)
return True
def _remove_copied_views(self):