def func_timeout(timeout, func, args=(), kwargs=None):
    '''
        func_timeout - Runs the given function for up to #timeout# seconds.

        Raises any exceptions #func# would raise, returns what #func# would return (unless timeout is exceeded), in which case it raises FunctionTimedOut

        @param timeout <float> - Maximum number of seconds to run #func# before terminating

        @param func <function> - The function to call

        @param args    <tuple> - Any ordered arguments to pass to the function

        @param kwargs  <dict/None> - Keyword arguments to pass to the function.


        @raises - FunctionTimedOut if #timeout# is exceeded, otherwise anything #func# could raise will be raised

        If the timeout is exceeded, FunctionTimedOut will be raised within the context of the called function every two seconds until it terminates,
        but will not block the calling thread (a new thread will be created to perform the join). If possible, you should try/except FunctionTimedOut
        to return cleanly, but in most cases it will 'just work'.

        @return - The return value that #func# gives
    '''

    if not kwargs:
        kwargs = {}
    if not args:
        args = ()

    ret = []
    exception = []
    isStopped = False

    def funcwrap(args2, kwargs2):
        try:
            ret.append( func(*args2, **kwargs2) )
        except FunctionTimedOut:
            # Don't print traceback to stderr if we time out
            pass
        except Exception as e:
            exc_info = sys.exc_info()
            if isStopped is False:
                # Assemble the alternate traceback, excluding this function
                #  from the trace (by going to next frame)
                # Pytohn3 reads native from __traceback__, 
                # python2 has a different form for "raise"
                e.__traceback__ = exc_info[2].tb_next
                exception.append( e )

    thread = StoppableThread(target=funcwrap, args=(args, kwargs))
    thread.daemon = True

    thread.start()
    thread.join(timeout)

    stopException = None
    if thread.isAlive():
        isStopped = True

        class FunctionTimedOutTempType(FunctionTimedOut):
            def __init__(self):
                return FunctionTimedOut.__init__(self, '', timeout, func, args, kwargs)

        FunctionTimedOutTemp = type('FunctionTimedOut' + str( hash( "%d_%d_%d_%d" %(id(timeout), id(func), id(args), id(kwargs))) ), FunctionTimedOutTempType.__bases__, dict(FunctionTimedOutTempType.__dict__))

        stopException = FunctionTimedOutTemp
        thread._stopThread(stopException)
        thread.join(min(.1, timeout / 50.0))
        raise FunctionTimedOut('', timeout, func, args, kwargs)
    else:
        # We can still cleanup the thread here..
        # Still give a timeout... just... cuz..
        thread.join(.5)

    if exception:
        raise_exception(exception)

    if ret:
        return ret[0]
func_timeout - Runs the given function for up to #timeout# seconds.

        Raises any exceptions #func# would raise, returns what #func# would return (unless timeout is exceeded), in which case it raises FunctionTimedOut

        @param timeout <float> - Maximum number of seconds to run #func# before terminating

        @param func <function> - The function to call

        @param args    <tuple> - Any ordered arguments to pass to the function

        @param kwargs  <dict/None> - Keyword arguments to pass to the function.


        @raises - FunctionTimedOut if #timeout# is exceeded, otherwise anything #func# could raise will be raised

        If the timeout is exceeded, FunctionTimedOut will be raised within the context of the called function every two seconds until it terminates,
        but will not block the calling thread (a new thread will be created to perform the join). If possible, you should try/except FunctionTimedOut
        to return cleanly, but in most cases it will 'just work'.

        @return - The return value that #func# gives