def make_lookuper(func):
        """
        Creates a single argument function looking up result in a memory.

        Decorated function is called once on first lookup and should return all available
        arg-value pairs.

        Resulting function will raise LookupError when using @make_lookuper
        or simply return None when using @silent_lookuper.
        """
        has_args, has_keys = has_arg_types(func)
        assert not has_keys, \
            'Lookup table building function should not have keyword arguments'

        if has_args:
            @memoize
            def wrapper(*args):
                f = lambda: func(*args)
                f.__name__ = '%s(%s)' % (func.__name__, ', '.join(map(str, args)))
                return make_lookuper(f)
        else:
            memory = {}

            def wrapper(arg):
                if not memory:
                    memory[object()] = None # prevent continuos memory refilling
                    memory.update(func())

                if silent:
                    return memory.get(arg)
                elif arg in memory:
                    return memory[arg]
                else:
                    raise LookupError("Failed to look up %s(%s)" % (func.__name__, arg))

        return wraps(func)(wrapper)

        Creates a single argument function looking up result in a memory.

        Decorated function is called once on first lookup and should return all available
        arg-value pairs.

        Resulting function will raise LookupError when using @make_lookuper
        or simply return None when using @silent_lookuper.
        
funcy/calc.py