Commits

Henning Schröder committed 6d63701

prepartions for asyncipc

  • Participants
  • Parent commits 4603218

Comments (0)

Files changed (6)

 import rope.base.libutils
 import rope.contrib.codeassist
 
-from pycode.utils import async
+from pycode.utils import async, register
 from pycode.project import Project
 
 
 _project_cache = {}
 
-
-def _get_resource(project, filename):
+def _get_project(project):
     if isinstance(project, basestring):
         root_path = project
         try:
             project = _project_cache[root_path]
         except KeyError:
             project = _project_cache[root_path] = Project(root_path)
+    return project
+
+
+def _get_resource(project, filename):
     try:
         resource = rope.base.libutils.path_to_resource(project._rope_prj, filename.encode('utf-8'))
     except Exception, _error:
     return resource
 
 
-
+@register
 def completions(project, source_code, offset, filename="XXXunknownXXX.py"):
 	# TODO:
 	#  * include import completitions
 	#  * offer name to override from base after "def " inside a class
 	#  * 
+    project = _get_project(project)
     resource = _get_resource(project, filename)
     try:
         proposals = rope.contrib.codeassist.code_assist(project._rope_prj, source_code, offset, resource)
 
 async_completions = async(completions)
 
-    
+
+@register
 def calltip(project, source_code, offset, filename="XXXunknownXXX.py"):
+    project = _get_project(project)
     resource = _get_resource(project, filename)
     try:
         cts = rope.contrib.codeassist.get_calltip(project._rope_prj, source_code, offset, resource, ignore_unknown=False, remove_self=True)
 async_calltip = async(calltip)
 
 
+@register
 def definition_location(project, source_code, offset, filename="XXXunknownXXX.py"):
+    project = _get_project(project)
     resource = _get_resource(project, filename)
     try:
         resource, lineno = rope.contrib.codeassist.get_definition_location(project._rope_prj, source_code, offset, resource)

pycode/asyncipc.py

 # -*- coding: utf-8 -*-
 import atexit
-import marshal
-try:
-	import cPickle as pickle
-except ImportError:
-	import pickle
 from multiprocessing import Process, Queue
 from threading import Thread
 
 
 
 class Server(object):
-	
+    
 
-	def __init__(self):
-		pass
+    def __init__(self):
+        pass
 
-	
-	def received(self, data):
-		print "received", len(data), "bytes"
-		return data
+    
+    def received(self, data):
+        print "received", len(data), "bytes"
+        return data
 
 
 
 class Connection(object):
 
 
-	def __init__(self, server_factory):
-		self.server_factory = server_factory
-		self.input_queue = Queue()
-		self.output_queue = Queue()
+    def __init__(self, server_factory):
+        self.server_factory = server_factory
+        self.input_queue = Queue()
+        self.output_queue = Queue()
 
 
-	def _listen(self, server_factory, input_queue, output_queue):
-		server = server_factory()
-		while True:
-			item = input_queue.get()
-			if item is None:
-				output_queue.put(None)
-				break
-			result = server.received(item)
-			output_queue.put(result)
+    def _listen(self, server_factory, input_queue, output_queue):
+        server = server_factory()
+        while True:
+            item = input_queue.get()
+            if item is None:
+                output_queue.put(None)
+                break
+            result = server.received(item)
+            output_queue.put(result)
 
-		
-	def start(self):
-		self.proc = Process(target=self._listen, args=(self.server_factory, self.input_queue, self.output_queue))
-		self.proc.start()
+        
+    def start(self):
+        self.proc = Process(target=self._listen, args=(self.server_factory, self.input_queue, self.output_queue))
+        self.proc.start()
 
 
 
 
 class Client(object):
-	
-	
-	def __init__(self, connection):
-		self._connection = connection
-		atexit.register(self._exit)
-		self._callback_queue = []
-		self._callback_thread = Thread(target=self._watch_results)
-		self._callback_thread.setDaemon(True)
-		self._callback_thread.start()
-		
+    
+    
+    def __init__(self, connection):
+        self._connection = connection
+        atexit.register(self._exit)
+        self._callback_queue = []
+        self._callback_thread = Thread(target=self._watch_results)
+        self._callback_thread.setDaemon(True)
+        self._callback_thread.start()
+        
 
-	def _exit(self):
-		self._call(None, None)
+    def _exit(self):
+        self._call(None, None)
 
 
-	def _watch_results(self):
-		while True:
-			item = self._connection.output_queue.get()
-			if item is None:
-				break
-			callback = self._callback_queue.pop()
-			callback(item)
-		
-		
-	def _call(self, data, callback):	
-		self._connection.input_queue.put(data)
-		self._callback_queue.insert(0, callback)
+    def _watch_results(self):
+        while True:
+            item = self._connection.output_queue.get()
+            if item is None:
+                break
+            callback = self._callback_queue.pop()
+            callback(item)
+        
+        
+    def _call(self, data, callback):    
+        self._connection.input_queue.put(data)
+        self._callback_queue.insert(0, callback)
 
 
-	def call(self, data, callback):
-		self._call(data, callback)
+    def call(self, data, callback):
+        self._call(data, callback)
 
-		
-		
+        
+        
 class IpcCallMixIn(object):
 
     
     def _decode_call(self, data):
-        (msg, args, kwargs) = pickle.loads(data)
+        (msg, args, kwargs) = data
         return (msg, args, kwargs)
     
     
     def _encode_result(self, error, result):
-        return pickle.dumps((error, result), 2)
+        return (error, result)
     
 
     def _encode_call(self, msg, args, kwargs):
         info = (msg, args, kwargs)
-        data = pickle.dumps(info, 2)
+        data = info
         return data
 
         
     def _decode_result(self, data):
-        error, value = pickle.loads(data)
+        error, value = data
         if error:
             raise error
         return value
 
 
-	
+    
 class IpcServer(Server, IpcCallMixIn):
 
 
-	def __init__(self, root=None):
-		Server.__init__(self)
-		if root is None:
-			root = self
-		self._root = root
+    def __init__(self, root=None):
+        Server.__init__(self)
+        if root is None:
+            root = self
+        self._root = root
 
 
-	def received(self, data):
-		msg, args, kwargs = self._decode_call(data)
-		method = getattr(self._root, msg)
-		try:
-			result = method(*args, **kwargs)
-			error = None
-		except Exception, error:
-			result = None
-		return self._encode_result(error, result)
+    def received(self, data):
+        msg, args, kwargs = self._decode_call(data)
+        method = getattr(self._root, msg)
+        try:
+            result = method(*args, **kwargs)
+            error = None
+        except Exception, error:
+            result = None
+        return self._encode_result(error, result)
 
 
 
 
 class _ResultCallback(object):
 
-	
-	def __init__(self, client, callback):
-		self.client = client
-		self.callback = callback
-		
+    
+    def __init__(self, client, callback):
+        self.client = client
+        self.callback = callback
+        
 
-	def __call__(self, data):
-		result = self.client._decode_result(data)
-		return self.callback(result)
+    def __call__(self, data):
+        result = self.client._decode_result(data)
+        return self.callback(result)
 
-		
-		
+        
+        
 class IpcClient(Client, IpcCallMixIn):
-	
+    
 
-	def call(self, msg, *args, **kwargs):
-		callback = kwargs.pop("callback")
-		data = self._encode_call(msg, args, kwargs)
-		return self._call(data, callback=_ResultCallback(self, callback))
+    def call(self, msg, *args, **kwargs):
+        callback = kwargs.pop("callback")
+        data = self._encode_call(msg, args, kwargs)
+        return self._call(data, callback=_ResultCallback(self, callback))
 
-	
-	def __getattr__(self, name):
-		method = lambda *args, **kwargs: self.call(name, *args, **kwargs)
-		return method
+    
+    def __getattr__(self, name):
+        method = lambda *args, **kwargs: self.call(name, *args, **kwargs)
+        return method
 
 
 
 if __name__ == "__main__":
-	def cb(result):
-		print "got", repr(result)
+    def cb(result):
+        print "got", repr(result)
 
-	def create_server():
-		class Root(object):
-			def foo(self):
-				return "Foo!"
-			def bar(self, count=1):
-				return "BAR" * count
-		server = IpcServer(Root())
-		return server
+    def create_server():
+        class Root(object):
+            def foo(self):
+                return "Foo!"
+            def bar(self, count=1):
+                return "BAR" * count
+        server = IpcServer(Root())
+        return server
 
-	con = Connection(create_server)
-	con.start()
-	client = IpcClient(con)
-	client.foo(callback=cb)
-	client.bar(2, callback=cb)
-	
-	import time; time.sleep(1)
-	print "done"
+    con = Connection(create_server)
+    con.start()
+    client = IpcClient(con)
+    client.foo(callback=cb)
+    client.bar(2, callback=cb)
+    
+    import time; time.sleep(1)
+    print "done"
 
 
 
-def tasks(source_code):
+def tasks(project, source_code):
 	"""Find tasks in source code (TODO, FIXME, XXX, ...)"""
 	results = []
 	for line, text in enumerate(source_code.splitlines()):
 	
 
 
-def pyflakes(source_code, filename=None):
+def pyflakes(project, source_code, filename=None):
 	"""
 	Check source code with pyflakes
 	Returns an empty list if pyflakes is not installed
     return output
 
 
-def pep8(source_code, filename=None):
+def pep8(project, source_code, filename=None):
     """Check source code with pep8"""
     args = ['pep8']
     results = []
 
 
 
-def lint(source_code, filename=None):    
+def lint(project, source_code, filename=None):    
     args = ["pylint"]
     options = ["-f parseable", "-r", "-n", "--disable-msg-cat=C,R"]
     results = []

pycode/qtintegration.py

 from pycode.assist import async_completions, async_calltip, async_definition_location
 from pycode.indenter import PythonCodeIndenter
 
-from pycode.utils import set_async_method
+from pycode.utils import set_async_method, enable_ipc
 
 
 
         
 
     def run(self):
-        self.result = self.target(*self.args, **self.kwargs)
+        if ipc_client:
+            kwargs = dict(self.kwargs, callback=self.callback)
+            self.result = ipc_client.call(self.target.__name__, *self.args, **kwargs)
+        else:
+            self.result = self.target(*self.args, **self.kwargs)
 
 
     def on_finished(self):
     func._thread.start()
 
 
+ipc_client = None #enable_ipc()
 set_async_method(async_pyqt)
 
 
     
     def __init__(self, textedit):
         super(CompleterPopup, self).__init__(None)
+        self.setMinimumHeight(150)
         self._textedit = textedit
         #self.setAlternatingRowColors(True)
         self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
         _async_method(func, *args, **kwargs)
     return wrapper
 
+
+
+class ServiceRoot(object):
+    pass
+
+
+root = ServiceRoot()
+
+
+def register(func):
+    root.__dict__[func.__name__] = func
+    return func
+
+
+def enable_ipc():
+    from asyncipc import IpcServer, Connection, IpcClient
+
+    def create_server():
+        server = IpcServer(root)
+        return server
+
+    con = Connection(create_server)
+    con.start()
+    
+    return IpcClient(con)
+
+
+    
 if __name__ == "__main__":
     app = QApplication(sys.argv)
     win = QMainWindow()
-    prj = Project(".")
     edit = QPlainTextEdit(None)
-    pc = PyCode(prj, edit)
+    pc = PyCode(".", edit)
     edit.setPlainText(open("testedit.py").read())
     win.setCentralWidget(edit)
     win.resize(640, 480)