Repository: Chia-Network/chia-blockchain
File: chia/util/streamable.py (Python)

Code before:
        fields.append(
            Field(
                name=field.name,
                type=hint,
                has_default=field.default is not dataclasses.MISSING
                or field.default_factory is not dataclasses.MISSING,
                stream_function=function_to_stream_one_item(hint),
                parse_function=function_to_parse_one_item(hint),
                convert_function=function_to_convert_one_item(hint),
                post_init_function=function_to_post_init_process_one_item(hint),
            )
        )

    return tuple(fields)


def is_type_List(f_type: object) -> bool:
    return get_origin(f_type) is list or f_type is list


def is_type_SpecificOptional(f_type: object) -> bool:
    """
    Returns true for types such as Optional[T], but not Optional, or T.
    """
    return get_origin(f_type) == Union and get_args(f_type)[1]() is None


def is_type_Tuple(f_type: object) -> bool:
    return get_origin(f_type) is tuple or f_type is tuple


def is_type_Dict(f_type: object) -> bool:
    return get_origin(f_type) is dict or f_type is dict


def is_type_Enum(f_type: object) -> bool:
    return type(f_type) is EnumMeta


def convert_optional(convert_func: ConvertFunctionType, item: Any) -> Any:
    if item is None:
        return None
    return convert_func(item)


def convert_tuple(convert_funcs: list[ConvertFunctionType], items: Collection[Any]) -> tuple[Any, ...]:
    if not isinstance(items, (list, tuple)):
        raise InvalidTypeError(tuple, type(items))
    if len(items) != len(convert_funcs):
        raise InvalidSizeError(len(convert_funcs), len(items))
    return tuple(convert_func(item) for convert_func, item in zip(convert_funcs, items))

Review comment (suggestion):
This is a real change.  The new `X | Y` syntax results in a different type upon inspection.

Code after:
        hint = hints[field.name]
        fields.append(
            Field(
                name=field.name,
                type=hint,
                has_default=field.default is not dataclasses.MISSING
                or field.default_factory is not dataclasses.MISSING,
                stream_function=function_to_stream_one_item(hint),
                parse_function=function_to_parse_one_item(hint),
                convert_function=function_to_convert_one_item(hint),
                post_init_function=function_to_post_init_process_one_item(hint),
            )
        )

    return tuple(fields)


def is_type_List(f_type: object) -> bool:
    return get_origin(f_type) is list or f_type is list


def is_type_SpecificOptional(f_type: object) -> bool:
    """
    Returns true for types such as Optional[T], but not Optional, or T.
    """
    return get_origin(f_type) in {Union, UnionType} and get_args(f_type)[1]() is None


def is_type_Tuple(f_type: object) -> bool:
    return get_origin(f_type) is tuple or f_type is tuple


def is_type_Dict(f_type: object) -> bool:
    return get_origin(f_type) is dict or f_type is dict


def is_type_Enum(f_type: object) -> bool:
    return type(f_type) is EnumMeta


def convert_optional(convert_func: ConvertFunctionType, item: Any) -> Any:
    if item is None:
        return None
    return convert_func(item)


def convert_tuple(convert_funcs: list[ConvertFunctionType], items: Collection[Any]) -> tuple[Any, ...]:
    if not isinstance(items, (list, tuple)):
        raise InvalidTypeError(tuple, type(items))
    if len(items) != len(convert_funcs):
        raise InvalidSizeError(len(convert_funcs), len(items))