让mypy明白,该属性不是None

问题描述 投票:0回答:1

我的环境的快速描述:

- django                      4.2.11
- mypy                        1.9.0
- django-stubs                4.2.5

这是我在下面制作的综合示例,仅供该帖子使用,请不要根据名称的含义等来判断我。重点是如何处理 mypy 错误...

我有两个模型,一个通过ForeignKey引用另一个模型:

class Author(models.Model):
    name = models.CharField()

class Book(models.Model):
    author = models.ForeignKey(Author, blank=False, null=True, ...)

然后我有一组类似的函数,对于每个函数都有一个规则:我们检查,该作者不是 None,如果是 - 则引发错误:ImproperlyConfigured:

def _check_configuration(book: Book) -> None:
    if not book.author:
        raise ImproperlyConfigured()

def func1(book: Book) -> int:
    _check_configuration(book)
    ....
    author_name = book.author.name  # here it comes...

def func2(book: Book) -> str:
    _check_configuration(book)
    ....

出于 DRY 目的,我使用验证功能。如果我将

if book.author is None...
直接放入 func1 - 那么错误就会消失。

这是错误:

error: ... "Author | None" has no attribute "name" [union-attr]

如何向mypy解释作者肯定不是None?

谢谢!

ChatGPT 和谷歌搜索。 ChatGPT 返回关于该问题的愚蠢建议,对于 Google,我什至无法制定请求,我尝试过的一切 - 引导我解决另一个问题...

python django-models mypy python-typing
1个回答
0
投票

对于像这样简单的检查,我将使用断言 - 您可以使用自定义错误,类型检查器可以推断键入信息,并且重复的行几乎不再存在(我使用下面的数据类来呈现示例) ,但它适用于任何东西):

from dataclasses import dataclass

@dataclass
class Author:
    name: str

@dataclass
class Book:
    author: Author | None

class ImproperlyConfigured(ValueError):
    pass

def func1(book: Book) -> str:
    assert book.author, ImproperlyConfigured
    author_name = book.author.name
    return author_name

func1(Book(None))
© www.soinside.com 2019 - 2024. All rights reserved.