def generate_name_variations(name):
def _update_name_variations_with_product(set_a, set_b):<EOL><INDENT>name_variations.update([<EOL>unidecode((names_variation[<NUM_LIT:0>] +<EOL>separator +<EOL>names_variation[<NUM_LIT:1>]).strip('<STR_LIT>'.join(_LASTNAME_NON_LASTNAME_SEPARATORS))).lower()<EOL>for names_variation<EOL>in product(set_a, set_b)<EOL>for separator<EOL>in _LASTNAME_NON_LASTNAME_SEPARATORS<EOL>])<EOL><DEDENT>parsed_name = ParsedName.loads(name)<EOL>if len(parsed_name) == <NUM_LIT:1>:<EOL><INDENT>return [parsed_name.dumps().lower()]<EOL><DEDENT>name_variations = set()<EOL>non_lastnames = [<EOL>non_lastname<EOL>for non_lastname<EOL>in parsed_name.first_list + parsed_name.suffix_list<EOL>if non_lastname<EOL>]<EOL>if len(non_lastnames) > _NAMES_MAX_NUMBER_THRESHOLD or len(parsed_name.last_list) > _NAMES_MAX_NUMBER_THRESHOLD:<EOL><INDENT>LOGGER.error('<STR_LIT>', name)<EOL>return [name]<EOL><DEDENT>non_lastnames_variations =_generate_non_lastnames_variations(non_lastnames)<EOL>lastnames_variations = _generate_lastnames_variations(parsed_name.last_list)<EOL>_update_name_variations_with_product(lastnames_variations, non_lastnames_variations)<EOL>_update_name_variations_with_product(non_lastnames_variations, lastnames_variations)<EOL>return list(name_variations)<EOL>
Generate name variations for a given name.

    Args:
        name (six.text_type): The name whose variations are to be generated.

    Returns:
        list: All the name variations for the given name.

    Notes:
        Uses `unidecode` for doing unicode characters transliteration to ASCII ones. This was chosen so that we can map
        both full names of authors in HEP records and user's input to the same space and thus make exact queries work.