modAL 1.2.3.dev2__py3-none-any.whl → 1.2.3.dev3__py3-none-any.whl

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.
@@ -1,12 +1,14 @@
1
1
  # Copyright Modal Labs 2022
2
2
  import asyncio
3
3
  import concurrent.futures
4
+ import contextlib
4
5
  import functools
5
6
  import inspect
6
7
  import itertools
7
8
  import sys
8
9
  import time
9
10
  import typing
11
+ import warnings
10
12
  from collections.abc import AsyncGenerator, AsyncIterable, Awaitable, Iterable, Iterator
11
13
  from contextlib import asynccontextmanager
12
14
  from dataclasses import dataclass
@@ -134,7 +136,8 @@ class TaskContext:
134
136
  _loops: set[asyncio.Task]
135
137
 
136
138
  def __init__(self, grace: Optional[float] = None):
137
- self._grace = grace
139
+ self._grace = grace # grace is the time we want for tasks to finish before cancelling them
140
+ self._cancellation_grace: float = 1.0 # extra graceperiod for the cancellation itself to "bubble up"
138
141
  self._loops = set()
139
142
 
140
143
  async def start(self):
@@ -166,22 +169,29 @@ class TaskContext:
166
169
  # still needs to be handled
167
170
  # (https://stackoverflow.com/a/63356323/2475114)
168
171
  if gather_future:
169
- try:
172
+ with contextlib.suppress(asyncio.CancelledError):
170
173
  await gather_future
171
- except asyncio.CancelledError:
172
- pass
173
174
 
175
+ cancelled_tasks: list[asyncio.Task] = []
174
176
  for task in self._tasks:
175
177
  if task.done() and not task.cancelled():
176
178
  # Raise any exceptions if they happened.
177
179
  # Only tasks without a done_callback will still be present in self._tasks
178
180
  task.result()
179
181
 
180
- if task.done() or task in self._loops: # Note: Legacy code, we can probably cancel loops.
182
+ if task.done():
181
183
  continue
182
184
 
183
185
  # Cancel any remaining unfinished tasks.
184
186
  task.cancel()
187
+ cancelled_tasks.append(task)
188
+
189
+ cancellation_gather = asyncio.gather(*cancelled_tasks, return_exceptions=True)
190
+ try:
191
+ await asyncio.wait_for(cancellation_gather, timeout=self._cancellation_grace)
192
+ except asyncio.TimeoutError:
193
+ warnings.warn(f"Internal warning: Tasks did not cancel in a timely manner: {cancelled_tasks}")
194
+
185
195
  await asyncio.sleep(0) # wake up coroutines waiting for cancellations
186
196
 
187
197
  async def __aexit__(self, exc_type, value, tb):
modal/client.pyi CHANGED
@@ -33,7 +33,7 @@ class _Client:
33
33
  server_url: str,
34
34
  client_type: int,
35
35
  credentials: typing.Optional[tuple[str, str]],
36
- version: str = "1.2.3.dev2",
36
+ version: str = "1.2.3.dev3",
37
37
  ):
38
38
  """mdmd:hidden
39
39
  The Modal client object is not intended to be instantiated directly by users.
@@ -164,7 +164,7 @@ class Client:
164
164
  server_url: str,
165
165
  client_type: int,
166
166
  credentials: typing.Optional[tuple[str, str]],
167
- version: str = "1.2.3.dev2",
167
+ version: str = "1.2.3.dev3",
168
168
  ):
169
169
  """mdmd:hidden
170
170
  The Modal client object is not intended to be instantiated directly by users.
modal/functions.pyi CHANGED
@@ -408,7 +408,7 @@ class Function(
408
408
 
409
409
  _call_generator: ___call_generator_spec[typing_extensions.Self]
410
410
 
411
- class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
411
+ class __remote_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
412
412
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER:
413
413
  """Calls the function remotely, executing it with the given arguments and returning the execution's result."""
414
414
  ...
@@ -417,7 +417,7 @@ class Function(
417
417
  """Calls the function remotely, executing it with the given arguments and returning the execution's result."""
418
418
  ...
419
419
 
420
- remote: __remote_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
420
+ remote: __remote_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
421
421
 
422
422
  class __remote_gen_spec(typing_extensions.Protocol[SUPERSELF]):
423
423
  def __call__(self, /, *args, **kwargs) -> typing.Generator[typing.Any, None, None]:
@@ -444,7 +444,7 @@ class Function(
444
444
  """
445
445
  ...
446
446
 
447
- class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
447
+ class ___experimental_spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
448
448
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
449
449
  """[Experimental] Calls the function with the given arguments, without waiting for the results.
450
450
 
@@ -468,7 +468,7 @@ class Function(
468
468
  ...
469
469
 
470
470
  _experimental_spawn: ___experimental_spawn_spec[
471
- modal._functions.ReturnType, modal._functions.P, typing_extensions.Self
471
+ modal._functions.P, modal._functions.ReturnType, typing_extensions.Self
472
472
  ]
473
473
 
474
474
  class ___spawn_map_inner_spec(typing_extensions.Protocol[P_INNER, SUPERSELF]):
@@ -477,7 +477,7 @@ class Function(
477
477
 
478
478
  _spawn_map_inner: ___spawn_map_inner_spec[modal._functions.P, typing_extensions.Self]
479
479
 
480
- class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
480
+ class __spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
481
481
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
482
482
  """Calls the function with the given arguments, without waiting for the results.
483
483
 
@@ -498,7 +498,7 @@ class Function(
498
498
  """
499
499
  ...
500
500
 
501
- spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
501
+ spawn: __spawn_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
502
502
 
503
503
  def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]:
504
504
  """Return the inner Python object wrapped by this Modal Function."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.2.3.dev2
3
+ Version: 1.2.3.dev3
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -26,7 +26,7 @@ modal/app.pyi,sha256=5XnLb07hnNS5mI7MpLTHSFrDVJbh7lYqHOdU0jz7lnk,50683
26
26
  modal/billing.py,sha256=zmQ3bcCJlwa4KD1IA_QgdWpm1pn13c-7qfy79iEauYI,195
27
27
  modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
28
28
  modal/client.py,sha256=tPzihC7R9WtP56k6dyPKi5GLGdLEHdMA6YUj9Ry5G8o,14409
29
- modal/client.pyi,sha256=wxGpphUAXs_j7UzpgZmFmmxpu6xNxAgykEQLGEnR0og,13092
29
+ modal/client.pyi,sha256=hyv3eqEzrYcBxlm1mav9i5230cRJjikzM1x5brVnjVg,13092
30
30
  modal/cloud_bucket_mount.py,sha256=Ff8UFG_Z0HUzcRAAfo1jvDwzaNgiX_btTFOHL7CGyI8,6016
31
31
  modal/cloud_bucket_mount.pyi,sha256=vXusGMOUk9HjCs4lhxteuCK4xLQclPfugGWKo7LECEA,7539
32
32
  modal/cls.py,sha256=TSkc7XOdfYcMkVfXBHZzhqgnQTUYA8RPdv-DySIT9L0,41883
@@ -43,7 +43,7 @@ modal/file_io.py,sha256=Whs3QSl3pQbSoLzSRIIWfK4XyP-kwgyZmWgx3bhJ9u0,20933
43
43
  modal/file_io.pyi,sha256=xtO6Glf_BFwDE7QiQQo24QqcMf_Vv-iz7WojcGVlLBU,15932
44
44
  modal/file_pattern_matcher.py,sha256=A_Kdkej6q7YQyhM_2-BvpFmPqJ0oHb54B6yf9VqvPVE,8116
45
45
  modal/functions.py,sha256=kcNHvqeGBxPI7Cgd57NIBBghkfbeFJzXO44WW0jSmao,325
46
- modal/functions.pyi,sha256=11hKG3vRpHzXUycfz6ozZzJ-EUHLzBUo6la_et3pEPY,38049
46
+ modal/functions.pyi,sha256=l0w4BTq6iYuTgxTKnYiNtuEMhs6pP3ffMxUIc2jPajA,38049
47
47
  modal/gpu.py,sha256=Fe5ORvVPDIstSq1xjmM6OoNgLYFWvogP9r5BgmD3hYg,6769
48
48
  modal/image.py,sha256=wdgZlQqewK8Tj95uGOq7s8YZ8wFxMhKZtzJFTN-RT0Y,108328
49
49
  modal/image.pyi,sha256=grkqK9BfyKDXmJYNme-lGa0O3u7pOU5GifyLOAhG3sc,78202
@@ -95,7 +95,7 @@ modal/_runtime/telemetry.py,sha256=T1RoAGyjBDr1swiM6pPsGRSITm7LI5FDK18oNXxY08U,5
95
95
  modal/_runtime/user_code_imports.py,sha256=1MlOgw810aj0MeDvFPvHBIz-aHd7jUX6dwRfIcM3-KE,16498
96
96
  modal/_utils/__init__.py,sha256=waLjl5c6IPDhSsdWAm9Bji4e2PVxamYABKAze6CHVXY,28
97
97
  modal/_utils/app_utils.py,sha256=88BT4TPLWfYAQwKTHcyzNQRHg8n9B-QE2UyJs96iV-0,108
98
- modal/_utils/async_utils.py,sha256=j2DEgAvYrp89tni0_oS-YotT8npvTlY97DExfiUHG4E,30057
98
+ modal/_utils/async_utils.py,sha256=PnwHfaHcqjLwMnlGC2kn8nqubxpXcSKcy4jHx6477dg,30625
99
99
  modal/_utils/auth_token_manager.py,sha256=QsDokl1c1dN9m6Z9N-Se-8cY3laphByjJtNdRXUTieI,5151
100
100
  modal/_utils/blob_utils.py,sha256=NoAWDqYQsqAjievWmH5mCFSXA6XxQStDt9otT-Nh7_g,22755
101
101
  modal/_utils/bytes_io_segment_payload.py,sha256=vaXPq8b52-x6G2hwE7SrjS58pg_aRm7gV3bn3yjmTzQ,4261
@@ -158,7 +158,7 @@ modal/experimental/__init__.py,sha256=sCwNbBLcR2t-jhrpwtMAPGKt2WNqXBg0xkNZdyB-6C
158
158
  modal/experimental/flash.py,sha256=RKS3X3h4tY_mOLcMzbRs5tNCLPFL01dBAhCZSqCeBgA,26675
159
159
  modal/experimental/flash.pyi,sha256=uwinKAYxpunNNfBj58FP88DXb535Qik4F6tnJKPAIwQ,14696
160
160
  modal/experimental/ipython.py,sha256=TrCfmol9LGsRZMeDoeMPx3Hv3BFqQhYnmD_iH0pqdhk,2904
161
- modal-1.2.3.dev2.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
161
+ modal-1.2.3.dev3.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
162
162
  modal_docs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
163
163
  modal_docs/gen_cli_docs.py,sha256=c1yfBS_x--gL5bs0N4ihMwqwX8l3IBWSkBAKNNIi6bQ,3801
164
164
  modal_docs/gen_reference_docs.py,sha256=d_CQUGQ0rfw28u75I2mov9AlS773z9rG40-yq5o7g2U,6359
@@ -186,10 +186,10 @@ modal_proto/task_command_router_pb2.py,sha256=_pD2ZpU0bNzhwBdzmLoLyLtAtftI_Agxwn
186
186
  modal_proto/task_command_router_pb2.pyi,sha256=EyDgXPLr7alqjXYERV8w_MPuO404x0uCppmSkrfE9IE,14589
187
187
  modal_proto/task_command_router_pb2_grpc.py,sha256=uEQ0HdrCp8v-9bB5yIic9muA8spCShLHY6Bz9cCgOUE,10114
188
188
  modal_proto/task_command_router_pb2_grpc.pyi,sha256=s3Yxsrawdj4nr8vqQqsAxyX6ilWaGbdECy425KKbLIA,3301
189
- modal_version/__init__.py,sha256=FPoBBRsPS4AgaiRSGF8SVokWTqwMef4VYUcnXbbVzBE,120
189
+ modal_version/__init__.py,sha256=Dh5jhBXRE203wEtSyCD_VeLkq72lF0QM8QzZP7mpmac,120
190
190
  modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
191
- modal-1.2.3.dev2.dist-info/METADATA,sha256=3NU8Pr_G7t2YETKOTggQKe_YUL5o0rbeH1jx7YaZGY8,2489
192
- modal-1.2.3.dev2.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
193
- modal-1.2.3.dev2.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
194
- modal-1.2.3.dev2.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
195
- modal-1.2.3.dev2.dist-info/RECORD,,
191
+ modal-1.2.3.dev3.dist-info/METADATA,sha256=Z_lI2pKFtVcGbC_PVK7DgSj-pV2C2imVFJrs6Gk0Zq8,2489
192
+ modal-1.2.3.dev3.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
193
+ modal-1.2.3.dev3.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
194
+ modal-1.2.3.dev3.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
195
+ modal-1.2.3.dev3.dist-info/RECORD,,
modal_version/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  # Copyright Modal Labs 2025
2
2
  """Supplies the current version of the modal client library."""
3
3
 
4
- __version__ = "1.2.3.dev2"
4
+ __version__ = "1.2.3.dev3"