from IPython.genutils import Term,warn,error,flag_calls, ask_yes_no import thread,inspect try: import ctypes HAS_CTYPES = True except ImportError: HAS_CTYPES = False # 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 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 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