removed-odoo-method-call (ODE9503)
Preview (since 0.16.3.34) · Related issues · View source
Derived from the odoo linter.
This rule is unstable and in preview. The --preview flag is required for use.
What it does
Checks for calls to ORM model methods that no longer exist in the configured
odoo-version.
Why is this bad?
Odoo deletes model methods between releases, most of them without a deprecation cycle:
name_get, user_has_groups and copy_multi went in 18.0, _where_calc,
clear_caches and _apply_ir_rules in 19.0. The call sites keep reading as valid Python
and raise AttributeError the first time the line runs, which on a portal controller or
a report means the branch nobody exercised during the migration.
Nothing else finds these. deprecated-odoo-method-call
only knows the handful of methods Odoo marked @api.deprecated, and
invalid-odoo-method-call binds arguments against a
signature, so it goes quiet on exactly the methods that no longer have one.
The removal set is generated from Odoo's own source by
scripts/generate_odoo_model_stubs.py, which subtracts every name Odoo still defines
on some class before calling a method gone. That is what keeps two shapes out of it: a
method that moved, like _condition_to_sql leaving BaseModel for Field in 19.0, and
a name too ordinary to judge from the name alone, like refresh, which the ORM dropped
in 17.0 and a hardware driver's browser still answers to.
The check needs a removal set to look in, so it reports nothing unless odoo-version is
set to a version this linter ships one for. Since that silence is indistinguishable from
a clean run, it warns once on stderr when the setting is missing or names a version with
no set; the run still succeeds, and the warning only appears when this rule is enabled.
Scope
Any receiver counts, inside any class that inherits something which is not a Python builtin. Unlike the argument-binding rules there is no need to prove the receiver is a recordset: these names no longer exist anywhere in Odoo, so a call to one is either an ORM call that breaks or a name the project defined itself, and the second is checked for. That is what reaches the shape the migrations actually leave behind, a model looked up into a local:
A class that defines the method itself keeps its call, since the call means that
definition rather than Odoo's. A class inheriting only object, Exception or another
builtin is left alone: it is Python, not Odoo.
Example
class SaleOrder(models.Model):
_inherit = "sale.order"
def matching(self, domain):
return self._where_calc(domain)
Use instead: