Python 输入有效的布尔组合

Python typing valid boolean combinations

我正在尝试使用 Python 的类型检查器来捕获不兼容的权限。我有一个许可情况,可以允许(布尔值)和要求(布尔值)执行特定操作。显然,我想排除既禁止又要求的情况,因为这是不可能的。

这是我试过的方法。

Permissions = Union[
    Tuple[Literal[False], Literal[False]],  # forbidden and not required
    Tuple[Literal[True], Literal[False]],   # permitted and not required
    Tuple[Literal[True], Literal[True]]     # permitted and required
    # (No option for forbidden and required)
]

forbidden: Permissions = (False, False)
allowed: Permissions = (True, False)
required: Permissions = (True, True)
mypy_should_catch: Permissions = (False, True)

我希望 mypy 允许前三个,但不允许最后一个。

然而,我实际上得到的是所有四个错误:

error: Incompatible types in assignment (expression has type "Tuple[bool, bool]", variable has type "Union[Tuple[Literal[False], Literal[False]], Tuple[Literal[True], Literal[False]], Tuple[Literal[True], Literal[True]]]")

我怎样才能使这个工作?

mypy 0.941 只捕获最后一行:

$ mypy test.py
test.py:13: error: Incompatible types in assignment (expression has type "Tuple[bool, bool]", variable has type "Union[Tuple[Literal[False], Literal[False]], Tuple[Literal[True], Literal[False]], Tuple[Literal[True], Literal[True]]]")  [assignment]
Found 1 error in 1 file (checked 1 source file)

看来您只需要升级即可。

最后,我尝试以 type-safe 的方式捕捉 forbidden/permitted/required 的逻辑。

class Permissions(Enum):
    FORBIDDEN = auto()
    PERMITTED = auto()
    REQUIRED = auto()

    @property
    def permitted(self) -> bool:
        return self is not self.FORBIDDEN

    @property
    def required(self) -> bool:
        return self is self.REQUIRED

但是,我不会将此标记为答案,因为仍然存在原始方法为何未按预期工作的问题。