Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
marvel
GitHub Repository: marvel/qnf
Path: blob/master/elisp/emacs-for-python/rope-dist/rope/base/oi/doa.py
1428 views
1
import cPickle as pickle
2
import marshal
3
import os
4
import socket
5
import subprocess
6
import sys
7
import tempfile
8
import threading
9
10
11
class PythonFileRunner(object):
12
"""A class for running python project files"""
13
14
def __init__(self, pycore, file_, args=None, stdin=None,
15
stdout=None, analyze_data=None):
16
self.pycore = pycore
17
self.file = file_
18
self.analyze_data = analyze_data
19
self.observers = []
20
self.args = args
21
self.stdin = stdin
22
self.stdout = stdout
23
24
def run(self):
25
"""Execute the process"""
26
env = dict(os.environ)
27
file_path = self.file.real_path
28
path_folders = self.pycore.get_source_folders() + \
29
self.pycore.get_python_path_folders()
30
env['PYTHONPATH'] = os.pathsep.join(folder.real_path
31
for folder in path_folders)
32
runmod_path = self.pycore.find_module('rope.base.oi.runmod').real_path
33
self.receiver = None
34
self._init_data_receiving()
35
send_info = '-'
36
if self.receiver:
37
send_info = self.receiver.get_send_info()
38
args = [sys.executable, runmod_path, send_info,
39
self.pycore.project.address, self.file.real_path]
40
if self.analyze_data is None:
41
del args[1:4]
42
if self.args is not None:
43
args.extend(self.args)
44
self.process = subprocess.Popen(
45
executable=sys.executable, args=args, env=env,
46
cwd=os.path.split(file_path)[0], stdin=self.stdin,
47
stdout=self.stdout, stderr=self.stdout, close_fds=os.name != 'nt')
48
49
def _init_data_receiving(self):
50
if self.analyze_data is None:
51
return
52
# Disabling FIFO data transfer due to blocking when running
53
# unittests in the GUI.
54
# XXX: Handle FIFO data transfer for `rope.ui.testview`
55
if True or os.name == 'nt':
56
self.receiver = _SocketReceiver()
57
else:
58
self.receiver = _FIFOReceiver()
59
self.receiving_thread = threading.Thread(target=self._receive_information)
60
self.receiving_thread.setDaemon(True)
61
self.receiving_thread.start()
62
63
def _receive_information(self):
64
#temp = open('/dev/shm/info', 'w')
65
for data in self.receiver.receive_data():
66
self.analyze_data(data)
67
#temp.write(str(data) + '\n')
68
#temp.close()
69
for observer in self.observers:
70
observer()
71
72
def wait_process(self):
73
"""Wait for the process to finish"""
74
self.process.wait()
75
if self.analyze_data:
76
self.receiving_thread.join()
77
78
def kill_process(self):
79
"""Stop the process"""
80
if self.process.poll() is not None:
81
return
82
try:
83
if hasattr(self.process, 'terminate'):
84
self.process.terminate()
85
elif os.name != 'nt':
86
os.kill(self.process.pid, 9)
87
else:
88
import ctypes
89
handle = int(self.process._handle)
90
ctypes.windll.kernel32.TerminateProcess(handle, -1)
91
except OSError:
92
pass
93
94
def add_finishing_observer(self, observer):
95
"""Notify this observer when execution finishes"""
96
self.observers.append(observer)
97
98
99
class _MessageReceiver(object):
100
101
def receive_data(self):
102
pass
103
104
def get_send_info(self):
105
pass
106
107
108
class _SocketReceiver(_MessageReceiver):
109
110
def __init__(self):
111
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
112
self.data_port = 3037
113
while self.data_port < 4000:
114
try:
115
self.server_socket.bind(('', self.data_port))
116
break
117
except socket.error, e:
118
self.data_port += 1
119
self.server_socket.listen(1)
120
121
def get_send_info(self):
122
return str(self.data_port)
123
124
def receive_data(self):
125
conn, addr = self.server_socket.accept()
126
self.server_socket.close()
127
my_file = conn.makefile('r')
128
while True:
129
try:
130
yield pickle.load(my_file)
131
except EOFError:
132
break
133
my_file.close()
134
conn.close()
135
136
137
class _FIFOReceiver(_MessageReceiver):
138
139
def __init__(self):
140
# XXX: this is insecure and might cause race conditions
141
self.file_name = self._get_file_name()
142
os.mkfifo(self.file_name)
143
144
def _get_file_name(self):
145
prefix = tempfile.gettempdir() + '/__rope_'
146
i = 0
147
while os.path.exists(prefix + str(i).rjust(4, '0')):
148
i += 1
149
return prefix + str(i).rjust(4, '0')
150
151
def get_send_info(self):
152
return self.file_name
153
154
def receive_data(self):
155
my_file = open(self.file_name, 'rb')
156
while True:
157
try:
158
yield marshal.load(my_file)
159
except EOFError:
160
break
161
my_file.close()
162
os.remove(self.file_name)
163
164