Skip to content

Commit c86b6d5

Browse files
committed
PythonCodeCompletion: 1. fix problem with buffering on windows (would cause hang) 2. tidy up the python_completion_server
1 parent 8aff5c1 commit c86b6d5

2 files changed

Lines changed: 33 additions & 37 deletions

File tree

‎PythonCodeCompletion/python/python_completion_server.py‎

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
1-
import code
21
import sys
32
import os.path
4-
import time
5-
import types
63
import struct
74
import xmlrpclib
85
from SimpleXMLRPCServer import SimpleXMLRPCServer
9-
#from pysmell import idehelper
10-
#from pysmell import tags
11-
from re import split
126
from rope.contrib import codeassist
137
import rope.base.project
148

159
'''
10+
Rope type/scope combinations
11+
type
12+
scope
1613
| | instance | class | function | module | None
1714
| local | + | + | + | + |
1815
| global | + | + | + | + |
@@ -23,23 +20,8 @@
2320
| parameter_keyword | | | | | +
2421
'''
2522

26-
'''
27-
type_map = {
28-
str(types.ModuleType) : 1,
29-
str(types.ClassType) : 2,
30-
str(types.ObjectType) : 3,
31-
str(types.TypeType) : 4,
32-
str(types.InstanceType) : 5,
33-
str(types.FunctionType) : 6,
34-
str(types.MethodType) : 7,
35-
str(types.UnboundMethodType) : 8,
36-
str(types.BuiltinFunctionType) : 6,
37-
str(types.BuiltinMethodType) : 7,
38-
str(types.LambdaType) : 9,
39-
str(types.GeneratorType) : 10 }
40-
'''
41-
4223
def type_suffix(o):
24+
#TODO: Add type/scope combinations here adding more bitmaps to the list in the plugin
4325
t = o.type
4426
s = o.scope
4527
if t=='instance':
@@ -57,15 +39,23 @@ def type_suffix(o):
5739
isz=struct.calcsize('I')
5840

5941
class XmlRpcPipeServer:
42+
'''
43+
A simple XMLRPC server implementation that uses the stdin, stdout
44+
pipes to communicate with the owner of the process. Implements
45+
most of the features of SimpleXMLRPCServer
46+
'''
6047
def __init__(self):
6148
self.fn_dict={}
6249
self.inpipe=sys.stdin
6350
self.outpipe=sys.stdout
6451
sys.stdout=open(os.devnull,'wb')
52+
6553
def register_function(self,fn,name):
6654
self.fn_dict[name]=fn
55+
6756
def register_introspection_functions(self):
6857
pass
58+
6959
def handle_request(self):
7060
##TODO: Need more error handling!
7161
size_buf = self.inpipe.read(isz)
@@ -81,23 +71,28 @@ def handle_request(self):
8171
res_xml = bytes(xmlrpclib.dumps(result, methodresponse=True))
8272
except:
8373
import traceback
84-
res_xml='Error running call'+name+call_xml+'\n'
74+
res_xml='Error running call'+name+'\n'+call_xml+'\n'
8575
res_xml+='\n'.join(traceback.format_exception(*sys.exc_info()))
8676
size = len(res_xml)
8777
self.outpipe.write(struct.pack('I',size))
8878
self.outpipe.write(res_xml)
79+
8980
def __call__(self,name,*args):
9081
return self.fn_dict[name](*args)
9182

9283

93-
class PyCompletionServer:
84+
class PythonCompletionServer:
85+
'''
86+
An XMLRPC server that serves up a rope interface
87+
'''
9488
def __init__(self,port):
9589
# Create XMLRPC server
9690
self.timeout=0.2
9791
self._quit=False
9892
self.port=port
9993
self.project=None
10094
self.active_path=None
95+
10196
def run(self):
10297
if self.port==-1:
10398
self.server = XmlRpcPipeServer()
@@ -112,6 +107,7 @@ def run(self):
112107
self.server.register_function(self.get_definition_location,'get_definition_location')
113108
while not self._quit:
114109
self.server.handle_request()
110+
115111
def notify_active_path(self,path):
116112
if self.active_path==os.path.split(path)[0]:
117113
return True
@@ -124,11 +120,9 @@ def notify_active_path(self,path):
124120
except:
125121
return False
126122
return True
123+
127124
def complete_phrase(self,path,source,position):
128125
# print 'complete context',path,position
129-
# if '\r' in source:
130-
# print 'replacing CRs'
131-
# source=source.replace('\r\n',' \n').replace('\r','\n')
132126
if path!=None:
133127
if not self.notify_active_path(path):
134128
return []
@@ -137,9 +131,9 @@ def complete_phrase(self,path,source,position):
137131
results = codeassist.code_assist(self.project, source, position)
138132
completions=sorted([s.name+type_suffix(s) for s in results])
139133
return completions
134+
140135
def complete_tip(self,path,source,position):
141136
# print 'complete tip',symbol
142-
# source=source.replace('\r\n',' \n').replace('\r','\n')
143137
if path!=None:
144138
if not self.notify_active_path(path):
145139
return []
@@ -175,6 +169,7 @@ def complete_tip(self,path,source,position):
175169
if calltip==None:
176170
calltip='<unknown function>'
177171
return calltip
172+
178173
def get_definition_location(self,path,source,position):
179174
if path!=None:
180175
if not self.notify_active_path(path):
@@ -185,6 +180,7 @@ def get_definition_location(self,path,source,position):
185180
if resource == None:
186181
return [path,lineno]
187182
return [resource.path,lineno]
183+
188184
def end(self):
189185
self._quit=True
190186
return True
@@ -205,5 +201,5 @@ def cmd_err():
205201
if port<-1:
206202
cmd_err()
207203

208-
server=PyCompletionServer(port)
204+
server=PythonCompletionServer(port)
209205
server.run()

‎PythonCodeCompletion/xmlrpc_embedder.cpp‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -139,22 +139,22 @@ class XmlRpcPipeClient
139139
std::cout<<"bad request value"<<std::endl;
140140
return false;
141141
}
142-
uint32_t r_size=msg.size();
142+
uint32_t r_size=msg.size(); //TODO: Is it safer to use uint64_t (would need to use long long on the python side)
143143
m_ostream->Write(&r_size,sizeof(uint32_t));
144-
m_ostream->Write(msg.c_str(),msg.size());
144+
for(uint32_t i=0;i<msg.size();++i)
145+
m_ostream->PutC(msg[i]);
146+
// m_ostream->Write(msg.c_str(),msg.size()); //On windows, this will frequently result in an incomplete write becasue the buffer gets full so better to use the blocking PutC instead
145147
std::cout<<"wrote "<<msg<<std::endl;
146-
std::cout<<"wrote "<<r_size<<std::endl;
148+
std::cout<<"with size "<<r_size<<std::endl;
147149
char ch=m_istream->GetC();
148150
std::cout<<"read ch "<<ch<<std::endl;
149-
for(int i=0;i<sizeof(uint32_t);i++)
151+
for(uint32_t i=0;i<sizeof(uint32_t);i++)
150152
((char*)(&r_size))[i]=m_istream->GetC();
151153
std::cout<<"response size is "<<r_size<<std::endl;
152154
char *buf = new char[r_size+1];
153-
for(int i=0;i<r_size;i++)
155+
for(uint32_t i=0;i<r_size;i++)
154156
buf[i]=m_istream->GetC();
155-
//// m_istream->Read(buf,r_size);
156157
buf[r_size]=0;
157-
int offset=0;
158158
std::cout<<"response was "<<std::string(buf)<<std::endl;
159159
if(parseResponse(std::string(buf), result))
160160
{
@@ -321,7 +321,7 @@ long XmlRpcInstance::LaunchProcess(const wxString &processcmd)
321321
#ifdef __WXMSW__
322322
//by default wxExecute shows the terminal window on MSW (redirecting would hide it, but that breaks the process if buffers are not flushed periodically)
323323
if(m_port==-1)
324-
m_proc_id=wxExecute(processcmd,wxEXEC_ASYNC|wxEXEC_MAKE_GROUP_LEADER,m_proc);
324+
m_proc_id=wxExecute(processcmd,wxEXEC_ASYNC/*|wxEXEC_MAKE_GROUP_LEADER*/,m_proc);
325325
else
326326
m_proc_id=wxExecuteHidden(processcmd,wxEXEC_ASYNC|wxEXEC_MAKE_GROUP_LEADER,m_proc);
327327
#else

0 commit comments

Comments
 (0)