Pyright

共 71 篇文章 · 当前标签「Pyright」

Tony Gu· 2026-10-17 ·Odoo

给 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 去约束"服务层需要的模型接口",也同样做不到:检查器无法确认运行期拿到的模型实例真的满足那个接口。