给 Odoo 补上静态类型:odoo-typegen
Odoo 的模型是运行时拼装出来的:一个模型由多个 addon 通过 _inherit 不断扩展,最后在 registry 里合成。这带来一个副作用——静态类型检查器看不见它。
问题在哪
Python 的类型检查器(Pyright、mypy)靠继承关系推断类型。但 Odoo 扩展模型并不靠 Python 继承:
class CrmLead(models.Model):
_inherit = "crm.lead"
@api.model
def attach_source(self, partner_id: int, source: str) -> None:
...
在检查器眼里,env["crm.lead"] 的类型永远是 BaseModel:它不知道这个模型上还有什么方法。
于是你想调用别处加进来的方法时,编辑器只能这样报错:
class ResPartner(models.Model):
_inherit = "res.partner"
def action_mark_referral(self) -> None:
leads = self.env["crm.lead"]
leads.attach_source(partner_id=self.id, source="referral")
# Pyright: Cannot access member "attach_source" for type "BaseModel"
⚠️ 关键在这条报错的含义:它不是说方法不存在,而是检查器不知道这个模型上有什么。
于是你既得不到补全,也得不到校验——写错参数名、传错类型,它都不会提醒你,只能整段 # type: ignore 掉。
如果你想再进一步,用 Protocol 去约束"服务层需要的模型接口",也同样做不到:检查器无法确认运行期拿到的模型实例真的满足那个接口。