Esempio n. 1
0
def set_interrupt_handler(interrupt_signal=DEFAULT_SIGNAL):
    """
    Set up an interrupt handler, to activate PuDB when Python receives the
    signal `interrupt_signal`.  By default it is SIGINT (i.e., Ctrl-c).

    To use a different signal, pass it as the argument to this function, like
    `set_interrupt_handler(signal.SIGALRM)`.  You can then break your code
    with `kill -ALRM pid`, where `pid` is the process ID of the Python
    process.  Note that PuDB will still use SIGINT once it is running to allow
    breaking running code.  If that is an issue, you can change the default
    signal by hooking `pudb.DEFAULT_SIGNAL`, like

    >>> import pudb
    >>> import signal
    >>> pudb.DEFAULT_SIGNAL = signal.SIGALRM

    Note, this may not work if you use threads or subprocesses.
    """
    import signal
    try:
        signal.signal(interrupt_signal, _interrupt_handler)
    except ValueError:
        from pudb.lowlevel import format_exception
        import sys
        from warnings import warn
        warn("setting interrupt handler on signal %d failed: %s"
                % (interrupt_signal, "".join(format_exception(sys.exc_info()))))
Esempio n. 2
0
def set_interrupt_handler(interrupt_signal=None):
    """
    Set up an interrupt handler, to activate PuDB when Python receives the
    signal `interrupt_signal`.  By default it is SIGINT (i.e., Ctrl-c).

    To use a different signal, pass it as the argument to this function, like
    `set_interrupt_handler(signal.SIGALRM)`.  You can then break your code
    with `kill -ALRM pid`, where `pid` is the process ID of the Python
    process.  Note that PuDB will still use SIGINT once it is running to allow
    breaking running code.  If that is an issue, you can change the default
    signal by hooking `pudb.DEFAULT_SIGNAL`, like

    >>> import pudb
    >>> import signal
    >>> pudb.DEFAULT_SIGNAL = signal.SIGALRM

    Note, this may not work if you use threads or subprocesses.

    Note, this only works when called from the main thread.
    """

    if interrupt_signal is None:
        interrupt_signal = DEFAULT_SIGNAL

    import signal
    old_handler = signal.getsignal(interrupt_signal)

    if old_handler is not signal.default_int_handler \
            and old_handler != signal.SIG_DFL and old_handler != _interrupt_handler:
        # Since we don't currently have support for a non-default signal handlers,
        # let's avoid undefined-behavior territory and just show a warning.
        from warnings import warn
        if old_handler is None:
            # This is the documented meaning of getsignal()->None.
            old_handler = "not installed from python"
        return warn(
            "A non-default handler for signal %d is already installed (%s). "
            "Skipping pudb interrupt support." %
            (interrupt_signal, old_handler))

    import threading
    if not isinstance(threading.current_thread(), threading._MainThread):
        from warnings import warn
        # Setting signals from a non-main thread will not work
        return warn(
            "Setting the interrupt handler can only be done on the main "
            "thread. The interrupt handler was NOT installed.")

    try:
        signal.signal(interrupt_signal, _interrupt_handler)
    except ValueError:
        from pudb.lowlevel import format_exception
        import sys
        from warnings import warn
        warn("setting interrupt handler on signal %d failed: %s" %
             (interrupt_signal, "".join(format_exception(sys.exc_info()))))
Esempio n. 3
0
def set_interrupt_handler(interrupt_signal=DEFAULT_SIGNAL):
    """
    Set up an interrupt handler, to activate PuDB when Python receives the
    signal `interrupt_signal`.  By default it is SIGINT (i.e., Ctrl-c).

    To use a different signal, pass it as the argument to this function, like
    `set_interrupt_handler(signal.SIGALRM)`.  You can then break your code
    with `kill -ALRM pid`, where `pid` is the process ID of the Python
    process.  Note that PuDB will still use SIGINT once it is running to allow
    breaking running code.  If that is an issue, you can change the default
    signal by hooking `pudb.DEFAULT_SIGNAL`, like

    >>> import pudb
    >>> import signal
    >>> pudb.DEFAULT_SIGNAL = signal.SIGALRM

    Note, this may not work if you use threads or subprocesses.

    Note, this only works when called from the main thread.
    """
    import signal
    old_handler = signal.getsignal(interrupt_signal)

    if old_handler is not signal.default_int_handler \
            and old_handler != signal.SIG_DFL and old_handler != _interrupt_handler:
        # Since we don't currently have support for a non-default signal handlers,
        # let's avoid undefined-behavior territory and just show a warning.
        from warnings import warn
        if old_handler is None:
            # This is the documented meaning of getsignal()->None.
            old_handler = 'not installed from python'
        return warn("A non-default handler for signal %d is already installed (%s). "
                "Skipping pudb interrupt support."
                % (interrupt_signal, old_handler))

    import threading
    if not isinstance(threading.current_thread(), threading._MainThread):
        from warnings import warn
        # Setting signals from a non-main thread will not work
        return warn("Setting the interrupt handler can only be done on the main "
                "thread. The interrupt handler was NOT installed.")

    try:
        signal.signal(interrupt_signal, _interrupt_handler)
    except ValueError:
        from pudb.lowlevel import format_exception
        import sys
        from warnings import warn
        warn("setting interrupt handler on signal %d failed: %s"
                % (interrupt_signal, "".join(format_exception(sys.exc_info()))))