Expose PROC_THREAD_ATTRIBUTE_JOB_LIST through subprocess on Windows

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_LIST in the existing STARTUPINFOEX path;

  • 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_list and job_list to 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, and test_multiprocessing_spawn: 3,104 tests PASS

  • live Job membership verified with IsProcessInJob

  • combined handle_list + job_list behavior tested

  • malformed input tested

  • non-KeyError mapping 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:

  1. Is lpAttributeList["job_list"] the appropriate public API?

  2. Should multiple Job Object handles be supported exactly as Windows exposes them?

  3. Are there compatibility or API-design concerns that would make a different interface preferable?