|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2020 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing a function to patch subprocess.Popen to support debugging |
|
8 of the process. |
|
9 """ |
|
10 |
|
11 import os |
|
12 import shlex |
|
13 |
|
14 from DebugUtilities import isPythonProgram, startsWithShebang, patchArguments |
|
15 |
|
16 _debugClient = None |
|
17 |
|
18 |
|
19 def patchSubprocess(module, debugClient): |
|
20 """ |
|
21 Function to patch the subprocess module. |
|
22 |
|
23 @param module reference to the imported module to be patched |
|
24 @type module |
|
25 @param debugClient reference to the debug client object |
|
26 @type DebugClient |
|
27 """ # __IGNORE_WARNING_D234__ |
|
28 global _debugClient |
|
29 |
|
30 # TODO: implement a process tracer |
|
31 # i.e. report which processes are started |
|
32 class PopenWrapper(module.Popen): |
|
33 """ |
|
34 Wrapper class for subprocess.Popen. |
|
35 """ |
|
36 def __init__(self, arguments, *args, **kwargs): |
|
37 """ |
|
38 Constructor |
|
39 |
|
40 @param arguments command line arguments for the new process |
|
41 @type list of str or str |
|
42 @param args constructor arguments of Popen |
|
43 @type list |
|
44 @param kwargs constructor keword only arguments of Popen |
|
45 @type dict |
|
46 """ |
|
47 if ( |
|
48 _debugClient.debugging and |
|
49 _debugClient.multiprocessSupport and |
|
50 isinstance(arguments, (str, list)) |
|
51 ): |
|
52 if isinstance(arguments, str): |
|
53 # convert to arguments list |
|
54 arguments = shlex.split(arguments) |
|
55 else: |
|
56 # create a copy of the arguments |
|
57 arguments = arguments[:] |
|
58 ok = isPythonProgram(arguments[0]) |
|
59 if ok: |
|
60 if startsWithShebang(arguments[0]): |
|
61 scriptName = os.path.basename(arguments[0]) |
|
62 else: |
|
63 scriptName = os.path.basename(arguments[0]) |
|
64 if scriptName not in _debugClient.noDebugList: |
|
65 arguments = patchArguments( |
|
66 _debugClient, arguments, noRedirect=True |
|
67 ) |
|
68 |
|
69 super(PopenWrapper, self).__init__(arguments, *args, **kwargs) |
|
70 |
|
71 _debugClient = debugClient |
|
72 module.Popen = PopenWrapper |