cli.output: use subprocess.DEVNULL in PlayerOutput

Instead of passing `os.devnull` file-handles to `subprocess.Popen`,
use the `subprocess.DEVNULL` identifier for stdout/stderr streams.

This avoids `ResourceWarning`s in tests when the file-handles don't get
closed despite never calling `PlayerOutput.open()`, as they were already
opened in the `PlayerOutput`'s constructor, e.g. during test collection
in parametrized tests without indirect fixtures.

Also call `PlayerOutput.close()` in tests where a *mocked* player output
was explicitly opened.
This commit is contained in:
bastimeyer 2023-03-12 11:52:23 +01:00 committed by Forrest
parent 33d9790b07
commit f635705cbe
3 changed files with 13 additions and 20 deletions

View File

@ -117,8 +117,8 @@ class PlayerOutput(Output):
self.stdin = subprocess.PIPE
if self.quiet:
self.stdout = open(os.devnull, "w")
self.stderr = open(os.devnull, "w")
self.stdout = subprocess.DEVNULL
self.stderr = subprocess.DEVNULL
else:
self.stdout = sys.stdout
self.stderr = sys.stderr
@ -203,18 +203,12 @@ class PlayerOutput(Output):
return shlex.split(cmd) + extra_args + shlex.split(args)
def _open(self):
try:
if self.record:
self.record.open()
if self.call and self.filename:
self._open_call()
else:
self._open_subprocess()
finally:
if self.quiet:
# Output streams no longer needed in parent process
self.stdout.close()
self.stderr.close()
if self.record:
self.record.open()
if self.call and self.filename:
self._open_call()
else:
self._open_subprocess()
def _open_call(self):
args = self._create_arguments()

View File

@ -1,4 +1,3 @@
from contextlib import suppress
from unittest.mock import Mock, call, patch
import pytest
@ -8,11 +7,10 @@ from streamlink_cli.output import PlayerOutput
@pytest.fixture()
def playeroutput(request: pytest.FixtureRequest):
playeroutput = PlayerOutput(**getattr(request, "param", {}))
yield playeroutput
for stream in playeroutput.stdout, playeroutput.stderr:
with suppress(OSError):
stream.close()
with patch("streamlink_cli.output.sleep"):
playeroutput = PlayerOutput(**getattr(request, "param", {}))
yield playeroutput
playeroutput.close()
@pytest.fixture()

View File

@ -175,6 +175,7 @@ class TestPlayerOutput:
output = FakePlayerOutput("mocked")
output.open()
yield output
output.close()
@pytest.fixture()
def stream_runner(self, stream: FakeStream, output: FakePlayerOutput):