1# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
2# For details: https://github.com/pylint-dev/astroid/blob/main/LICENSE
3# Copyright (c) https://github.com/pylint-dev/astroid/blob/main/CONTRIBUTORS.txt
4
5import textwrap
6
7from astroid import nodes
8from astroid.brain.helpers import register_module_extender
9from astroid.builder import parse
10from astroid.const import PY311_PLUS
11from astroid.manager import AstroidManager
12
13
14def _subprocess_transform() -> nodes.Module:
15 communicate = (bytes("string", "ascii"), bytes("string", "ascii"))
16 communicate_signature = "def communicate(self, input=None, timeout=None)"
17 args = """\
18 self, args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None,
19 preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None,
20 universal_newlines=None, startupinfo=None, creationflags=0, restore_signals=True,
21 start_new_session=False, pass_fds=(), *, encoding=None, errors=None, text=None,
22 user=None, group=None, extra_groups=None, umask=-1, pipesize=-1"""
23 if PY311_PLUS:
24 args += ", process_group=None"
25
26 init = f"""
27 def __init__({args}):
28 pass"""
29 wait_signature = "def wait(self, timeout=None)"
30 ctx_manager = """
31 def __enter__(self): return self
32 def __exit__(self, *args): pass
33 """
34 py3_args = "args = []"
35
36 check_output_signature = """
37 check_output(
38 args, *,
39 stdin=None,
40 stderr=None,
41 shell=False,
42 cwd=None,
43 encoding=None,
44 errors=None,
45 universal_newlines=False,
46 timeout=None,
47 env=None,
48 text=None,
49 restore_signals=True,
50 preexec_fn=None,
51 pass_fds=(),
52 input=None,
53 bufsize=0,
54 executable=None,
55 close_fds=False,
56 startupinfo=None,
57 creationflags=0,
58 start_new_session=False
59 ):
60 """.strip()
61
62 code = textwrap.dedent(f"""
63 def {check_output_signature}
64 if universal_newlines:
65 return ""
66 return b""
67
68 class Popen(object):
69 returncode = pid = 0
70 stdin = stdout = stderr = file()
71 {py3_args}
72
73 {communicate_signature}:
74 return {communicate!r}
75 {wait_signature}:
76 return self.returncode
77 def poll(self):
78 return self.returncode
79 def send_signal(self, signal):
80 pass
81 def terminate(self):
82 pass
83 def kill(self):
84 pass
85 {ctx_manager}
86 @classmethod
87 def __class_getitem__(cls, item):
88 pass
89 """)
90
91 init_lines = textwrap.dedent(init).splitlines()
92 indented_init = "\n".join(" " * 4 + line for line in init_lines)
93 code += indented_init
94 return parse(code)
95
96
97def register(manager: AstroidManager) -> None:
98 register_module_extender(manager, "subprocess", _subprocess_transform)