|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2020 - 2022 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 ( |
|
15 isPythonProgram, |
|
16 patchArguments, |
|
17 stringToArgumentsWindows, |
|
18 isWindowsPlatform, |
|
19 ) |
|
20 |
|
21 _debugClient = None |
|
22 |
|
23 |
|
24 def patchSubprocess(module, debugClient): |
|
25 """ |
|
26 Function to patch the subprocess module. |
|
27 |
|
28 @param module reference to the imported module to be patched |
|
29 @type module |
|
30 @param debugClient reference to the debug client object |
|
31 @type DebugClient |
|
32 """ # __IGNORE_WARNING_D234__ |
|
33 global _debugClient |
|
34 |
|
35 class PopenWrapper(module.Popen): |
|
36 """ |
|
37 Wrapper class for subprocess.Popen. |
|
38 """ |
|
39 |
|
40 def __init__(self, arguments, *args, **kwargs): |
|
41 """ |
|
42 Constructor |
|
43 |
|
44 @param arguments command line arguments for the new process |
|
45 @type list of str or str |
|
46 @param args constructor arguments of Popen |
|
47 @type list |
|
48 @param kwargs constructor keyword only arguments of Popen |
|
49 @type dict |
|
50 """ |
|
51 if ( |
|
52 _debugClient.debugging |
|
53 and _debugClient.multiprocessSupport |
|
54 and isinstance(arguments, (str, list)) |
|
55 ): |
|
56 if isinstance(arguments, str): |
|
57 # convert to arguments list |
|
58 arguments = ( |
|
59 stringToArgumentsWindows(arguments) |
|
60 if isWindowsPlatform() |
|
61 else shlex.split(arguments) |
|
62 ) |
|
63 else: |
|
64 # create a copy of the arguments |
|
65 arguments = arguments[:] |
|
66 ok = isPythonProgram(arguments[0]) |
|
67 if ok: |
|
68 scriptName = os.path.basename(arguments[0]) |
|
69 if not _debugClient.skipMultiProcessDebugging(scriptName): |
|
70 arguments = patchArguments( |
|
71 _debugClient, arguments, noRedirect=True |
|
72 ) |
|
73 |
|
74 super().__init__(arguments, *args, **kwargs) |
|
75 |
|
76 _debugClient = debugClient |
|
77 module.Popen = PopenWrapper |