Skip to content

Commit 3b7e466

Browse files
authored
Merge pull request #363 from justjanne/type-hints
Type Checking
2 parents 4456a75 + 700cdd2 commit 3b7e466

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1245
-549
lines changed

.github/workflows/test.yaml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Test
1+
name: Build
22

33
on: [push]
44

@@ -18,8 +18,13 @@ jobs:
1818
with:
1919
python-version-file: "pyproject.toml"
2020
- name: Install the project
21-
run: uv sync --dev
22-
- name: Run tests
21+
run: |-
22+
uv venv --system-site-packages
23+
uv pip install pygobject-stubs --config-settings=config=Gtk3,Gdk3
24+
uv sync --dev
25+
- name: Typechecking
26+
run: uv run mypy -p voctocore -p voctogui
27+
- name: Tests
2328
run: uv run pytest
2429
docker:
2530
runs-on: ubuntu-latest

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@ those.
1010

1111
```bash
1212
uv venv --system-site-packages
13-
uv sync
14-
uv pip install pygobject-stubs --config-settings=config=Gtk3
13+
uv pip install pygobject-stubs --config-settings=config=Gtk3,Gdk3
14+
uv sync --dev
1515
```
1616

1717
## Tests
1818

1919
```bash
2020
uv run pytest
21+
uv run mypy -p voctocore -p voctogui
2122
```
2223

2324
## Current Documentation

pyproject.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ readme = "README.md"
66
requires-python = ">=3.11"
77
dependencies = [
88
"scipy>=1.15.2",
9+
"scipy-stubs>=1.15.2.1",
910
"sdnotify>=0.3.2",
1011
]
1112

@@ -14,11 +15,20 @@ dev = [
1415
"mock>=5.2.0",
1516
"pytest>=8.3.5",
1617
"pygobject-stubs>=2.13.0",
18+
"mypy>=1.15.0",
1719
]
1820

1921
[tool.uv]
2022
python-preference = "only-system"
2123

24+
[tool.mypy]
25+
mypy_path = "python_stubs"
26+
exclude = "tests|venv"
27+
28+
[[tool.mypy.overrides]]
29+
module = ["cairo.*"]
30+
ignore_missing_imports = true
31+
2232
[tool.pytest.ini_options]
2333
testpaths = [
2434
"voctocore/tests",
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import enum
2+
3+
from gi.repository import Gst, GLib
4+
5+
6+
# https://gstreamer.freedesktop.org/documentation/controller/gsttimedvaluecontrolsource.html?gi-language=python
7+
8+
class ControlPoint:
9+
timestamp: int = ...
10+
value: float = ...
11+
12+
def copy(self) -> ControlPoint: ...
13+
def free(self) -> None: ...
14+
15+
class TimedValueControlSource(Gst.ControlSource):
16+
class Props(Gst.ControlSource.Props): ...
17+
18+
parent: Gst.ControlSource = ...
19+
props: Props = ...
20+
21+
lock: GLib.Mutex = ...
22+
values: list[Gst.TimedValue] = ...
23+
nvalues: int = ...
24+
valid_cache: bool = ...
25+
26+
def find_control_point_iter(self, timestamp: int) -> GLib.SequenceIter: ...
27+
def get_all(self) -> list[Gst.TimedValue]: ...
28+
def get_count(self) -> int: ...
29+
def set(self, timestamp: int, value: float) -> bool: ...
30+
def set_from_list(self, timedvalues: list[Gst.TimedValue]) -> bool: ...
31+
def unset(self, timestamp: int) -> bool: ...
32+
def unset_all(self) -> bool: ...
33+
34+
def timed_value_control_invalidate_cache(source: TimedValueControlSource) -> None: ...
35+
36+
# https://gstreamer.freedesktop.org/documentation/controller/gstinterpolationcontrolsource.html?gi-language=python
37+
38+
class InterpolationControlSource(TimedValueControlSource):
39+
class Props(TimedValueControlSource.Props):
40+
mode: InterpolationMode
41+
42+
parent: TimedValueControlSource = ...
43+
props: Props = ...
44+
45+
@staticmethod
46+
def new() -> InterpolationControlSource: ...
47+
48+
class InterpolationMode(enum.IntEnum):
49+
NONE = 0
50+
LINEAR = 1
51+
CUBIC = 2
52+
CUBIC_MONOTONIC = 3
53+
54+
# https://gstreamer.freedesktop.org/documentation/controller/gsttriggercontrolsource.html?gi-language=python
55+
56+
class TriggerControlSource(TimedValueControlSource):
57+
class Props(TimedValueControlSource.Props):
58+
tolerance: int
59+
60+
parent: TimedValueControlSource = ...
61+
props: Props = ...
62+
63+
@staticmethod
64+
def new() -> TriggerControlSource: ...
65+
66+
# https://gstreamer.freedesktop.org/documentation/controller/gstlfocontrolsource.html?gi-language=python
67+
68+
class LFOControlSource(Gst.ControlSource):
69+
class Props(Gst.ControlSource.Props):
70+
amplitude: float
71+
frequency: float
72+
offset: float
73+
timeshift: int
74+
waveform: LFOWaveform
75+
76+
parent: Gst.ControlSource = ...
77+
props: Props = ...
78+
79+
@staticmethod
80+
def new() -> LFOControlSource: ...
81+
82+
class LFOWaveform(enum.IntEnum):
83+
SINE = 0
84+
SQUARE = 1
85+
SAW = 2
86+
REVERSE_SAW = 3
87+
TRIANGLE = 4
88+
89+
# https://gstreamer.freedesktop.org/documentation/controller/gstargbcontrolbinding.html?gi-language=python
90+
91+
class ARGBControlBinding(Gst.ControlBinding):
92+
class Props(Gst.ControlBinding.Props):
93+
control_source_a: Gst.ControlSource
94+
control_source_r: Gst.ControlSource
95+
control_source_g: Gst.ControlSource
96+
control_source_b: Gst.ControlSource
97+
98+
parent: Gst.ControlBinding = ...
99+
props: Props = ...
100+
101+
@staticmethod
102+
def new(object: Gst.Object, property_name: str, cs_a: Gst.ControlSource, cs_r: Gst.ControlSource, cs_g: Gst.ControlSource, cs_b: Gst.ControlSource) -> ARGBControlBinding: ...
103+
104+
# https://gstreamer.freedesktop.org/documentation/controller/gstdirectcontrolbinding.html?gi-language=python
105+
106+
class DirectControlBinding(Gst.ControlBinding):
107+
class Props(Gst.ControlBinding.Props):
108+
absolute: bool
109+
control_source: Gst.ControlSource
110+
111+
parent: Gst.ControlBinding = ...
112+
props: Props = ...
113+
114+
@staticmethod
115+
def new(object: Gst.Object, property_name: str, cs: Gst.ControlSource) -> DirectControlBinding: ...
116+
117+
@staticmethod
118+
def new_absolute(object: Gst.Object, property_name: str, cs: Gst.ControlSource) -> DirectControlBinding: ...
119+
120+
# https://gstreamer.freedesktop.org/documentation/controller/gstproxycontrolbinding.html?gi-language=python
121+
122+
class ProxyControlBinding(Gst.ControlBinding):
123+
@staticmethod
124+
def new(object: Gst.Object, property_name: str, ref_object: Gst.Object, ref_property_name: str) -> ProxyControlBinding: ...
125+
126+
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
from typing import Any, Optional, Callable
2+
3+
from gi.repository import Gst, GObject, Gio
4+
5+
6+
# https://gstreamer.freedesktop.org/documentation/net/gstnetaddressmeta.html?gi-language=python
7+
8+
class NetAddressMeta(Gst.Meta):
9+
meta: Gst.Meta
10+
addr: Gio.SocketAddress
11+
12+
def net_address_meta_get_info() -> Gst.MetaInfo: ...
13+
def buffer_add_net_address_meta(buffer: Gst.Buffer, addr: Gio.SocketAddress) -> NetAddressMeta: ...
14+
def buffer_get_net_address_meta(buffer: Gst.Buffer) -> NetAddressMeta: ...
15+
def net_address_meta_api_get_type() -> GObject.GType: ...
16+
17+
# https://gstreamer.freedesktop.org/documentation/net/gstnetclientclock.html?gi-language=python
18+
19+
class NetClientClock(Gst.SystemClock):
20+
class Props(Gst.SystemClock.Props):
21+
address: str
22+
base_time: int
23+
bus: Gst.Bus
24+
internal_clock: Gst.Clock
25+
minimum_update_interval: int
26+
port: int
27+
qos_dscp: int
28+
round_trip_limit: int
29+
30+
props: Props = ...
31+
32+
clock: Gst.SystemClock = ...
33+
34+
@staticmethod
35+
def new(name: str, remote_address: str, remote_port: int, base_time: int) -> 'NetClientClock': ...
36+
37+
# https://gstreamer.freedesktop.org/documentation/net/gstnetcontrolmessagemeta.html?gi-language=python
38+
39+
class NetControlMessageMeta(Gst.Meta):
40+
meta: Gst.Meta
41+
message: Gio.SocketControlMessage
42+
43+
def net_control_message_meta_get_info() -> Gst.MetaInfo: ...
44+
def buffer_add_net_control_message_meta(buffer: Gst.Buffer, message: Gio.SocketControlMessage) -> NetControlMessageMeta: ...
45+
def net_control_message_meta_api_get_type() -> GObject.GType: ...
46+
47+
# https://gstreamer.freedesktop.org/documentation/net/gstnettimepacket.html?gi-language=python
48+
49+
NET_TIME_PACKET_SIZE = 16
50+
51+
class NetTimePacket:
52+
local_time: int = ...
53+
remote_time: int = ...
54+
55+
@staticmethod
56+
def new(buffer: list[int]) -> NetTimePacket: ...
57+
58+
def copy(self) -> NetTimePacket: ...
59+
def free(self) -> None: ...
60+
def send(self, socket: Gio.Socket, dest_address: Gio.SocketAddress) -> bool: ...
61+
def serialize(self) -> list[int]: ...
62+
63+
def net_time_packet_receive(socket: Gio.Socket) -> tuple[NetTimePacket, Gio.SocketAddress]: ...
64+
65+
# https://gstreamer.freedesktop.org/documentation/net/gstnettimeprovider.html?gi-language=python
66+
67+
class NetTimeProvider(Gst.Object):
68+
class Props(Gst.Object.Props):
69+
active: bool
70+
address: str
71+
clock: Gst.Clock
72+
port: int
73+
qos_dscp: int
74+
75+
props: Props = ...
76+
77+
@staticmethod
78+
def new(clock: Gst.Clock, address: str, port: int) -> 'NetTimeProvider': ...
79+
80+
# https://gstreamer.freedesktop.org/documentation/net/gstnetclientclock.html?gi-language=python#GstNtpClock
81+
82+
class NtpClock(NetClientClock):
83+
@staticmethod
84+
def new(name: str, remote_address: str, remote_port: int, base_time: int) -> 'NtpClock': ...
85+
86+
# https://gstreamer.freedesktop.org/documentation/net/gstptpclock.html?gi-language=python
87+
88+
PTP_CLOCK_ID_NONE: int = ...
89+
PTP_STATISTICS_BEST_MASTER_CLOCK_SELECTED: str = "GstPtpStatisticsBestMasterClockSelected"
90+
PTP_STATISTICS_NEW_DOMAIN_FOUND: str = "GstPtpStatisticsNewDomainFound"
91+
PTP_STATISTICS_PATH_DELAY_MEASURED: str = "GstPtpStatisticsPathDelayMeasured"
92+
PTP_STATISTICS_TIME_UPDATED: str = "GstPtpStatisticsTimeUpdated"
93+
94+
class PtpClock(Gst.SystemClock):
95+
class Props(Gst.SystemClock.Props):
96+
domain: int
97+
grandmaster_clock_id: int
98+
internal_clock: Gst.Clock
99+
master_clock_id: int
100+
101+
props: Props = ...
102+
103+
@staticmethod
104+
def new(name: str, domain: int) -> 'PtpClock': ...
105+
106+
def ptp_deinit() -> None: ...
107+
def ptp_init(clock_id: int, interfaces: list[str]) -> bool: ...
108+
def ptp_init_full(config: Gst.Structure) -> bool: ...
109+
def ptp_is_initialized() -> bool: ...
110+
def ptp_is_supported() -> bool: ...
111+
112+
PtpStatisticsCallback = Callable[[int, Gst.Structure, Any], bool]
113+
def ptp_statistics_callback_add(callback: Optional[PtpStatisticsCallback] = None, *user_data: Any) -> int: ...
114+
def ptp_statistics_callback_remove(id: int) -> None: ...
115+
116+
# https://gstreamer.freedesktop.org/documentation/net/gstnetutils.html?gi-language=python
117+
118+
def net_utils_set_socket_tos(socket: Gio.Socket, qos_dscp: int) -> bool: ...
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# https://gstreamer.freedesktop.org/documentation/video/gstvideo.html?gi-language=python
2+
3+
4+
class GstVideoAlignment:
5+
padding_top: int
6+
padding_bottom: int
7+
padding_left: int
8+
padding_right: int
9+
stride_align: list[int]
10+
11+
def reset(self) -> None: ...
12+
13+
def video_calculate_display_ratio(video_width: int, video_height: int, video_par_n: int, video_par_d: int, display_par_n: int, display_par_d: int) -> tuple[bool, int, int]: ...
14+
def video_guess_framerate(duration: int) -> tuple[bool, int, int]: ...
15+
def video_is_common_aspect_ratio(width: int, height: int, par_n: int, par_d: int) -> bool: ...
16+
17+
GST_META_TAG_VIDEO_COLORSPACE_STR = "colorspace"
18+
GST_META_TAG_VIDEO_ORIENTATION_STR = "orientation"
19+
GST_META_TAG_VIDEO_SIZE_STR = "size"
20+
GST_META_TAG_VIDEO_STR = "video"

python_stubs/sdnotify.pyi

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from typing import Protocol
2+
3+
4+
class SystemdNotifier(Protocol):
5+
def notify(self, state: str) -> None:
6+
pass

0 commit comments

Comments
 (0)