vsjetengine 1.2.0__tar.gz → 1.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/PKG-INFO +1 -1
  2. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/tests/test_futures.py +120 -7
  3. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/tests/test_hospice.py +2 -2
  4. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/tests/test_loop_adapters.py +5 -5
  5. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/tests/test_vpy.py +2 -2
  6. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/vsengine/__init__.py +1 -0
  7. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/vsengine/_helpers.py +2 -2
  8. vsjetengine-1.4.0/vsengine/_version.py +2 -0
  9. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/vsengine/adapters/asyncio.py +2 -2
  10. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/vsengine/adapters/trio.py +2 -2
  11. vsjetengine-1.4.0/vsengine/futures.py +595 -0
  12. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/vsengine/loops.py +3 -3
  13. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/vsengine/policy.py +6 -6
  14. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/vsengine/video.py +1 -1
  15. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/vsengine/vpy.py +1 -1
  16. vsjetengine-1.2.0/vsengine/_futures.py +0 -372
  17. vsjetengine-1.2.0/vsengine/_version.py +0 -2
  18. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/.gitignore +0 -0
  19. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/COPYING +0 -0
  20. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/README.md +0 -0
  21. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/pyproject.toml +0 -0
  22. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/tests/__init__.py +0 -0
  23. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/tests/_testutils.py +0 -0
  24. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/tests/conftest.py +0 -0
  25. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/tests/fixtures/heuristic_examples.json +0 -0
  26. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/tests/fixtures/test.vpy +0 -0
  27. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/tests/test_helpers.py +0 -0
  28. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/tests/test_loops.py +0 -0
  29. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/tests/test_policy.py +0 -0
  30. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/tests/test_policy_store.py +0 -0
  31. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/tests/test_video.py +0 -0
  32. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/vsengine/_hospice.py +0 -0
  33. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/vsengine/_nodes.py +0 -0
  34. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/vsengine/adapters/__init__.py +0 -0
  35. {vsjetengine-1.2.0 → vsjetengine-1.4.0}/vsengine/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vsjetengine
3
- Version: 1.2.0
3
+ Version: 1.4.0
4
4
  Summary: An engine for vapoursynth previewers, renderers and script analyis tools.
5
5
  Project-URL: Source Code, https://github.com/Jaded-Encoding-Thaumaturgy/vs-jet-engine
6
6
  Project-URL: Contact, https://discord.gg/XTpc6Fa9eB
@@ -7,14 +7,14 @@
7
7
 
8
8
  import contextlib
9
9
  import threading
10
- from collections.abc import AsyncIterator, Iterator
10
+ from collections.abc import AsyncGenerator, Generator, Iterator
11
11
  from concurrent.futures import Future
12
12
  from typing import Any
13
13
 
14
14
  import pytest
15
15
 
16
- from vsengine._futures import UnifiedFuture, UnifiedIterator, unified
17
16
  from vsengine.adapters.asyncio import AsyncIOLoop
17
+ from vsengine.futures import UnifiedFuture, UnifiedIterator, unified
18
18
  from vsengine.loops import NO_LOOP, set_loop
19
19
 
20
20
 
@@ -32,7 +32,7 @@ def reject(err: BaseException) -> Future[Any]:
32
32
 
33
33
  def contextmanager_helper() -> Future[Any]:
34
34
  @contextlib.contextmanager
35
- def noop() -> Iterator[int]:
35
+ def noop() -> Generator[int]:
36
36
  yield 1
37
37
 
38
38
  return resolve(noop())
@@ -40,7 +40,7 @@ def contextmanager_helper() -> Future[Any]:
40
40
 
41
41
  def asynccontextmanager_helper() -> Future[Any]:
42
42
  @contextlib.asynccontextmanager
43
- async def noop() -> AsyncIterator[int]:
43
+ async def noop() -> AsyncGenerator[int]:
44
44
  yield 2
45
45
 
46
46
  return resolve(noop())
@@ -141,9 +141,6 @@ def test_unified_future_catch() -> None:
141
141
 
142
142
  @pytest.mark.asyncio
143
143
  async def test_unified_future_add_loop_callback() -> None:
144
- from vsengine.adapters.asyncio import AsyncIOLoop
145
- from vsengine.loops import set_loop
146
-
147
144
  set_loop(AsyncIOLoop())
148
145
 
149
146
  def _init_thread(fut: Future[threading.Thread]) -> None:
@@ -170,6 +167,122 @@ async def test_unified_future_add_loop_callback() -> None:
170
167
  assert cb_thread != loop_thread
171
168
 
172
169
 
170
+ @pytest.mark.asyncio
171
+ async def test_unified_future_add_loop_callback_chaining() -> None:
172
+ set_loop(AsyncIOLoop())
173
+
174
+ fut = Future[int]()
175
+ unified_fut = UnifiedFuture.from_future(fut)
176
+
177
+ recorded_value: int | None = None
178
+
179
+ def _side_effect(f: Future[int]) -> None:
180
+ nonlocal recorded_value
181
+ recorded_value = f.result() * 2
182
+
183
+ chained_fut = unified_fut.add_loop_callback(_side_effect)
184
+
185
+ results = list[int]()
186
+ chained_fut.then(lambda val: results.append(val))
187
+
188
+ fut.set_result(21)
189
+
190
+ res = await chained_fut
191
+ assert res == 21
192
+ assert results == [21]
193
+ assert recorded_value == 42
194
+
195
+
196
+ @pytest.mark.asyncio
197
+ async def test_unified_future_then_on_loop() -> None:
198
+ set_loop(AsyncIOLoop())
199
+
200
+ fut = Future[int]()
201
+ unified_fut = UnifiedFuture.from_future(fut)
202
+
203
+ loop_thread: threading.Thread | None = None
204
+ callback_thread: threading.Thread | None = None
205
+
206
+ def _init_thread() -> None:
207
+ fut.set_result(42)
208
+
209
+ def _on_success(v: int) -> int:
210
+ nonlocal callback_thread
211
+ callback_thread = threading.current_thread()
212
+ return v * 2
213
+
214
+ chained = unified_fut.then(_on_success, on_loop=True)
215
+
216
+ thr = threading.Thread(target=_init_thread)
217
+ thr.start()
218
+
219
+ res = await chained
220
+ loop_thread = threading.current_thread()
221
+
222
+ assert callback_thread == loop_thread
223
+ assert res == 84
224
+
225
+
226
+ @pytest.mark.asyncio
227
+ async def test_unified_future_map_on_loop() -> None:
228
+ set_loop(AsyncIOLoop())
229
+
230
+ fut = Future[int]()
231
+ unified_fut = UnifiedFuture.from_future(fut)
232
+
233
+ loop_thread: threading.Thread | None = None
234
+ callback_thread: threading.Thread | None = None
235
+
236
+ def _init_thread() -> None:
237
+ fut.set_result(10)
238
+
239
+ def _map_fn(v: int) -> str:
240
+ nonlocal callback_thread
241
+ callback_thread = threading.current_thread()
242
+ return f"value: {v}"
243
+
244
+ chained = unified_fut.map(_map_fn, on_loop=True)
245
+
246
+ thr = threading.Thread(target=_init_thread)
247
+ thr.start()
248
+
249
+ res = await chained
250
+ loop_thread = threading.current_thread()
251
+
252
+ assert callback_thread == loop_thread
253
+ assert res == "value: 10"
254
+
255
+
256
+ @pytest.mark.asyncio
257
+ async def test_unified_future_catch_on_loop() -> None:
258
+ set_loop(AsyncIOLoop())
259
+
260
+ fut = Future[int]()
261
+ unified_fut = UnifiedFuture.from_future(fut)
262
+
263
+ loop_thread: threading.Thread | None = None
264
+ callback_thread: threading.Thread | None = None
265
+
266
+ def _init_thread() -> None:
267
+ fut.set_exception(ValueError("error!"))
268
+
269
+ def _catch_fn(e: BaseException) -> str:
270
+ nonlocal callback_thread
271
+ callback_thread = threading.current_thread()
272
+ return str(e)
273
+
274
+ chained = unified_fut.catch(_catch_fn, on_loop=True)
275
+
276
+ thr = threading.Thread(target=_init_thread)
277
+ thr.start()
278
+
279
+ res = await chained
280
+ loop_thread = threading.current_thread()
281
+
282
+ assert callback_thread == loop_thread
283
+ assert res == "error!"
284
+
285
+
173
286
  # UnifiedIterator tests
174
287
 
175
288
 
@@ -9,7 +9,7 @@ import contextlib
9
9
  import gc
10
10
  import logging
11
11
  import weakref
12
- from collections.abc import Iterator
12
+ from collections.abc import Generator, Iterator
13
13
  from typing import Any
14
14
 
15
15
  import pytest
@@ -53,7 +53,7 @@ class MockEnv:
53
53
 
54
54
 
55
55
  @contextlib.contextmanager
56
- def hide_logs() -> Iterator[None]:
56
+ def hide_logs() -> Generator[None]:
57
57
  logging.disable(logging.CRITICAL)
58
58
  try:
59
59
  yield
@@ -42,7 +42,7 @@ class AdapterTest:
42
42
  """Base class for event loop adapter tests."""
43
43
 
44
44
  @contextlib.contextmanager
45
- def with_loop(self) -> Iterator[EventLoop]:
45
+ def with_loop(self) -> Generator[EventLoop]:
46
46
  loop = self.make_loop()
47
47
  set_loop(loop)
48
48
  try:
@@ -60,7 +60,7 @@ class AdapterTest:
60
60
  raise NotImplementedError
61
61
 
62
62
  @contextlib.contextmanager
63
- def assert_cancelled(self) -> Iterator[None]:
63
+ def assert_cancelled(self) -> Generator[None]:
64
64
  raise NotImplementedError
65
65
 
66
66
  @make_async
@@ -216,7 +216,7 @@ class TestNoLoop(AdapterTest):
216
216
  pass
217
217
 
218
218
  @contextlib.contextmanager
219
- def assert_cancelled(self) -> Iterator[None]:
219
+ def assert_cancelled(self) -> Generator[None]:
220
220
  with pytest.raises(CancelledError):
221
221
  yield
222
222
 
@@ -244,7 +244,7 @@ class TestAsyncIO(AsyncAdapterTest):
244
244
  return await asyncio.wait_for(coro, timeout)
245
245
 
246
246
  @contextlib.contextmanager
247
- def assert_cancelled(self) -> Iterator[None]:
247
+ def assert_cancelled(self) -> Generator[None]:
248
248
  with pytest.raises(asyncio.CancelledError):
249
249
  yield
250
250
 
@@ -309,6 +309,6 @@ else:
309
309
  return await coro
310
310
 
311
311
  @contextlib.contextmanager
312
- def assert_cancelled(self) -> Iterator[None]:
312
+ def assert_cancelled(self) -> Generator[None]:
313
313
  with pytest.raises(trio.Cancelled):
314
314
  yield
@@ -15,7 +15,7 @@ import textwrap
15
15
  import threading
16
16
  import types
17
17
  import weakref
18
- from collections.abc import Callable, Iterator
18
+ from collections.abc import Callable, Generator
19
19
  from pathlib import Path
20
20
  from typing import Any
21
21
 
@@ -44,7 +44,7 @@ PATH: str = os.path.join(DIR, "fixtures", "test.vpy")
44
44
 
45
45
 
46
46
  @contextlib.contextmanager
47
- def noop() -> Iterator[None]:
47
+ def noop() -> Generator[None]:
48
48
  yield
49
49
 
50
50
 
@@ -13,6 +13,7 @@ Parts:
13
13
  - vpy: Run .vpy-scripts in your application.
14
14
  """
15
15
 
16
+ from vsengine.futures import *
16
17
  from vsengine.loops import *
17
18
  from vsengine.policy import *
18
19
  from vsengine.video import *
@@ -4,7 +4,7 @@
4
4
  # This project is licensed under the EUPL-1.2
5
5
  # SPDX-License-Identifier: EUPL-1.2
6
6
  import contextlib
7
- from collections.abc import Iterator
7
+ from collections.abc import Generator
8
8
 
9
9
  import vapoursynth as vs
10
10
 
@@ -13,7 +13,7 @@ from vsengine.policy import ManagedEnvironment
13
13
 
14
14
  # Automatically set the environment within that block.
15
15
  @contextlib.contextmanager
16
- def use_inline(function_name: str, env: vs.Environment | ManagedEnvironment | None) -> Iterator[None]:
16
+ def use_inline(function_name: str, env: vs.Environment | ManagedEnvironment | None) -> Generator[None]:
17
17
  if env is None:
18
18
  # Ensure there is actually an environment set in this block.
19
19
  try:
@@ -0,0 +1,2 @@
1
+ __version__ = "1.4.0"
2
+ __version_tuple__ = (1, 4, 0)
@@ -7,7 +7,7 @@
7
7
  import asyncio
8
8
  import contextlib
9
9
  import contextvars
10
- from collections.abc import Callable, Iterator
10
+ from collections.abc import Callable, Generator
11
11
  from concurrent.futures import Future
12
12
 
13
13
  from vsengine.loops import Cancelled, EventLoop
@@ -78,7 +78,7 @@ class AsyncIOLoop(EventLoop):
78
78
  return await asyncio.wrap_future(future, loop=self.loop)
79
79
 
80
80
  @contextlib.contextmanager
81
- def wrap_cancelled(self) -> Iterator[None]:
81
+ def wrap_cancelled(self) -> Generator[None]:
82
82
  try:
83
83
  yield
84
84
  except Cancelled:
@@ -5,7 +5,7 @@
5
5
  # SPDX-License-Identifier: EUPL-1.2
6
6
 
7
7
  import contextlib
8
- from collections.abc import Callable, Iterator
8
+ from collections.abc import Callable, Generator
9
9
  from concurrent.futures import Future
10
10
 
11
11
  import trio
@@ -100,7 +100,7 @@ class TrioEventLoop(EventLoop):
100
100
  raise exc
101
101
 
102
102
  @contextlib.contextmanager
103
- def wrap_cancelled(self) -> Iterator[None]:
103
+ def wrap_cancelled(self) -> Generator[None]:
104
104
  try:
105
105
  yield
106
106
  except Cancelled: