Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/IPython/shellglobals.py
blob: 34ce467a80633671b2976eec1bd2945d936568a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
"""Some globals used by the main Shell classes.
"""

#-----------------------------------------------------------------------------
# Module imports
#-----------------------------------------------------------------------------

# stdlib
import inspect
import thread

try:
    import ctypes
    HAS_CTYPES = True
except ImportError:
    HAS_CTYPES = False

# our own
from IPython.genutils import Term,warn,error,flag_calls, ask_yes_no

#-----------------------------------------------------------------------------
# Globals
#-----------------------------------------------------------------------------
# global flag to pass around information about Ctrl-C without exceptions
KBINT = False

# global flag to turn on/off Tk support.
USE_TK = False

# ID for the main thread, used for cross-thread exceptions
MAIN_THREAD_ID = thread.get_ident()

# Tag when runcode() is active, for exception handling
CODE_RUN = None

#-----------------------------------------------------------------------------
# This class is trivial now, but I want to have it in to publish a clean
# interface. Later when the internals are reorganized, code that uses this
# shouldn't have to change.

if HAS_CTYPES:
    #  Add async exception support.  Trick taken from:
    # http://sebulba.wikispaces.com/recipe+thread2
    def _async_raise(tid, exctype):
        """raises the exception, performs cleanup if needed"""
        if not inspect.isclass(exctype):
            raise TypeError("Only types can be raised (not instances)")
        res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid,
                                                         ctypes.py_object(exctype))
        if res == 0:
            raise ValueError("invalid thread id")
        elif res != 1:
            # """if it returns a number greater than one, you're in trouble, 
            # and you should call it again with exc=NULL to revert the effect"""
            ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
            raise SystemError("PyThreadState_SetAsyncExc failed")

    def sigint_handler (signum,stack_frame):
        """Sigint handler for threaded apps.

        This is a horrible hack to pass information about SIGINT _without_
        using exceptions, since I haven't been able to properly manage
        cross-thread exceptions in GTK/WX.  In fact, I don't think it can be
        done (or at least that's my understanding from a c.l.py thread where
        this was discussed)."""

        global KBINT

        if CODE_RUN:
            _async_raise(MAIN_THREAD_ID,KeyboardInterrupt)
        else:
            KBINT = True
            print '\nKeyboardInterrupt - Press <Enter> to continue.',
            Term.cout.flush()

else:
    def sigint_handler (signum,stack_frame):
        """Sigint handler for threaded apps.

        This is a horrible hack to pass information about SIGINT _without_
        using exceptions, since I haven't been able to properly manage
        cross-thread exceptions in GTK/WX.  In fact, I don't think it can be
        done (or at least that's my understanding from a c.l.py thread where
        this was discussed)."""

        global KBINT

        print '\nKeyboardInterrupt - Press <Enter> to continue.',
        Term.cout.flush()
        # Set global flag so that runsource can know that Ctrl-C was hit
        KBINT = True


def run_in_frontend(src):
    """ Check if source snippet can be run in the REPL thread, as opposed to
    GUI mainloop (to prevent unnecessary hanging of mainloop).
    """
    
    if src.startswith('_ip.system(') and not '\n' in src:
        return True
    return False