def _generic_convert_string(v, from_type, to_type, encoding):
    """
    Generic method to convert any argument type (string type, list, set, tuple, dict) to an equivalent,
    with string values converted to given 'to_type' (str or unicode).
    This method must be used with Python 2 interpreter only.

    :param v: The value to convert
    :param from_type: The original string type to convert
    :param to_type: The target string type to convert to
    :param encoding: When
    :return:
    """

    assert six.PY2, "This function should be used with Python 2 only"
    assert from_type != to_type

    if from_type == six.binary_type and isinstance(v, six.binary_type):
        return six.text_type(v, encoding)

    elif from_type == six.text_type and isinstance(v, six.text_type):
        return v.encode(encoding)

    elif isinstance(v, (list, tuple, set)):
        return type(v)([_generic_convert_string(element, from_type, to_type, encoding) for element in v])

    elif isinstance(v, dict):
        return {k: _generic_convert_string(v, from_type, to_type, encoding) for k, v in v.iteritems()}

    return v