views:

14

answers:

0

My problem is the following: I would like to open an instance of ipython in a terminal of mine by simply typing, as usual:

$ ipython -pylab

and be able to have other processes order this ipython instance to execute a file as the execfile() would. This could be any other process, for instance, vim could ask ipython to run the currently open file automatically, without me having to switch windows and type the execfile() command in the ipython terminal myself every time.

My first idea was to write a simple module called exec_server.py that would listen on a given unix socket and execute the files that it receives. Of course, if the server is not running in a seperate thread, the ipython instance freezes on the serve_forever() command right after typing:

[1]: import exec_server

Therefor, the code would be the following:

# file: exec_server.py

import os, SocketServer, threading

class MyServerHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        received_data = self.request.recv(1024).strip("\n")
        execfile(received_data)

server = SocketServer.ThreadingUnixStreamServer(os.environ['IPY_SERVER_PATH'], MyServerHandler)
server_thread = threading.Thread(target=server.serve_forever) 
server_thread.setDaemon(True) 
server_thread.start()

The problem is that when a file path is given to the socket by an other process, the file is executed by ipython but not in the right "context". If the file contains a syntax error, for instance, the traceback will be coming from the separate thread and will look very different from the traceback coming from a normal manually typed execfile() command. The ability to use the magic "debug" command is lost. Any ideas ?

Traceback when executed with a "real" execfile():

[1]: execfile("/home/user/pytest/script.py")

/home/user/<ipython console> in <module>()

/home/user/pytest/script.py in <module>()
     18 print 'Module imported'
     19 
     20 '''Fn'''
     21 #badfn()
---> 22 dummy_module.goodfn()

/home/user/pytest/dummy_module.pyc in goodfn()
      2     a = 2
      3     b = 3
----> 4     abc()
      5     c = 3
      6 

NameError: global name 'abc' is not defined

Traceback when executed in a thread:

----------------------------------------
Exception happened during processing of request from 
Traceback (most recent call last):
  File "/usr/lib64/python2.6/SocketServer.py", line 281, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/usr/lib64/python2.6/SocketServer.py", line 307, in process_request
    self.finish_request(request, client_address)
  File "/usr/lib64/python2.6/SocketServer.py", line 320, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib64/python2.6/SocketServer.py", line 615, in __init__
    self.handle()
  File "/home/user/.ipython/exec_server.py", line 36, in handle
    execfile(received_data)
  File "/home/user/pytest/script.py", line 22, in <module>
    dummy_module.goodfn()
  File "/home/user/pytest/dummy_module.py", line 4, in goodfn
    abc()
NameError: global name 'abc' is not defined
----------------------------------------