def METHOD_NAME(left, right, may_swap_arguments):
    # Complex stuff with many cases, pylint: disable=too-many-branches
    left_shape = left.getTypeShape()
    right_shape = right.getTypeShape()
    if left_shape in _int_types_family and right_shape in _int_types_family:
        may_swap_arguments = may_swap_arguments in ("number", "always")
        left_c_type = _pickIntFamilyType(left)
        right_c_type = _pickIntFamilyType(right)
        needs_argument_swap = (
            may_swap_arguments
            and left_c_type is not right_c_type
            and _long_argument_normalization[(left_c_type, right_c_type)]
        )
        # TODO: The INT and LONG types, do not have distinct C types yet, and maybe
        # won't have it, so these are manual:
        if may_swap_arguments and not needs_argument_swap:
            if right_shape is tshape_long and left_shape is tshape_int:
                needs_argument_swap = True
        unknown_types = False
    elif left_shape in _float_types_family and right_shape in _float_types_family:
        may_swap_arguments = may_swap_arguments in ("number", "always")
        left_c_type = _pickFloatFamilyType(left)
        right_c_type = _pickFloatFamilyType(right)
        # Arguments might be swapped because of normalization.
        needs_argument_swap = (
            may_swap_arguments
            and left_c_type is not right_c_type
            and _float_argument_normalization[(left_c_type, right_c_type)]
        )
        # TODO: The INT and LONG types, do not have distinct C types yet, and maybe
        # won't have it, so these are manual:
        if may_swap_arguments and not needs_argument_swap:
            if right_shape is tshape_float and left_shape in (tshape_int, tshape_long):
                needs_argument_swap = True
        unknown_types = False
    elif left_shape in _str_types_family and right_shape in _str_types_family:
        may_swap_arguments = may_swap_arguments == "always"
        left_c_type = _pickStrFamilyType(left)
        right_c_type = _pickStrFamilyType(right)
        # Arguments might be swapped because of normalization.
        needs_argument_swap = (
            may_swap_arguments
            and left_c_type is not right_c_type
            and _str_argument_normalization[(left_c_type, right_c_type)]
        )
        # TODO: The STR and UNICODE types, do not have distinct C types yet, and maybe
        # won't have it, so these are manual:
        if may_swap_arguments and not needs_argument_swap and str is bytes:
            if right_shape is tshape_unicode and left_shape is tshape_str:
                needs_argument_swap = True
        unknown_types = False
    elif left_shape in _bytes_types_family and right_shape in _bytes_types_family:
        may_swap_arguments = may_swap_arguments == "always"
        left_c_type = _pickBytesFamilyType(left)
        right_c_type = _pickBytesFamilyType(right)
        # Arguments might be swapped because of normalization.
        needs_argument_swap = (
            may_swap_arguments
            and left_c_type is not right_c_type
            and _bytes_argument_normalization[(left_c_type, right_c_type)]
        )
        # TODO: The BYTES and BYTEARRAY types, do not have distinct C types yet, and maybe
        # won't have it, so these are manual:
        if may_swap_arguments and not needs_argument_swap:
            if right_shape is tshape_bytearray and left_shape is tshape_bytes:
                needs_argument_swap = True
        unknown_types = False
    else:
        left_c_type = right_c_type = CTypePyObjectPtr
        needs_argument_swap = False
        unknown_types = True
    return (
        unknown_types,
        needs_argument_swap,
        left_shape,
        right_shape,
        left_c_type,
        right_c_type,
    )