Skip to content

Commit 020a0ce

Browse files
committed
Add type stubs for common.py funcs
1 parent f324274 commit 020a0ce

File tree

4 files changed

+55
-36
lines changed

4 files changed

+55
-36
lines changed

av/filter/filter.pyi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,6 @@ class Filter:
1818
inputs: tuple[FilterPad, ...]
1919
outputs: tuple[FilterPad, ...]
2020

21+
def __init__(self, name: str) -> None: ...
22+
2123
filters_available: set[str]

tests/common.py

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
from __future__ import annotations
2+
13
import datetime
24
import errno
35
import functools
46
import os
57
import types
8+
from typing import TYPE_CHECKING
69
from unittest import TestCase as _Base
710

811
import numpy as np
@@ -16,14 +19,22 @@
1619
except ImportError:
1720
has_pillow = False
1821

22+
if TYPE_CHECKING:
23+
from typing import Any, Callable, TypeVar
24+
25+
from PIL.Image import Image
26+
27+
T = TypeVar("T")
28+
29+
1930
__all__ = ("fate_suite",)
2031

2132

2233
is_windows = os.name == "nt"
2334
skip_tests = frozenset(os.environ.get("PYAV_SKIP_TESTS", "").split(","))
2435

2536

26-
def makedirs(path: str) -> None:
37+
def safe_makedirs(path: str) -> None:
2738
try:
2839
os.makedirs(path)
2940
except OSError as e:
@@ -61,22 +72,20 @@ def fate_png() -> str:
6172
return fate_suite("png1/55c99e750a5fd6_50314226.png")
6273

6374

64-
def sandboxed(*args, **kwargs) -> str:
65-
do_makedirs = kwargs.pop("makedirs", True)
66-
base = kwargs.pop("sandbox", None)
67-
timed = kwargs.pop("timed", False)
68-
if kwargs:
69-
raise TypeError("extra kwargs: %s" % ", ".join(sorted(kwargs)))
70-
path = os.path.join(_sandbox(timed=timed) if base is None else base, *args)
71-
if do_makedirs:
72-
makedirs(os.path.dirname(path))
75+
def sandboxed(
76+
*args: str, makedirs: bool = True, sandbox: str | None = None, timed: bool = False
77+
) -> str:
78+
path = os.path.join(_sandbox(timed) if sandbox is None else sandbox, *args)
79+
if makedirs:
80+
safe_makedirs(os.path.dirname(path))
81+
7382
return path
7483

7584

7685
# Decorator for running a test in the sandbox directory
77-
def run_in_sandbox(func):
86+
def run_in_sandbox(func: Callable[..., T]) -> Callable[..., T]:
7887
@functools.wraps(func)
79-
def _inner(self, *args, **kwargs):
88+
def _inner(self: Any, *args: Any, **kwargs: Any) -> T:
8089
current_dir = os.getcwd()
8190
try:
8291
os.chdir(self.sandbox)
@@ -104,13 +113,13 @@ def assertNdarraysEqual(a: np.ndarray, b: np.ndarray) -> None:
104113
assert False, f"ndarrays contents differ\n{msg}"
105114

106115

107-
def assertImagesAlmostEqual(a, b, epsilon=0.1):
116+
def assertImagesAlmostEqual(a: Image, b: Image, epsilon: float = 0.1) -> None:
108117
import PIL.ImageFilter as ImageFilter
109118

110119
assert a.size == b.size
111120
a = a.filter(ImageFilter.BLUR).getdata()
112121
b = b.filter(ImageFilter.BLUR).getdata()
113-
for i, ax, bx in zip(range(len(a)), a, b):
122+
for i, ax, bx in zip(range(len(a)), a, b): # type: ignore
114123
diff = sum(abs(ac / 256 - bc / 256) for ac, bc in zip(ax, bx)) / 3
115124
assert diff < epsilon, f"images differed by {diff} at index {i}; {ax} {bx}"
116125

@@ -119,14 +128,23 @@ class TestCase(_Base):
119128
@classmethod
120129
def _sandbox(cls, timed: bool = True) -> str:
121130
path = os.path.join(_sandbox(timed=timed), cls.__name__)
122-
makedirs(path)
131+
safe_makedirs(path)
123132
return path
124133

125134
@property
126135
def sandbox(self) -> str:
127136
return self._sandbox(timed=True)
128137

129-
def sandboxed(self, *args, **kwargs) -> str:
130-
kwargs.setdefault("sandbox", self.sandbox)
131-
kwargs.setdefault("timed", True)
132-
return sandboxed(*args, **kwargs)
138+
def sandboxed(
139+
self,
140+
*args: str,
141+
makedirs: bool = True,
142+
timed: bool = True,
143+
sandbox: str | None = None,
144+
) -> str:
145+
if sandbox is None:
146+
return sandboxed(
147+
*args, makedirs=makedirs, timed=timed, sandbox=self.sandbox
148+
)
149+
else:
150+
return sandboxed(*args, makedirs=makedirs, timed=timed, sandbox=sandbox)

tests/test_filters.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,19 @@ def generate_audio_frame(
3434
return frame
3535

3636

37-
def pull_until_blocked(graph):
38-
frames = []
37+
def pull_until_blocked(graph: Graph) -> list[av.VideoFrame]:
38+
frames: list[av.VideoFrame] = []
3939
while True:
4040
try:
41-
frames.append(graph.pull())
41+
frames.append(graph.vpull())
4242
except av.AVError as e:
4343
if e.errno != errno.EAGAIN:
4444
raise
4545
return frames
4646

4747

4848
class TestFilters(TestCase):
49-
def test_filter_descriptor(self):
49+
def test_filter_descriptor(self) -> None:
5050
f = Filter("testsrc")
5151
assert f.name == "testsrc"
5252
assert f.description == "Generate test pattern."
@@ -86,24 +86,25 @@ def test_generator_graph(self):
8686
if has_pillow:
8787
frame.to_image().save(self.sandboxed("mandelbrot2.png"))
8888

89-
def test_auto_find_sink(self):
89+
def test_auto_find_sink(self) -> None:
9090
graph = Graph()
9191
src = graph.add("testsrc")
9292
src.link_to(graph.add("buffersink"))
9393
graph.configure()
9494

95-
frame = graph.pull()
95+
frame = graph.vpull()
9696

9797
if has_pillow:
9898
frame.to_image().save(self.sandboxed("mandelbrot3.png"))
9999

100-
def test_delegate_sink(self):
100+
def test_delegate_sink(self) -> None:
101101
graph = Graph()
102102
src = graph.add("testsrc")
103103
src.link_to(graph.add("buffersink"))
104104
graph.configure()
105105

106106
frame = src.pull()
107+
assert isinstance(frame, av.VideoFrame)
107108

108109
if has_pillow:
109110
frame.to_image().save(self.sandboxed("mandelbrot4.png"))

tests/test_videoframe.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,8 @@ def test_opaque() -> None:
4343
assert type(frame.opaque) is tuple and len(frame.opaque) == 2
4444

4545

46-
def test_invalid_pixel_format():
47-
with pytest.raises(
48-
ValueError, match="not a pixel format: '__unknown_pix_fmt'"
49-
) as cm:
46+
def test_invalid_pixel_format() -> None:
47+
with pytest.raises(ValueError, match="not a pixel format: '__unknown_pix_fmt'"):
5048
VideoFrame(640, 480, "__unknown_pix_fmt")
5149

5250

@@ -90,7 +88,7 @@ def test_yuv420p_planes() -> None:
9088
assert frame.planes[i].buffer_size == 320 * 240
9189

9290

93-
def test_yuv420p_planes_align():
91+
def test_yuv420p_planes_align() -> None:
9492
# If we request 8-byte alignment for a width which is not a multiple of 8,
9593
# the line sizes are larger than the plane width.
9694
frame = VideoFrame(318, 238, "yuv420p")
@@ -106,7 +104,7 @@ def test_yuv420p_planes_align():
106104
assert frame.planes[i].buffer_size == 160 * 119
107105

108106

109-
def test_rgb24_planes():
107+
def test_rgb24_planes() -> None:
110108
frame = VideoFrame(640, 480, "rgb24")
111109
assert len(frame.planes) == 1
112110
assert frame.planes[0].width == 640
@@ -115,7 +113,7 @@ def test_rgb24_planes():
115113
assert frame.planes[0].buffer_size == 640 * 480 * 3
116114

117115

118-
def test_memoryview_read():
116+
def test_memoryview_read() -> None:
119117
frame = VideoFrame(640, 480, "rgb24")
120118
frame.planes[0].update(b"01234" + (b"x" * (640 * 480 * 3 - 5)))
121119
mem = memoryview(frame.planes[0])
@@ -129,11 +127,11 @@ def test_memoryview_read():
129127

130128

131129
class TestVideoFrameImage(TestCase):
132-
def setUp(self):
130+
def setUp(self) -> None:
133131
if not has_pillow:
134132
pytest.skip()
135133

136-
def test_roundtrip(self):
134+
def test_roundtrip(self) -> None:
137135
import PIL.Image as Image
138136

139137
image = Image.open(fate_png())
@@ -142,7 +140,7 @@ def test_roundtrip(self):
142140
img.save(self.sandboxed("roundtrip-high.jpg"))
143141
assertImagesAlmostEqual(image, img)
144142

145-
def test_to_image_rgb24(self):
143+
def test_to_image_rgb24(self) -> None:
146144
sizes = [(318, 238), (320, 240), (500, 500)]
147145
for width, height in sizes:
148146
frame = VideoFrame(width, height, format="rgb24")

0 commit comments

Comments
 (0)