def force_hashable(obj, recursive=True):
<EOL>if hasattr(obj, '<STR_LIT>') and not hasattr(obj, '<STR_LIT>') and not hasattr(obj, '<STR_LIT>'):<EOL><INDENT>try:<EOL><INDENT>hash(obj)<EOL>return obj<EOL><DEDENT>except (IndexError, ValueError, AttributeError, TypeError):<EOL><INDENT>pass<EOL><DEDENT><DEDENT>if hasattr(obj, '<STR_LIT>'):<EOL><INDENT>if hasattr(obj, '<STR_LIT>') and hasattr(obj, '<STR_LIT>'):<EOL><INDENT>return force_hashable(tuple(obj.items()))<EOL><DEDENT>if recursive:<EOL><INDENT>return tuple(force_hashable(item) for item in obj)<EOL><DEDENT>return tuple(obj)<EOL><DEDENT>return str(obj)<EOL>
Force frozenset() command to freeze the order and contents of mutables and iterables like lists, dicts, generators

    Useful for memoization and constructing dicts or hashtables where keys must be immutable.

    FIXME: Rename function because "hashable" is misleading.
           A better name might be `force_immutable`.
           because some hashable objects (generators) are tuplized  by this function
           `tuplized` is probably a better name, but strings are left alone, so not quite right

    >>> force_hashable([1,2.,['3','four'],'five', {'s': 'ix'}])
    (1, 2.0, ('3', 'four'), 'five', (('s', 'ix'),))
    >>> force_hashable(i for i in range(4))
    (0, 1, 2, 3)
    >>> sorted(force_hashable(Counter('abbccc'))) ==   [('a', 1), ('b', 2), ('c', 3)]
    True