簡體   English   中英

如何在不破壞“attrs”驗證器 function 的情況下注釋它?

[英]How do I annotate an `attrs` validator function without breaking it?

使用 attrs 庫,我可以為屬性值定義一個驗證器:

from attrs import define, field

def is_odd(inst, attr, value):
    if value % 2 == 1:
        return None

    raise ValueError("Only odd values allowed")

@define
class Foo:
  bar = field(validator=is_odd)

Foo(1)
Foo(2)

Foo(1)實例化成功,而Foo(2)實例化失敗並出現ValueError ,如預期的那樣。

不出所料,這段代碼不進行類型檢查(根據mypy --strict ):

foo.py:3:1: error: Function is missing a type annotation  [no-untyped-def]
    def is_odd(inst, attr, value):
    ^
foo.py:11:3: error: Need type annotation for "bar"  [var-annotated]
      bar = field(validator=is_odd)
      ^
Found 2 errors in 1 file (checked 1 source file)

但是,我不知道如何注釋它以便它這樣做。 天真的第一次嘗試可能看起來像:

from attrs import Attribute, define, field

def is_odd(inst: object, attr: Attribute, value: int) -> None:
    if value % 2 == 1:
        return None

    raise ValueError("Only odd values allowed")

@define
class Foo:
  bar: int = field(validator=is_odd)

Foo(1)
Foo(2)

但是mypy --strict報告此錯誤:

foo.py:3:32: error: Missing type parameters for generic type "Attribute"  [type-arg]

這可以通過提供缺少的類型參數來解決:

from attrs import Attribute, define, field

def is_odd(inst: object, attr: Attribute[int], value: int) -> None:
    if value % 2 == 1:
        return None

    raise ValueError("Only odd values allowed")

@define
class Foo:
  bar: int = field(validator=is_odd)

Foo(1)
Foo(2)

這滿足了mypy:

Success: no issues found in 1 source file

但是,該程序現在在運行時被破壞:

Traceback (most recent call last):
  File "foo.py", line 3, in <module>
    def is_odd(inst: object, attr: Attribute[int], value: int) -> None:
TypeError: 'type' object is not subscriptable

如何在運行時使程序正確並在mypy --strict下進行類型檢查(不只是添加“忽略”注釋來消除錯誤)?

如此Github 問題中所述,引用類型注釋:

from attrs import Attribute, define, field


def is_odd(inst: object, attr: "Attribute[int]", value: int) -> None:
    if value % 2 == 1:
        return None

    raise ValueError("Only odd values allowed")


@define
class Foo:
    bar: int = field(validator=is_odd)


Foo(1)
Foo(2)

或使用from __future__ import annotations

from __future__ import annotations

from attrs import Attribute, define, field


def is_odd(inst: object, attr: Attribute[int], value: int) -> None:
    if value % 2 == 1:
        return None

    raise ValueError("Only odd values allowed")


@define
class Foo:
    bar: int = field(validator=is_odd)


Foo(1)
Foo(2)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM