Skip to content

Commit

Permalink
add FakePopenWrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
Michal Poddubiuk committed Oct 2, 2024
1 parent 570fbaf commit 63768f5
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 1 deletion.
14 changes: 13 additions & 1 deletion pytest_subprocess/process_dispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@
from copy import deepcopy
from functools import partial
from typing import Any as AnyType
from typing import AnyStr
from typing import Awaitable
from typing import Callable
from typing import Deque
from typing import Dict
from typing import Generic
from typing import List
from typing import Optional
from typing import Tuple
Expand All @@ -29,6 +31,9 @@
from .fake_process import FakeProcess


__all__ = ["ProcessDispatcher"]


class ProcessDispatcher:
"""Main class for handling processes."""

Expand All @@ -44,7 +49,7 @@ class ProcessDispatcher:
def register(cls, process: "FakeProcess") -> None:
if not cls.process_list:
cls.built_in_popen = subprocess.Popen
subprocess.Popen = cls.dispatch # type: ignore
subprocess.Popen = FakePopenWrapper # type: ignore

cls.built_in_async_subprocess = asyncio.subprocess
asyncio.create_subprocess_shell = cls.async_shell # type: ignore
Expand Down Expand Up @@ -238,3 +243,10 @@ def _get_process(
if processes and isinstance(processes, deque):
return command_instance, processes, process_instance
return None, None, None


class FakePopenWrapper(Generic[AnyStr]):
def __new__( # type: ignore
cls, command: COMMAND, **kwargs: Optional[Dict]
) -> FakePopen:
return ProcessDispatcher.dispatch(command, **kwargs) # type: ignore
22 changes: 22 additions & 0 deletions tests/test_subprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -1232,3 +1232,25 @@ def test_process_recorder(fp):
recorder.clear()

assert not recorder.was_called()


def test_fake_popen_is_typed(fp):
fp.allow_unregistered(True)
fp.register(
[PYTHON, "example_script.py"],
stdout=b"Stdout line 1\r\nStdout line 2\r\n",
)

def spawn_process() -> subprocess.Popen[str]:
import subprocess

return subprocess.Popen(
(PYTHON, "example_script.py"),
universal_newlines=True,
stdout=subprocess.PIPE,
)

proc = spawn_process()
proc.wait()

assert proc.stdout.read() == "Stdout line 1\nStdout line 2\n"

0 comments on commit 63768f5

Please sign in to comment.