no-partial-type-is
TypeIs must not reject a value belonging to its declared target type.
Why
TypeIs narrows both branches. A positive-int or non-empty-container filter can return false for a valid member of its target type, making callers incorrectly exclude that type in the false branch.
Fix
Use an ordinary bool return for a value filter. Ensure every accepted value satisfies the declared target. Use TypeGuard for an intentional partial predicate only when its true branch is sound; TypeIs must recognize exactly the target values. Check false-branch callers when changing the narrowing contract.
Examples
from typing import Literal, TypeIs
def is_selected(value: str) -> TypeIs[Literal["red", "blue"]]: return value == "red"from typing import Literal, TypeIs
def is_selected(value: str) -> TypeIs[Literal["red"]]: return value == "red"from typing import TypeIs
def is_positive(value: object) -> TypeIs[int]: return isinstance(value, int) and value > 0from typing import TypeGuard
def is_positive(value: object) -> TypeGuard[int]: return isinstance(value, int) and value > 0from typing import TypeIs
def is_text(value: object) -> TypeIs[str]: return bool(value)def is_truthy(value: object) -> bool: return bool(value)