Skip to content

inheritable-method-lambda (ODE8148)

Preview (since 0.16.2.2) · Related issues · View source

Derived from the odoo linter.

Fix is always available.

This rule is unstable and in preview. The --preview flag is required for use.

What it does

Checks for default=/domain= field arguments that pass a direct method reference instead of a lambda.

Why is this bad?

A direct reference hardcodes the field to that exact function object at class-definition time. When another module inherits the model and overrides the method, the field keeps calling the original function and the override is silently ignored. Unlike compute=/search=/inverse= (see inheritable-method-string), these attributes do not accept a method name as a string — Odoo only accepts a plain value or a callable here — so a lambda that dispatches through self is what preserves inheritability.

This is not a theoretical concern: odoo/odoo#185419 un-hardcoded the domain= methods of the Sales Order Item fields for exactly this reason, and odoo/enterprise#72931 shows the follow-up — once the method became inheritable, an inheriting module's override that had been silently ignored started being called and had to be adapted.

Example

company_id = fields.Many2one("res.company", default=_default_company)

Use instead:

company_id = fields.Many2one(
    "res.company", default=lambda self: self._default_company()
)

Fix safety

The fix wraps the reference in lambda self: self.<name>(). Odoo calls the callable of these attributes with the record as its only argument, so the lambda calls the same method with the same argument the direct reference already received. The rule only fires when the enclosing class defines a method with that name, so the call resolves to a method that exists. The fix is still marked as unsafe because dispatch changes from the bound function object to a name lookup on the record: a subclass override starts being honored (the point of the rule), and if the reference actually pointed at a same-named object from an outer scope — for example an imported function shadowed by a method defined further down the class — the class method replaces it.

References