144 "method": method, |
146 "method": method, |
145 "params": params, |
147 "params": params, |
146 } |
148 } |
147 return json.dumps(commandDict) + '\n' |
149 return json.dumps(commandDict) + '\n' |
148 |
150 |
149 |
151 ########################################################################### |
150 def isPythonProgram(program, arguments): |
152 ## Things related to monkey patching below |
151 """ |
153 ########################################################################### |
152 Function to check, if program is a Python interpreter and |
154 |
153 arguments don't include '-m'. |
155 |
154 |
156 PYTHON_NAMES = ["python", "pypy"] |
155 @param program program to be executed |
157 |
156 @type str |
158 |
157 @param arguments list of command line arguments |
159 def isWindowsPlatform(): |
158 @type list of str |
160 """ |
159 @return flag indicating a python program and a tuple containing the |
161 Function to check, if this is a Windows platform. |
160 interpreter to be used and the arguments |
162 |
161 @rtype tuple of (bool, tuple of (str, list of str)) |
163 @return flag indicating Windows platform |
162 """ |
164 @rtype bool |
163 prog = program.lower() |
165 """ |
164 ok = ( |
166 return sys.platform.startswith(("win", "cygwin")) |
165 ("python" in prog and arguments[0] != '-m') or |
167 |
166 "pypy" in prog |
168 |
|
169 def isExecutable(program): |
|
170 """ |
|
171 Function to check, if the given program is executable. |
|
172 |
|
173 @param program program path to be checked |
|
174 @type str |
|
175 @return flag indicating an executable program |
|
176 @rtype bool |
|
177 """ |
|
178 return os.access(os.path.abspath(program), os.X_OK) |
|
179 |
|
180 |
|
181 def startsWithShebang(program): |
|
182 """ |
|
183 Function to check, if the given program start with a Shebang line. |
|
184 |
|
185 @param program program path to be checked |
|
186 @type str |
|
187 @return flag indicating an existing and valid shebang line |
|
188 @rtype bool |
|
189 """ |
|
190 try: |
|
191 with open(program) as f: |
|
192 for line in f: |
|
193 line = line.strip() |
|
194 if line: |
|
195 for name in PYTHON_NAMES: |
|
196 if line.startswith('#!/usr/bin/env {0}'.format(name)): |
|
197 return True |
|
198 return False |
|
199 except UnicodeDecodeError: |
|
200 return False |
|
201 except Exception: |
|
202 traceback.print_exc() |
|
203 return False |
|
204 |
|
205 |
|
206 def isPythonProgram(program): |
|
207 """ |
|
208 Function to check, if the given program is a Python interpreter or |
|
209 program. |
|
210 |
|
211 @param program program to be checked |
|
212 @type str |
|
213 @return flag indicating a Python interpreter or program |
|
214 @rtype bool |
|
215 """ |
|
216 prog = os.path.basename(program).lower() |
|
217 for pyname in PYTHON_NAMES: |
|
218 if pyname in prog: |
|
219 return True |
|
220 |
|
221 return ( |
|
222 not isWindowsPlatform() and |
|
223 isExecutable(program) and |
|
224 startsWithShebang(program) |
167 ) |
225 ) |
168 return ok, (program, arguments[:]) |
226 |
169 |
227 |
170 |
228 def patchArguments(debugClient, arguments, noRedirect=False): |
171 def patchArguments(debugClient, arguments, multiprocessSupport, |
|
172 noRedirect=False): |
|
173 """ |
229 """ |
174 Function to patch the arguments given to start a program in order to |
230 Function to patch the arguments given to start a program in order to |
175 execute it in our debugger. |
231 execute it in our debugger. |
176 |
232 |
177 @param debugClient reference to the debug client object |
233 @param debugClient reference to the debug client object |
178 @type DebugClient |
234 @type DebugClient |
179 @param arguments list of program arguments |
235 @param arguments list of program arguments |
180 @type list of str |
236 @type list of str |
181 @param multiprocessSupport flag indicating multi process debug support |
|
182 @type bool |
|
183 @param noRedirect flag indicating to not redirect stdin and stdout |
237 @param noRedirect flag indicating to not redirect stdin and stdout |
184 @type bool |
238 @type bool |
185 @return modified argument list |
239 @return modified argument list |
186 @rtype list of str |
240 @rtype list of str |
187 """ |
241 """ |
|
242 # TODO: support #! line |
188 (wd, host, port, exceptions, tracePython, redirect, noencoding |
243 (wd, host, port, exceptions, tracePython, redirect, noencoding |
189 ) = debugClient.startOptions[:7] |
244 ) = debugClient.startOptions[:7] |
190 |
245 |
191 modifiedArguments = [ |
246 modifiedArguments = [ |
|
247 arguments[0], # interpreter (should be modified if #! line |
192 os.path.join(os.path.dirname(__file__), "DebugClient.py"), |
248 os.path.join(os.path.dirname(__file__), "DebugClient.py"), |
193 "-h", host, |
249 "-h", host, |
194 "-p", str(port), |
250 "-p", str(port), |
195 "--no-passive", |
251 "--no-passive", |
196 ] |
252 ] |
203 modifiedArguments.append("-t") |
259 modifiedArguments.append("-t") |
204 if noRedirect or not redirect: |
260 if noRedirect or not redirect: |
205 modifiedArguments.append("-n") |
261 modifiedArguments.append("-n") |
206 if noencoding: |
262 if noencoding: |
207 modifiedArguments.append("--no-encoding") |
263 modifiedArguments.append("--no-encoding") |
208 if multiprocessSupport: |
264 if debugClient.multiprocessSupport: |
209 modifiedArguments.append("--multiprocess") |
265 modifiedArguments.append("--multiprocess") |
210 modifiedArguments.append("--") |
266 modifiedArguments.append("--") |
211 # end the arguments for DebugClient |
267 # end the arguments for DebugClient |
212 modifiedArguments.extend(arguments) |
268 |
|
269 # append the arguments for the program to be debugged |
|
270 modifiedArguments.extend(arguments[1:]) |
213 |
271 |
214 return modifiedArguments |
272 return modifiedArguments |
215 |
273 |
216 # |
274 # |
217 # eflag: noqa = M702 |
275 # eflag: noqa = M702 |