Skip to content

Commit

Permalink
Try using psutil.Popen if available (#85)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ch00k authored Dec 20, 2024
1 parent fbe56cb commit a55e549
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 7 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ jobs:
architecture: x64
- run: |
pip install "cryptography<44.0.0" poetry # cryptography 44.0.0 is not compatible with pypy3.8
poetry install --with dev
- run: poetry run pytest --cov=ffmpy --cov-report xml
poetry install
poetry run pytest --cov=ffmpy --cov-report xml
poetry install --extras psutil
poetry run pytest --cov=ffmpy --cov-report xml --cov-append
- uses: codecov/codecov-action@v4
if: matrix.python-version == 3.12
with:
Expand Down
13 changes: 11 additions & 2 deletions ffmpy/ffmpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@
import subprocess
from typing import IO, Any, Mapping, Sequence

try:
from psutil import Popen # noqa: F401

popen: type[subprocess.Popen | Popen]
except ImportError:
popen = subprocess.Popen
else:
popen = Popen


class FFmpeg:
"""Wrapper for various `FFmpeg <https://www.ffmpeg.org/>`_ related applications (ffmpeg,
Expand Down Expand Up @@ -56,7 +65,7 @@ def __init__(
self._cmd += _merge_args_opts(outputs)

self.cmd = subprocess.list2cmdline(self._cmd)
self.process: subprocess.Popen | None = None
self.process: subprocess.Popen | Popen | None = None

def __repr__(self) -> str:
return f"<{self.__class__.__name__!r} {self.cmd!r}>"
Expand Down Expand Up @@ -100,7 +109,7 @@ def run(
`FFExecutableNotFoundError` in case the executable path passed was not valid
"""
try:
self.process = subprocess.Popen(
self.process = popen(
self._cmd, stdin=subprocess.PIPE, stdout=stdout, stderr=stderr, env=env, **kwargs
)
except OSError as e:
Expand Down
35 changes: 34 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,16 @@ packages = [{ include = "ffmpy" }]

[tool.poetry.dependencies]
python = "^3.8"
psutil = { version = ">=5.5.0", optional = true } # 5.5.0 was realease around the same time as Python 3.8

[tool.poetry.group.dev.dependencies]
mypy = "^1.13.0"
pytest = "^8.3.4"
pytest-cov = "^5.0.0"

[tool.poetry.extras]
psutil = ["psutil"]

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
Expand Down
4 changes: 2 additions & 2 deletions tests/test_cmd_execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ def test_terminate_process() -> None:
assert ff.process.returncode == -15


@mock.patch("ffmpy.ffmpy.subprocess.Popen")
@mock.patch("ffmpy.ffmpy.popen")
def test_custom_env(popen_mock: mock.MagicMock) -> None:
ff = FFmpeg()
popen_mock.return_value.communicate.return_value = ("output", "error")
Expand All @@ -213,7 +213,7 @@ def test_custom_env(popen_mock: mock.MagicMock) -> None:
)


@mock.patch("ffmpy.ffmpy.subprocess.Popen")
@mock.patch("ffmpy.ffmpy.popen")
def test_arbitraty_popen_kwargs(popen_mock: mock.MagicMock) -> None:
ff = FFmpeg()
popen_mock.return_value.communicate.return_value = ("output", "error")
Expand Down

0 comments on commit a55e549

Please sign in to comment.