Expose PROC_THREAD_ATTRIBUTE_JOB_LIST through subprocess on Windows
I would like to propose exposing Windows PROC_THREAD_ATTRIBUTE_JOB_LIST through subprocess.STARTUPINFO.lpAttributeList.
CPython currently exposes PROC_THREAD_ATTRIBUTE_HANDLE_LIST through:
startupinfo = subprocess.STARTUPINFO(
lpAttributeList={
"handle_list": [...],
}
)
Windows also supports PROC_THREAD_ATTRIBUTE_JOB_LIST, which allows a process to be associated with one or more Job Objects as part of CreateProcessW.
A possible Python API would be:
startupinfo = subprocess.STARTUPINFO(
lpAttributeList={
"job_list": [job_handle],
}
)
process = subprocess.Popen(
command,
startupinfo=startupinfo,
)
Motivation
Applications that require Job Object membership to exist at process creation time currently cannot express that operation through subprocess.Popen().
Using:
CreateProcessW(...)
AssignProcessToJobObject(...)
after process creation is not equivalent when atomic process ownership is required.
Windows already provides the required mechanism through STARTUPINFOEX and PROC_THREAD_ATTRIBUTE_JOB_LIST.
Exposing it through the existing lpAttributeList interface would avoid requiring applications to implement their own native CreateProcessW wrapper.
Proposed semantics
job_list would:
-
contain existing Windows Job Object handles;
-
use
PROC_THREAD_ATTRIBUTE_JOB_LISTin the existingSTARTUPINFOEXpath; -
not create Job Objects automatically;
-
not alter Job breakaway policy;
-
not make Job handles inheritable merely because they appear in
job_list; -
preserve the existing behavior of
handle_list; -
allow
handle_listandjob_listto be used together.
Prototype
I have implemented and tested a prototype against current CPython main.
The implementation extends the existing _winapi.CreateProcess() attribute-list code rather than introducing a separate process launcher.
Validation on Windows x64 Debug CPython currently includes:
-
CPython debug build: PASS, 0 warnings / 0 errors
-
test_subprocess: PASS -
reference-leak testing with
-R 3:3: PASS -
dependent
test_winapi,test_asyncio, andtest_multiprocessing_spawn: 3,104 tests PASS -
live Job membership verified with
IsProcessInJob -
combined
handle_list+job_listbehavior tested -
malformed input tested
-
non-
KeyErrormapping exceptions verified to propagate instead of silently dropping the attribute
The current prototype has also undergone a separate review with no remaining P0/P1/P2/P3 findings.
I have not opened a pull request yet because I wanted to get feedback on whether exposing this through STARTUPINFO.lpAttributeList["job_list"] is an acceptable API direction first.
Questions I would especially appreciate feedback on:
-
Is
lpAttributeList["job_list"]the appropriate public API? -
Should multiple Job Object handles be supported exactly as Windows exposes them?
-
Are there compatibility or API-design concerns that would make a different interface preferable?