Skip to content

Commit

Permalink
Fix mypy warning
Browse files Browse the repository at this point in the history
  • Loading branch information
yukihiko-shinoda committed Aug 15, 2021
1 parent 96534b8 commit daf5f08
Show file tree
Hide file tree
Showing 13 changed files with 50 additions and 42 deletions.
2 changes: 1 addition & 1 deletion asyncffmpeg/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ class Error(Exception):
class FFmpegProcessError(Error):
"""FFmpeg process failed."""

def __init__(self, message, exit_code):
def __init__(self, message: str, exit_code: int) -> None:
super().__init__(message)
self.exit_code = exit_code
4 changes: 2 additions & 2 deletions asyncffmpeg/ffmpeg_coroutine.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""FFmpeg coroutine interface."""
import asyncio
from logging import getLogger
from typing import Awaitable, Callable, Optional, Type, TypeVar
from typing import Any, Awaitable, Callable, Optional, Type, TypeVar

from asyncffmpeg.ffmpegprocess.interface import FFmpegProcess
from asyncffmpeg.type_alias import StreamSpec
Expand Down Expand Up @@ -35,7 +35,7 @@ async def execute(
self,
create_stream_spec: Callable[[], Awaitable[StreamSpec]],
*,
after_start: Optional[Callable[[TypeVarFFmpegProcess], Awaitable]] = None
after_start: Optional[Callable[[TypeVarFFmpegProcess], Awaitable[Any]]] = None
) -> None:
"""
Executes FFmpeg process.
Expand Down
6 changes: 3 additions & 3 deletions asyncffmpeg/ffmpegprocess/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def __init__(self, time_to_force_termination: int) -> None:
self.realtime_pipe_reader = self.create_realtime_pipe_reader()

@abstractmethod
def create_popen(self) -> Popen:
def create_popen(self) -> Popen[bytes]:
raise NotImplementedError() # pragma: no cover

def create_realtime_pipe_reader(self) -> RealtimePipeReader:
Expand All @@ -51,7 +51,7 @@ async def wait(self) -> None:
self.logger.error("return_code = %d", return_code)
raise FFmpegProcessError(stderr, return_code)

async def quit(self, time_to_force_termination: Optional[int] = None) -> None:
async def quit(self, time_to_force_termination: Optional[float] = None) -> None:
"""
Quits FFmpeg process.
see: https://github.com/kkroening/ffmpeg-python/issues/162#issuecomment-571820244
Expand Down Expand Up @@ -83,5 +83,5 @@ def __init__(self, time_to_force_termination: int, stream_spec: StreamSpec) -> N
super().__init__(time_to_force_termination)

@abstractmethod
def create_popen(self) -> Popen:
def create_popen(self) -> Popen[bytes]:
raise NotImplementedError() # pragma: no cover
8 changes: 5 additions & 3 deletions asyncffmpeg/ffmpegprocess/posix.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Archive process."""
from subprocess import Popen
from typing import Optional

import ffmpeg

Expand All @@ -9,10 +10,11 @@
class FFmpegProcessPosix(FFmpegProcess):
"""FFmpeg process wrapping Popen object."""

def create_popen(self) -> Popen:
return ffmpeg.run_async(self.stream_spec, pipe_stdin=True, pipe_stdout=True, pipe_stderr=True)
def create_popen(self) -> Popen[bytes]:
# Reason: Requires to update ffmpeg-python side.
return ffmpeg.run_async(self.stream_spec, pipe_stdin=True, pipe_stdout=True, pipe_stderr=True) # type: ignore

async def quit(self, time_to_force_termination: int = None) -> None:
async def quit(self, time_to_force_termination: Optional[float] = None) -> None:
# Otherwise, we'll get OSError: [Errno 9] Bad file descriptor.
self.realtime_pipe_reader.stop()
await super().quit(time_to_force_termination)
4 changes: 2 additions & 2 deletions asyncffmpeg/ffmpegprocess/windows.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ def __init__(self, time_to_force_termination: int, argument: List[str]) -> None:
win32api.SetConsoleCtrlHandler(None, False)
win32api.SetConsoleCtrlHandler(self.handle, True)

def create_popen(self) -> Popen:
def create_popen(self) -> Popen[bytes]:
# Reason: This method is instead of ffmpeg.run_async(). pylint: disable=consider-using-with
return Popen(["ffmpeg", *self.argument], stdin=PIPE, stdout=PIPE, stderr=PIPE)

def handle(self, event):
def handle(self, event: int) -> int:
"""Handle console control events (like Ctrl-C)."""
if event in (
win32con.CTRL_C_EVENT,
Expand Down
5 changes: 3 additions & 2 deletions asyncffmpeg/ffmpegprocess/windows_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

# Reason: CREATE_NEW_PROCESS_GROUP is packaged only in Windows
from subprocess import CREATE_NEW_PROCESS_GROUP, PIPE, Popen # type: ignore
from typing import Optional

import ffmpeg

Expand All @@ -21,7 +22,7 @@
class FFmpegProcessWindowsWrapper(FFmpegProcess):
"""FFmpeg process wrapping Popen object."""

def create_popen(self) -> Popen:
def create_popen(self) -> Popen[bytes]:
argument = [
sys.executable,
str(Path(__file__).resolve().parent / "windows.py"),
Expand All @@ -35,7 +36,7 @@ def create_popen(self) -> Popen:
def create_realtime_pipe_reader(self) -> RealtimePipeReader:
return StringRealtimePipeReader(self.popen)

async def quit(self, time_to_force_termination: int = None) -> None:
async def quit(self, time_to_force_termination: Optional[float] = None) -> None:
self.logger.info(self.realtime_pipe_reader.read_stdout())
self.logger.error(self.realtime_pipe_reader.read_stderr())
self.popen.wait(time_to_force_termination)
Expand Down
20 changes: 10 additions & 10 deletions asyncffmpeg/pipe/pipe_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,41 @@
from logging import getLogger
from queue import Queue
from threading import Event, Thread
from typing import IO
from typing import IO, List, Union


class PipeManager:
"""Logs pipe output and stores it into queue."""

def __init__(self, event: Event, pipe: IO):
def __init__(self, event: Event, pipe: IO[bytes]) -> None:
self.event = event
self.queue: Queue = Queue()
self.queue: Queue[bytes] = Queue()
self.logger = getLogger(__name__)
self.thread = self.create_thread(pipe)

def create_thread(self, pipe: IO):
def create_thread(self, pipe: IO[bytes]) -> Thread:
thread = Thread(target=self.log, args=(pipe,))
thread.daemon = True # thread dies with the program
thread.start()
return thread

@abstractmethod
def log(self, pipe: IO):
def log(self, pipe: IO[bytes]) -> None:
raise NotImplementedError() # pragma: no cover

@abstractmethod
def read(self):
def read(self) -> Union[str, List[bytes]]:
raise NotImplementedError() # pragma: no cover


class BytesPipeManager(PipeManager):
"""For bytes."""

def __init__(self, event: Event, pipe: IO, frame_bytes: int):
def __init__(self, event: Event, pipe: IO[bytes], frame_bytes: int):
self.frame_bytes = frame_bytes
super().__init__(event, pipe)

def log(self, pipe: IO):
def log(self, pipe: IO[bytes]) -> None:
with pipe:
try:
while True:
Expand All @@ -50,7 +50,7 @@ def log(self, pipe: IO):
except ValueError as error: # pragma: no cover
self.logger.info(error, exc_info=True)

def read(self):
def read(self) -> List[bytes]:
"""
Vacuums stderr by get_nowait().
see:
Expand All @@ -66,7 +66,7 @@ def read(self):
class StringPipeManager(PipeManager):
"""For strings."""

def log(self, pipe: IO) -> None:
def log(self, pipe: IO[bytes]) -> None:
with pipe:
try:
for line in iter(pipe.readline, b""):
Expand Down
23 changes: 12 additions & 11 deletions asyncffmpeg/pipe/realtime_pipe_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,34 @@
from abc import abstractmethod
from subprocess import Popen
from threading import Event
from typing import Optional
from typing import List, Optional, Union

from asyncffmpeg.pipe.pipe_manager import BytesPipeManager, StringPipeManager


class RealtimePipeReader:
"""Abstract class."""

def __init__(self):
def __init__(self) -> None:
self.event = Event()

@abstractmethod
def read_stdout(self):
def read_stdout(self) -> Union[str, List[bytes]]:
raise NotImplementedError() # pragma: no cover

@abstractmethod
def read_stderr(self):
def read_stderr(self) -> str:
raise NotImplementedError() # pragma: no cover

@abstractmethod
def stop(self):
def stop(self) -> None:
raise NotImplementedError() # pragma: no cover


class StringRealtimePipeReader(RealtimePipeReader):
"""For strings."""

def __init__(self, popen: Popen) -> None:
def __init__(self, popen: Popen[bytes]) -> None:
super().__init__()
assert popen.stdout is not None
assert popen.stderr is not None
Expand All @@ -56,7 +56,7 @@ def stop(self) -> None:
class FFmpegRealtimePipeReader(RealtimePipeReader):
"""For FFmpeg."""

def __init__(self, popen: Popen, *, frame_bytes: Optional[int] = None):
def __init__(self, popen: Popen[bytes], *, frame_bytes: Optional[int] = None):
super().__init__()
assert popen.stdout is not None
assert popen.stderr is not None
Expand All @@ -65,13 +65,14 @@ def __init__(self, popen: Popen, *, frame_bytes: Optional[int] = None):
None if frame_bytes is None else BytesPipeManager(self.event, popen.stdout, frame_bytes)
)

def read_stdout(self):
return self.pipe_manager_stdout.read()
def read_stdout(self) -> List[bytes]:
# Reason: omit if statement for excluding None for performance.
return self.pipe_manager_stdout.read() # type: ignore

def read_stderr(self):
def read_stderr(self) -> str:
return self.pipe_manager_stderr.read()

def stop(self):
def stop(self) -> None:
self.event.set()
self.pipe_manager_stderr.thread.join()
if self.pipe_manager_stdout is not None:
Expand Down
7 changes: 4 additions & 3 deletions asyncffmpeg/type_alias.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
"""Type alias."""
from typing import Dict, List, Tuple, Union
from typing import Any, Dict, List, Tuple, Union

from ffmpeg.nodes import Stream
# Reason: Maybe, requires to update ffmpeg-python side.
from ffmpeg.nodes import Stream # type: ignore

__all__ = ["StreamSpec"]

StreamSpec = Union[None, Stream, List, Tuple, Dict]
StreamSpec = Union[None, Stream, List, Tuple[Any], Dict]
4 changes: 2 additions & 2 deletions tests/pipe/test_realtime_pipe_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,5 @@ def create_popen(path_file_input: Path) -> Popen[bytes]:
stream = ffmpeg.input(path_file_input)
stream = ffmpeg.filter(stream, "scale", 768, -1)
stream_spec = ffmpeg.output(stream, "pipe:", f="rawvideo").global_args("-n")

return ffmpeg.run_async(stream_spec, pipe_stdin=True, pipe_stdout=True, pipe_stderr=True)
# Reason: Requires to update ffmpeg-python side.
return ffmpeg.run_async(stream_spec, pipe_stdin=True, pipe_stdout=True, pipe_stderr=True) # type: ignore
3 changes: 2 additions & 1 deletion tests/test_ffmpeg_coroutine.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
import pytest
from pytest import LogCaptureFixture

from asyncffmpeg import FFmpegCoroutineFactory, FFmpegProcessError
# Reason: Following export method in __init__.py from Effective Python 2nd Edition item 85
from asyncffmpeg import FFmpegCoroutineFactory, FFmpegProcessError # type: ignore
from asyncffmpeg.ffmpegprocess.interface import FFmpegProcess
from tests.testlibraries import SECOND_SLEEP_FOR_TEST_KEYBOARD_INTERRUPT_CTRL_C_POSIX, SECOND_SLEEP_FOR_TEST_LONG
from tests.testlibraries.create_stream_spec_croutine import (
Expand Down
3 changes: 2 additions & 1 deletion tests/testlibraries/create_stream_spec_croutine.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

import ffmpeg

from asyncffmpeg import StreamSpec
# Reason: Following export method in __init__.py from Effective Python 2nd Edition item 85
from asyncffmpeg import StreamSpec # type: ignore


class CreateStreamSpecCoroutineCopy:
Expand Down
3 changes: 2 additions & 1 deletion tests/testlibraries/example_use_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
# Reason: mypy issue: https://github.com/python/mypy/issues/10198
from asynccpu import ProcessTaskPoolExecutor # type: ignore

from asyncffmpeg import FFmpegCoroutineFactory
# Reason: Following export method in __init__.py from Effective Python 2nd Edition item 85
from asyncffmpeg import FFmpegCoroutineFactory # type: ignore
from tests.testlibraries.create_stream_spec_croutine import CreateStreamSpecCoroutineFilter
from tests.testlibraries.keyboardinterrupter.local_socket import LocalSocket

Expand Down

0 comments on commit daf5f08

Please sign in to comment.