jonesmarvin8 24f6f1f8ca fixes
2026-04-26 21:29:54 -04:00

49 lines
1.4 KiB
Python

from functools import wraps
from typing import Callable, TypeVar, ParamSpec, cast
from .exceptions import InvalidStateError
from .card_interface import CardInterface
P = ParamSpec("P")
R = TypeVar("R")
def make_precondition(
attribute_name: str,
display_name: str | None = None
) -> Callable[[Callable[P, R]], Callable[P, R]]:
def decorator(func: Callable[P, R]) -> Callable[P, R]:
@wraps(func)
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
card = args[0]
if not isinstance(card, CardInterface):
raise TypeError("First argument must be a CardInterface")
if not getattr(card, attribute_name, False):
readable = (
display_name
if display_name is not None
else attribute_name.replace('_', ' ').title()
)
raise InvalidStateError(f"{readable} must be satisfied.")
return func(*args, **kwargs)
return cast(Callable[P, R], wrapper)
return decorator
require_selected = make_precondition(
'is_selected',
'Card Selection'
)
require_initialized = make_precondition(
'is_initialized',
'Card Initialization'
)
require_secure_channel = make_precondition(
'is_secure_channel_open',
'Secure Channel'
)
require_pin_verified = make_precondition(
'is_pin_verified',
'PIN verification'
)