Skip to content

Commit 8bdb234

Browse files
committed
Add type hints and stubs
1 parent 8405a57 commit 8bdb234

File tree

10 files changed

+590
-36
lines changed

10 files changed

+590
-36
lines changed

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ exclude OTIO_VERSION.json
2424
global-exclude *.pyc
2525
global-exclude *.so
2626
global-exclude *.pyd
27+
global-include *.pyi
2728

2829
prune maintainers
2930
prune tsc

setup.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,8 @@ def run(self):
332332
package_data={
333333
'opentimelineio': [
334334
'adapters/builtin_adapters.plugin_manifest.json',
335+
'*.pyi',
336+
'*/**/*.pyi',
335337
],
336338
},
337339

src/py-opentimelineio/opentimelineio/exceptions.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
UnsupportedSchemaError,
99
CannotComputeAvailableRangeError
1010
)
11+
from typing import Type
1112

1213
__all__ = [
1314
'OTIOError',

src/py-opentimelineio/opentimelineio/hooks.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
plugins,
66
core,
77
)
8+
from typing import Any, Optional, Dict, List
89

910
__doc__ = """
1011
HookScripts are plugins that run at defined points ("Hooks").
@@ -82,14 +83,14 @@ class HookScript(plugins.PythonPlugin):
8283

8384
def __init__(
8485
self,
85-
name=None,
86-
filepath=None,
87-
):
86+
name: Optional[str] = None,
87+
filepath: Optional[str] = None,
88+
) -> None:
8889
"""HookScript plugin constructor."""
8990

9091
super().__init__(name, filepath)
9192

92-
def run(self, in_timeline, argument_map={}):
93+
def run(self, in_timeline: Any, argument_map: Optional[Dict[str, Any]] = {}) -> Any:
9394
"""Run the hook_function associated with this plugin."""
9495

9596
# @TODO: should in_timeline be passed in place? or should a copy be
@@ -100,13 +101,13 @@ def run(self, in_timeline, argument_map={}):
100101
argument_map=argument_map
101102
)
102103

103-
def __str__(self):
104+
def __str__(self) -> str:
104105
return "HookScript({}, {})".format(
105106
repr(self.name),
106107
repr(self.filepath)
107108
)
108109

109-
def __repr__(self):
110+
def __repr__(self) -> str:
110111
return (
111112
"otio.hooks.HookScript("
112113
"name={}, "
@@ -118,24 +119,24 @@ def __repr__(self):
118119
)
119120

120121

121-
def names():
122+
def names() -> List[str]:
122123
"""Return a list of all the registered hooks."""
123124

124125
return plugins.ActiveManifest().hooks.keys()
125126

126127

127-
def available_hookscript_names():
128+
def available_hookscript_names() -> List[str]:
128129
"""Return the names of HookScripts that have been registered."""
129130

130131
return [hs.name for hs in plugins.ActiveManifest().hook_scripts]
131132

132133

133-
def available_hookscripts():
134+
def available_hookscripts() -> List[Any]:
134135
"""Return the HookScripts objects that have been registered."""
135136
return plugins.ActiveManifest().hook_scripts
136137

137138

138-
def scripts_attached_to(hook):
139+
def scripts_attached_to(hook: str) -> List[str]:
139140
"""Return an editable list of all the hook scripts that are attached to
140141
the specified hook, in execution order. Changing this list will change the
141142
order that scripts run in, and deleting a script will remove it from
@@ -146,7 +147,7 @@ def scripts_attached_to(hook):
146147
return plugins.ActiveManifest().hooks[hook]
147148

148149

149-
def run(hook, tl, extra_args=None):
150+
def run(hook: str, tl: Any, extra_args: Optional[Dict[str, Any]] = None) -> Any:
150151
"""Run all the scripts associated with hook, passing in tl and extra_args.
151152
152153
Will return the return value of the last hook script.

src/py-opentimelineio/opentimelineio/media_linker.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import os
2121
import inspect
22+
from typing import Any, Optional, Dict
2223

2324
from . import (
2425
exceptions,
@@ -64,7 +65,7 @@ def from_name(name):
6465
)
6566

6667

67-
def default_media_linker():
68+
def default_media_linker() -> str:
6869
try:
6970
return os.environ['OTIO_DEFAULT_MEDIA_LINKER']
7071
except KeyError:
@@ -74,10 +75,10 @@ def default_media_linker():
7475

7576

7677
def linked_media_reference(
77-
target_clip,
78-
media_linker_name=MediaLinkingPolicy.ForceDefaultLinker,
79-
media_linker_argument_map=None
80-
):
78+
target_clip: Any,
79+
media_linker_name: Any = MediaLinkingPolicy.ForceDefaultLinker,
80+
media_linker_argument_map: Optional[Dict[str, Any]] = None
81+
) -> Any:
8182
media_linker = from_name(media_linker_name)
8283

8384
if not media_linker:
@@ -100,12 +101,12 @@ class MediaLinker(plugins.PythonPlugin):
100101

101102
def __init__(
102103
self,
103-
name=None,
104-
filepath=None,
105-
):
104+
name: Optional[str] = None,
105+
filepath: Optional[str] = None,
106+
) -> None:
106107
super().__init__(name, filepath)
107108

108-
def link_media_reference(self, in_clip, media_linker_argument_map=None):
109+
def link_media_reference(self, in_clip: Any, media_linker_argument_map: Optional[Dict[str, Any]] = None) -> Any:
109110
media_linker_argument_map = media_linker_argument_map or {}
110111

111112
return self._execute_function(
@@ -114,10 +115,10 @@ def link_media_reference(self, in_clip, media_linker_argument_map=None):
114115
media_linker_argument_map=media_linker_argument_map
115116
)
116117

117-
def is_default_linker(self):
118+
def is_default_linker(self) -> bool:
118119
return os.environ.get("OTIO_DEFAULT_MEDIA_LINKER", "") == self.name
119120

120-
def plugin_info_map(self):
121+
def plugin_info_map(self) -> Dict[str, Any]:
121122
"""Adds extra adapter-specific information to call to the parent fn."""
122123

123124
result = super().plugin_info_map()
@@ -133,13 +134,13 @@ def plugin_info_map(self):
133134

134135
return result
135136

136-
def __str__(self):
137+
def __str__(self) -> str:
137138
return "MediaLinker({}, {})".format(
138139
repr(self.name),
139140
repr(self.filepath)
140141
)
141142

142-
def __repr__(self):
143+
def __repr__(self) -> str:
143144
return (
144145
"otio.media_linker.MediaLinker("
145146
"name={}, "

src/py-opentimelineio/opentimelineio/opentime.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,12 @@
3838
RationalTime.duration_from_start_end_time_inclusive
3939
)
4040

41+
from typing import Any, Optional
4142

42-
def to_timecode(rt, rate=None, drop_frame=None):
43+
44+
def to_timecode(
45+
rt: Any, rate: Optional[float] = None, drop_frame: Optional[bool] = None
46+
) -> str:
4347
"""Convert a :class:`~RationalTime` into a timecode string."""
4448
return (
4549
rt.to_timecode()
@@ -48,7 +52,9 @@ def to_timecode(rt, rate=None, drop_frame=None):
4852
)
4953

5054

51-
def to_nearest_timecode(rt, rate=None, drop_frame=None):
55+
def to_nearest_timecode(
56+
rt: Any, rate: Optional[float] = None, drop_frame: Optional[bool] = None
57+
) -> str:
5258
"""Convert a :class:`~RationalTime` into a timecode string."""
5359
return (
5460
rt.to_nearest_timecode()
@@ -57,17 +63,17 @@ def to_nearest_timecode(rt, rate=None, drop_frame=None):
5763
)
5864

5965

60-
def to_frames(rt, rate=None):
66+
def to_frames(rt: Any, rate: Optional[float] = None) -> float:
6167
"""Turn a :class:`~RationalTime` into a frame number."""
6268
return rt.to_frames() if rate is None else rt.to_frames(rate)
6369

6470

65-
def to_seconds(rt):
71+
def to_seconds(rt: Any) -> float:
6672
"""Convert a :class:`~RationalTime` into float seconds"""
6773
return rt.to_seconds()
6874

6975

70-
def to_time_string(rt):
76+
def to_time_string(rt: Any) -> str:
7177
"""
7278
Convert this timecode to time as used by ffmpeg, formatted as
7379
``hh:mm:ss`` where ss is an integer or decimal number.

src/py-opentimelineio/opentimelineio/test_utils.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,30 @@
66
"""Utility assertions for OTIO Unit tests."""
77

88
import re
9+
from typing import Any
910

1011
from . import (
1112
adapters
1213
)
1314

1415

1516
class OTIOAssertions:
16-
def assertJsonEqual(self, known, test_result):
17+
def assertJsonEqual(self, known: Any, test_result: Any) -> None:
1718
"""Convert to json and compare that (more readable)."""
1819
self.maxDiff = None
1920

2021
known_str = adapters.write_to_string(known, 'otio_json')
2122
test_str = adapters.write_to_string(test_result, 'otio_json')
2223

23-
def strip_trailing_decimal_zero(s):
24+
def strip_trailing_decimal_zero(s: str) -> str:
2425
return re.sub(r'"(value|rate)": (\d+)\.0', r'"\1": \2', s)
2526

2627
self.assertMultiLineEqual(
2728
strip_trailing_decimal_zero(known_str),
2829
strip_trailing_decimal_zero(test_str)
2930
)
3031

31-
def assertIsOTIOEquivalentTo(self, known, test_result):
32+
def assertIsOTIOEquivalentTo(self, known: Any, test_result: Any) -> None:
3233
"""Test using the 'is equivalent to' method on SerializableObject"""
3334

3435
self.assertTrue(known.is_equivalent_to(test_result))

src/py-opentimelineio/opentimelineio/url_utils.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77
import urllib
88
from urllib import request
99
import pathlib
10+
from typing import Union, Any
1011

1112

12-
def url_from_filepath(fpath):
13+
def url_from_filepath(fpath: Union[str, os.PathLike]) -> str:
1314
"""Convert a filesystem path to an url in a portable way.
1415
1516
ensures that `fpath` conforms to the following pattern:
@@ -42,7 +43,7 @@ def url_from_filepath(fpath):
4243
)
4344

4445

45-
def filepath_from_url(urlstr):
46+
def filepath_from_url(urlstr: str) -> str:
4647
"""
4748
Take an url and return a filepath.
4849

src/py-opentimelineio/opentimelineio/versioning.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@
44
"""Tools for fetching the family->label->schema:version maps"""
55

66
import copy
7+
from typing import Dict
78

89
from . import (
910
core,
1011
plugins
1112
)
1213

1314

14-
def full_map():
15+
def full_map() -> Dict[str, Dict[str, Dict[str, int]]]:
1516
"""Return the full map of schema version sets, including core and plugins.
1617
Organized as follows:
1718
@@ -57,7 +58,7 @@ def full_map():
5758
return result
5859

5960

60-
def fetch_map(family, label):
61+
def fetch_map(family: str, label: str) -> Dict[str, int]:
6162
"""Fetch the version map for the given family and label. OpenTimelineIO
6263
includes a built in family called "OTIO_CORE", this is compiled into the
6364
C++ core and represents the core interchange schemas of OpenTimelineIO.

0 commit comments

Comments
 (0)