The `else: proc.stderr = stderr` clause was dropped when the helper
was extracted into `_ltcov_helpers.py`. `stdin` and `stdout` both
have the corresponding else branches; this restores parity so that
callers passing a non-"auto" stderr value have it honoured.
Closes#7044
The StdioTransport.start() method had an unprotected logger.info() call
after successful Popen(). If that call raised, the subprocess would
leak as an orphaned process. Wrap all post-spawn initialization in a
try/except guard: on any exception after spawn, terminate and wait for
the process (with kill fallback), reset state to None, then re-raise
so callers still get proper error semantics.
The existing stop() method cleanup pattern (terminate → wait → kill) is
mirrored here for consistency across the transport lifecycle.
Tests added:
- TDD scenario with @tdd_issue_7044 verifying subprocess cleanup on
post-Popen exception and state reset to None
- Explicit is_alive() scenarios covering both alive and not-alive states
Refactoring:
- Extracted _make_mock_process and _build_lsp_frame helpers into a
shared _ltcov_helpers module to keep step files under the 500-line
CONTRIBUTING.md limit.
ISSUES CLOSED: #7044