invalid-odoo-method-call (ODE9502)
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 calls to Odoo ORM model methods against the parameter list the method actually
has in the configured odoo-version.
Why is this bad?
Odoo reshapes ORM signatures between releases, and the call sites do not fail until the
line runs. read_group is the extreme case: 20.0 reused the freed name for a different
method, so self.read_group(domain, fields, groupby, lazy=False) raises
TypeError: got an unexpected keyword argument 'lazy' there while reading as valid code.
The same happens more quietly elsewhere — _search dropped access_rights_uid in 18.0,
name_search renamed args to domain in 19.0 — and a migration has no way to find
them short of running every branch.
The check needs signatures to compare against, so it reports nothing unless odoo-version
is set to a version this linter ships a stub 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 signatures; the run still succeeds, and the warning only appears when this rule is
enabled.
Only receivers that are certainly recordsets are checked: self and super() inside a
model class, env[...] subscripts anywhere, and chains of recordset-returning ORM calls
over either, so self.env["res.partner"].sudo().search(...) is covered. A local is not,
because nothing distinguishes one holding a recordset from one holding a worksheet. A
method the file defines itself is left alone too, since the call may well mean that
override rather than Odoo's -- except through env["other.model"], which reaches a model
the override says nothing about.
Known limitation
The check binds arguments; it does not know that a name changed meaning. Where Odoo reused a freed name for a method of the same arity, a fully positional call still binds and is not reported, even though every argument now lands on a different parameter:
# Silent on 20.0: seven positionals against a signature that takes seven.
super().read_group(domain, fields, groupby, offset, limit, orderby, lazy)
Nothing in that call distinguishes it from correct 20.0 code, so reporting it would land
on code that is right. Naming a repurposed method is
deprecated-odoo-method-call's job, not this one's.
Example
Use instead: