def unique(func, num_args=<NUM_LIT:0>, max_attempts=<NUM_LIT:100>, cache=None):
if cache is None:<EOL><INDENT>cache = _cache_unique<EOL><DEDENT>@wraps(func)<EOL>def wrapper(*args):<EOL><INDENT>key = "<STR_LIT>" % (str(func.__name__), str(args[:num_args]))<EOL>attempt = <NUM_LIT:0><EOL>while attempt < max_attempts:<EOL><INDENT>attempt += <NUM_LIT:1><EOL>drawn = cache.get(key, [])<EOL>result = func(*args)<EOL>if result not in drawn:<EOL><INDENT>drawn.append(result)<EOL>cache[key] = drawn<EOL>return result<EOL><DEDENT><DEDENT>raise MaxAttemptException()<EOL><DEDENT>return wrapper<EOL>
wraps a function so that produce unique results

:param func:
:param num_args:

>>> import random
>>> choices = [1,2]
>>> a = unique(random.choice, 1)
>>> a,b = a(choices), a(choices)
>>> a == b
False