My only comments:
with StandardOutput() as stdout: ... if stdout: ...
You'll need two context managers if you want to also handle stderr - at least if you want to continue using each one inheriting from
with StandardOutput() as stdout, StandardError() as stderr: ... if stdout: ... if stderr: ...
The redundancy between the