Repository: Chia-Network/chia-blockchain
File: chia/wallet/wallet_request_types.py (Python)

Code before:
@kw_only_dataclass
class DIDUpdateMetadata(TransactionEndpointRequest):
    wallet_id: uint32 = field(default_factory=default_raise)
    metadata: dict[str, str] = field(default_factory=dict)


@streamable
@dataclass(frozen=True)
class DIDUpdateMetadataResponse(TransactionEndpointResponse):
    spend_bundle: WalletSpendBundle
    wallet_id: uint32


@streamable
@kw_only_dataclass
class DIDTransferDID(TransactionEndpointRequest):
    wallet_id: uint32 = field(default_factory=default_raise)
    inner_address: str = field(default_factory=default_raise)
    with_recovery_info: bool = True

    def __post_init__(self) -> None:
        if self.with_recovery_info is False:
            raise ValueError("Recovery related options are no longer supported. `with_recovery` must always be true.")
        return super().__post_init__()


@streamable
@dataclass(frozen=True)
class DIDTransferDIDResponse(TransactionEndpointResponse):
    transaction: TransactionRecord
    transaction_id: bytes32


@streamable
@kw_only_dataclass
class NFTMintNFTRequest(TransactionEndpointRequest):
    wallet_id: uint32 = field(default_factory=default_raise)
    royalty_address: Optional[str] = field(default_factory=default_raise)
    target_address: Optional[str] = field(default_factory=default_raise)
    uris: list[str] = field(default_factory=default_raise)
    hash: bytes32 = field(default_factory=default_raise)
    royalty_amount: uint16 = uint16(0)
    meta_uris: list[str] = field(default_factory=list)
    license_uris: list[str] = field(default_factory=list)
    edition_number: uint64 = uint64(1)
    edition_total: uint64 = uint64(1)
    meta_hash: Optional[bytes32] = None
    license_hash: Optional[bytes32] = None
    did_id: Optional[str] = None



Review comment (suggestion):
I think if the elif explicitly specifies `is None` it resolves this
`elif self.extra_delta is None or self.tail_reveal is None or self.tail_solution is None:`


Code after:
    amount: Optional[uint64] = None
    inner_address: Optional[str] = None
    memos: Optional[list[str]] = None
    coins: Optional[list[Coin]] = None
    extra_delta: Optional[str] = None  # str to support negative ints :(
    tail_reveal: Optional[bytes] = None
    tail_solution: Optional[bytes] = None

    def __post_init__(self) -> None:
        if (
            self.additions is not None
            and (self.amount is not None or self.inner_address is not None or self.memos is not None)
        ) or (self.additions is None and self.amount is None and self.inner_address is None and self.memos is None):
            raise ValueError('Must specify "additions" or "amount"+"inner_address"+"memos", but not both.')
        elif self.additions is None and None in {self.amount, self.inner_address}:
            raise ValueError('Must specify "amount" and "inner_address" together.')
        super().__post_init__()

    @property
    def cat_discrepancy(self) -> Optional[tuple[int, Program, Program]]:
        if self.extra_delta is None and self.tail_reveal is None and self.tail_solution is None:
            return None
        elif None in {self.extra_delta, self.tail_reveal, self.tail_solution}:
            raise ValueError('Must specify "extra_delta", "tail_reveal" and "tail_solution" together.')
        else:
            # Curious that mypy doesn't see the elif and know that none of these are None
            return (
                int(self.extra_delta),  # type: ignore[arg-type]
                Program.from_bytes(self.tail_reveal),  # type: ignore[arg-type]
                Program.from_bytes(self.tail_solution),  # type: ignore[arg-type]
            )


@streamable
@dataclass(frozen=True)
class CATSpendResponse(TransactionEndpointResponse):
    transaction: TransactionRecord
    transaction_id: bytes32


@streamable
@kw_only_dataclass
class DIDMessageSpend(TransactionEndpointRequest):
    wallet_id: uint32 = field(default_factory=default_raise)
    coin_announcements: list[bytes] = field(default_factory=list)
    puzzle_announcements: list[bytes] = field(default_factory=list)


@streamable
@dataclass(frozen=True)
class DIDMessageSpendResponse(TransactionEndpointResponse):