modal 0.73.10__py3-none-any.whl → 0.73.12__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.
modal/_functions.py CHANGED
@@ -65,7 +65,7 @@ from .exception import (
65
65
  )
66
66
  from .gpu import GPU_T, parse_gpu_config
67
67
  from .image import _Image
68
- from .mount import _get_client_mount, _Mount, get_auto_mounts
68
+ from .mount import _get_client_mount, _Mount, get_sys_modules_mounts
69
69
  from .network_file_system import _NetworkFileSystem, network_file_system_mount_protos
70
70
  from .output import _get_output_manager
71
71
  from .parallel_map import (
@@ -436,7 +436,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
436
436
  return fun
437
437
 
438
438
  @staticmethod
439
- def from_args(
439
+ def from_local(
440
440
  info: FunctionInfo,
441
441
  app,
442
442
  image: _Image,
@@ -504,18 +504,41 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
504
504
  if include_source_mode != IncludeSourceMode.INCLUDE_NOTHING:
505
505
  entrypoint_mounts = info.get_entrypoint_mount()
506
506
  else:
507
- entrypoint_mounts = []
507
+ entrypoint_mounts = {}
508
508
 
509
509
  all_mounts = [
510
510
  _get_client_mount(),
511
511
  *explicit_mounts,
512
- *entrypoint_mounts,
512
+ *entrypoint_mounts.values(),
513
513
  ]
514
514
 
515
515
  if include_source_mode is IncludeSourceMode.INCLUDE_FIRST_PARTY:
516
- # TODO(elias): if using INCLUDE_FIRST_PARTY *and* mounts are added that haven't already been
517
- # added to the image via add_local_python_source
518
- all_mounts += get_auto_mounts()
516
+ auto_mounts = get_sys_modules_mounts()
517
+ # don't need to add entrypoint modules to automounts:
518
+ for entrypoint_module in entrypoint_mounts:
519
+ auto_mounts.pop(entrypoint_module, None)
520
+
521
+ warn_missing_modules = set(auto_mounts.keys()) - image._added_python_source_set
522
+
523
+ if warn_missing_modules:
524
+ python_stringified_modules = ", ".join(f'"{mod}"' for mod in sorted(warn_missing_modules))
525
+ deprecation_warning(
526
+ (2025, 2, 3),
527
+ (
528
+ 'Modal will stop implicitly adding local Python modules to the Image ("automounting") in a '
529
+ "future update. The following modules need to be explicitly added for future "
530
+ "compatibility:\n"
531
+ )
532
+ + "\n".join(sorted([f"* {m}" for m in warn_missing_modules]))
533
+ + "\n\n"
534
+ + (
535
+ "e.g.:\n"
536
+ f"image_with_source = my_image.add_local_python_source({python_stringified_modules})\n\n"
537
+ )
538
+ + "For more information, see https://modal.com/docs/guide/modal-1-0-migration",
539
+ pending=True,
540
+ )
541
+ all_mounts += auto_mounts.values()
519
542
  else:
520
543
  # skip any mount introspection/logic inside containers, since the function
521
544
  # should already be hydrated
@@ -564,7 +587,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
564
587
  for k, pf in build_functions:
565
588
  build_function = pf.raw_f
566
589
  snapshot_info = FunctionInfo(build_function, user_cls=info.user_cls)
567
- snapshot_function = _Function.from_args(
590
+ snapshot_function = _Function.from_local(
568
591
  snapshot_info,
569
592
  app=None,
570
593
  image=image,
@@ -36,15 +36,12 @@ def toggle():
36
36
  logger.debug(f"Toggling CUDA checkpoint state for PID {pid}")
37
37
 
38
38
  try:
39
- cuda_checkpoint_lock_timeout_ms = 5 * 1000
40
39
  subprocess.run(
41
40
  [
42
41
  CUDA_CHECKPOINT_PATH,
43
42
  "--toggle",
44
43
  "--pid",
45
44
  str(pid),
46
- "--timeout",
47
- str(cuda_checkpoint_lock_timeout_ms),
48
45
  ],
49
46
  check=True,
50
47
  capture_output=True,
@@ -68,7 +65,6 @@ def get_state() -> CudaCheckpointState:
68
65
 
69
66
  # Parse output to get state
70
67
  state_str = result.stdout.strip().lower()
71
- logger.debug(f"Raw state output: {state_str}")
72
68
  return CudaCheckpointState(state_str)
73
69
 
74
70
  except subprocess.CalledProcessError as e:
@@ -86,6 +82,7 @@ def wait_for_state(target_state: CudaCheckpointState, timeout_secs: float = 5.0)
86
82
 
87
83
  if current_state == target_state:
88
84
  logger.debug(f"Target state {target_state.value} reached")
85
+ break
89
86
 
90
87
  if current_state == CudaCheckpointState.FAILED:
91
88
  raise CudaCheckpointException(f"CUDA process state is {current_state}")
@@ -308,7 +308,7 @@ class FunctionInfo:
308
308
  format=api_pb2.ClassParameterInfo.PARAM_SERIALIZATION_FORMAT_PROTO, schema=modal_parameters
309
309
  )
310
310
 
311
- def get_entrypoint_mount(self) -> list[_Mount]:
311
+ def get_entrypoint_mount(self) -> dict[str, _Mount]:
312
312
  """
313
313
  Includes:
314
314
  * Implicit mount of the function itself (the module or package that the function is part of)
@@ -322,7 +322,7 @@ class FunctionInfo:
322
322
  """
323
323
  if self.is_serialized():
324
324
  # Don't auto-mount anything for serialized functions (including notebooks)
325
- return []
325
+ return {}
326
326
 
327
327
  # make sure the function's own entrypoint is included:
328
328
  if self._type == FunctionInfoType.PACKAGE:
@@ -331,21 +331,23 @@ class FunctionInfo:
331
331
  # includes non-.py files, since we'll want to migrate to .py-only
332
332
  # soon to get it consistent with the `add_local_python_source()`
333
333
  # defaults.
334
- return [_Mount._from_local_python_packages(top_level_package)]
334
+ return {top_level_package: _Mount._from_local_python_packages(top_level_package)}
335
335
  elif self._type == FunctionInfoType.FILE:
336
- remote_path = ROOT_DIR / Path(self._file).name
336
+ # TODO: inspect if this file is already included as part of
337
+ # a package mount, and skip it + reference that package
338
+ # instead if that's the case. This avoids possible module
339
+ # duplication bugs
340
+ module_file = Path(self._file)
341
+ container_module_name = module_file.stem
342
+ remote_path = ROOT_DIR / module_file.name
337
343
  if not _is_modal_path(remote_path):
338
- # TODO: inspect if this file is already included as part of
339
- # a package mount, and skip it + reference that package
340
- # instead if that's the case. This avoids possible module
341
- # duplication bugs
342
- return [
343
- _Mount._from_local_file(
344
+ return {
345
+ container_module_name: _Mount._from_local_file(
344
346
  self._file,
345
347
  remote_path=remote_path,
346
348
  )
347
- ]
348
- return [] # this should never be reached...
349
+ }
350
+ return {} # this should never be reached...
349
351
 
350
352
  def get_tag(self):
351
353
  return self.function_name
modal/app.py CHANGED
@@ -725,7 +725,7 @@ class _App:
725
725
  raise InvalidError("`region` and `_experimental_scheduler_placement` cannot be used together")
726
726
  scheduler_placement = SchedulerPlacement(region=region)
727
727
 
728
- function = _Function.from_args(
728
+ function = _Function.from_local(
729
729
  info,
730
730
  app=self,
731
731
  image=image,
@@ -862,7 +862,7 @@ class _App:
862
862
 
863
863
  info = FunctionInfo(None, serialized=serialized, user_cls=user_cls)
864
864
 
865
- cls_func = _Function.from_args(
865
+ cls_func = _Function.from_local(
866
866
  info,
867
867
  app=self,
868
868
  image=image or self._get_default_image(),
modal/client.pyi CHANGED
@@ -27,7 +27,7 @@ class _Client:
27
27
  _snapshotted: bool
28
28
 
29
29
  def __init__(
30
- self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.73.10"
30
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.73.12"
31
31
  ): ...
32
32
  def is_closed(self) -> bool: ...
33
33
  @property
@@ -85,7 +85,7 @@ class Client:
85
85
  _snapshotted: bool
86
86
 
87
87
  def __init__(
88
- self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.73.10"
88
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.73.12"
89
89
  ): ...
90
90
  def is_closed(self) -> bool: ...
91
91
  @property
modal/functions.pyi CHANGED
@@ -57,7 +57,7 @@ class Function(
57
57
  def __init__(self, *args, **kwargs): ...
58
58
  def _bind_method(self, user_cls, method_name: str, partial_function: modal.partial_function.PartialFunction): ...
59
59
  @staticmethod
60
- def from_args(
60
+ def from_local(
61
61
  info: modal._utils.function_utils.FunctionInfo,
62
62
  app,
63
63
  image: modal.image.Image,
@@ -200,11 +200,11 @@ class Function(
200
200
 
201
201
  _call_generator_nowait: ___call_generator_nowait_spec[typing_extensions.Self]
202
202
 
203
- class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
203
+ class __remote_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
204
204
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER: ...
205
205
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER: ...
206
206
 
207
- remote: __remote_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
207
+ remote: __remote_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
208
208
 
209
209
  class __remote_gen_spec(typing_extensions.Protocol[SUPERSELF]):
210
210
  def __call__(self, *args, **kwargs) -> typing.Generator[typing.Any, None, None]: ...
@@ -219,19 +219,19 @@ class Function(
219
219
  self, *args: modal._functions.P.args, **kwargs: modal._functions.P.kwargs
220
220
  ) -> modal._functions.OriginalReturnType: ...
221
221
 
222
- class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
222
+ class ___experimental_spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
223
223
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
224
224
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
225
225
 
226
226
  _experimental_spawn: ___experimental_spawn_spec[
227
- modal._functions.ReturnType, modal._functions.P, typing_extensions.Self
227
+ modal._functions.P, modal._functions.ReturnType, typing_extensions.Self
228
228
  ]
229
229
 
230
- class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
230
+ class __spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
231
231
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
232
232
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
233
233
 
234
- spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
234
+ spawn: __spawn_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
235
235
 
236
236
  def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]: ...
237
237
 
modal/image.py CHANGED
@@ -402,12 +402,14 @@ class _Image(_Object, type_prefix="im"):
402
402
  _deferred_mounts: Sequence[
403
403
  _Mount
404
404
  ] # added as mounts on any container referencing the Image, see `def _mount_layers`
405
+ _added_python_source_set: frozenset[str] # used to warn about missing mounts during auto-mount deprecation
405
406
  _metadata: Optional[api_pb2.ImageMetadata] = None # set on hydration, private for now
406
407
 
407
408
  def _initialize_from_empty(self):
408
409
  self.inside_exceptions = []
409
410
  self._serve_mounts = frozenset()
410
411
  self._deferred_mounts = ()
412
+ self._added_python_source_set = frozenset()
411
413
  self.force_build = False
412
414
 
413
415
  def _initialize_from_other(self, other: "_Image"):
@@ -416,6 +418,7 @@ class _Image(_Object, type_prefix="im"):
416
418
  self.force_build = other.force_build
417
419
  self._serve_mounts = other._serve_mounts
418
420
  self._deferred_mounts = other._deferred_mounts
421
+ self._added_python_source_set = other._added_python_source_set
419
422
 
420
423
  def _hydrate_metadata(self, metadata: Optional[Message]):
421
424
  env_image_id = config.get("image_id") # set as an env var in containers
@@ -440,7 +443,9 @@ class _Image(_Object, type_prefix="im"):
440
443
  self2._deferred_mounts = tuple(base_image._deferred_mounts) + (mount,)
441
444
  self2._serve_mounts = base_image._serve_mounts | ({mount} if mount.is_local() else set())
442
445
 
443
- return _Image._from_loader(_load, "Image(local files)", deps=lambda: [base_image, mount])
446
+ img = _Image._from_loader(_load, "Image(local files)", deps=lambda: [base_image, mount])
447
+ img._added_python_source_set = base_image._added_python_source_set
448
+ return img
444
449
 
445
450
  @property
446
451
  def _mount_layers(self) -> typing.Sequence[_Mount]:
@@ -659,6 +664,9 @@ class _Image(_Object, type_prefix="im"):
659
664
  rep = f"Image({dockerfile_function})"
660
665
  obj = _Image._from_loader(_load, rep, deps=_deps)
661
666
  obj.force_build = force_build
667
+ obj._added_python_source_set = frozenset.union(
668
+ frozenset(), *(base._added_python_source_set for base in base_images.values())
669
+ )
662
670
  return obj
663
671
 
664
672
  def copy_mount(self, mount: _Mount, remote_path: Union[str, Path] = ".") -> "_Image":
@@ -843,7 +851,9 @@ class _Image(_Object, type_prefix="im"):
843
851
  ```
844
852
  """
845
853
  mount = _Mount._from_local_python_packages(*modules, ignore=ignore)
846
- return self._add_mount_layer_or_copy(mount, copy=copy)
854
+ img = self._add_mount_layer_or_copy(mount, copy=copy)
855
+ img._added_python_source_set |= set(modules)
856
+ return img
847
857
 
848
858
  def copy_local_dir(
849
859
  self,
@@ -1954,7 +1964,7 @@ class _Image(_Object, type_prefix="im"):
1954
1964
 
1955
1965
  info = FunctionInfo(raw_f)
1956
1966
 
1957
- function = _Function.from_args(
1967
+ function = _Function.from_local(
1958
1968
  info,
1959
1969
  app=None,
1960
1970
  image=self, # type: ignore[reportArgumentType] # TODO: probably conflict with type stub?
modal/image.pyi CHANGED
@@ -85,6 +85,7 @@ class _Image(modal._object._Object):
85
85
  inside_exceptions: list[Exception]
86
86
  _serve_mounts: frozenset[modal.mount._Mount]
87
87
  _deferred_mounts: collections.abc.Sequence[modal.mount._Mount]
88
+ _added_python_source_set: frozenset[str]
88
89
  _metadata: typing.Optional[modal_proto.api_pb2.ImageMetadata]
89
90
 
90
91
  def _initialize_from_empty(self): ...
@@ -355,6 +356,7 @@ class Image(modal.object.Object):
355
356
  inside_exceptions: list[Exception]
356
357
  _serve_mounts: frozenset[modal.mount.Mount]
357
358
  _deferred_mounts: collections.abc.Sequence[modal.mount.Mount]
359
+ _added_python_source_set: frozenset[str]
358
360
  _metadata: typing.Optional[modal_proto.api_pb2.ImageMetadata]
359
361
 
360
362
  def __init__(self, *args, **kwargs): ...
modal/mount.py CHANGED
@@ -821,14 +821,14 @@ def _is_modal_path(remote_path: PurePosixPath):
821
821
  return False
822
822
 
823
823
 
824
- def get_auto_mounts() -> list[_Mount]:
824
+ def get_sys_modules_mounts() -> dict[str, _Mount]:
825
825
  """mdmd:hidden
826
826
 
827
827
  Auto-mount local modules that have been imported in global scope.
828
828
  This may or may not include the "entrypoint" of the function as well, depending on how modal is invoked
829
829
  Note: sys.modules may change during the iteration
830
830
  """
831
- auto_mounts = []
831
+ auto_mounts = {}
832
832
  top_level_modules = []
833
833
  skip_prefixes = set()
834
834
  for name, module in sorted(sys.modules.items(), key=lambda kv: len(kv[0])):
@@ -858,6 +858,6 @@ def get_auto_mounts() -> list[_Mount]:
858
858
  # skip any module that has paths in SYS_PREFIXES, or would overwrite the modal Package in the container
859
859
  break
860
860
  else:
861
- auto_mounts.append(potential_mount)
861
+ auto_mounts[module_name] = potential_mount
862
862
 
863
863
  return auto_mounts
modal/mount.pyi CHANGED
@@ -306,7 +306,7 @@ def _create_client_mount(): ...
306
306
  def create_client_mount(): ...
307
307
  def _get_client_mount(): ...
308
308
  def _is_modal_path(remote_path: pathlib.PurePosixPath): ...
309
- def get_auto_mounts() -> list[_Mount]: ...
309
+ def get_sys_modules_mounts() -> dict[str, _Mount]: ...
310
310
 
311
311
  ROOT_DIR: pathlib.PurePosixPath
312
312
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: modal
3
- Version: 0.73.10
3
+ Version: 0.73.12
4
4
  Summary: Python client library for Modal
5
5
  Author: Modal Labs
6
6
  Author-email: support@modal.com
@@ -3,7 +3,7 @@ modal/__main__.py,sha256=scYhGFqh8OJcVDo-VOxIT6CCwxOgzgflYWMnIZiMRqE,2871
3
3
  modal/_clustered_functions.py,sha256=kTf-9YBXY88NutC1akI-gCbvf01RhMPCw-zoOI_YIUE,2700
4
4
  modal/_clustered_functions.pyi,sha256=vllkegc99A0jrUOWa8mdlSbdp6uz36TsHhGxysAOpaQ,771
5
5
  modal/_container_entrypoint.py,sha256=qahIuJvaMmWG85N5vNS1yuAQ9XZoo1ftzfatkos_q7I,29553
6
- modal/_functions.py,sha256=XTcpMIlGqa3MPSTbnCwvbagTCeIHlnV4g8WlkGF5SOs,70352
6
+ modal/_functions.py,sha256=Yv8hutin0R_0ZRvUZm8kcjVMf4CNAckgMSDpbLSUl0E,71593
7
7
  modal/_ipython.py,sha256=TW1fkVOmZL3YYqdS2YlM1hqpf654Yf8ZyybHdBnlhSw,301
8
8
  modal/_location.py,sha256=S3lSxIU3h9HkWpkJ3Pwo0pqjIOSB1fjeSgUsY3x7eec,1202
9
9
  modal/_object.py,sha256=ItQcsMNkz9Y3kdTsvfNarbW-paJ2qabDyQ7njaqY0XI,11359
@@ -17,11 +17,11 @@ modal/_traceback.py,sha256=IZQzB3fVlUfMHOSyKUgw0H6qv4yHnpyq-XVCNZKfUdA,5023
17
17
  modal/_tunnel.py,sha256=zTBxBiuH1O22tS1OliAJdIsSmaZS8PlnifS_6S5z-mk,6320
18
18
  modal/_tunnel.pyi,sha256=JmmDYAy9F1FpgJ_hWx0xkom2nTOFQjn4mTPYlU3PFo4,1245
19
19
  modal/_watcher.py,sha256=K6LYnlmSGQB4tWWI9JADv-tvSvQ1j522FwT71B51CX8,3584
20
- modal/app.py,sha256=wRygVSrWH8iIqhDAAl2Ww_RAkz8MCJZ0Jt9qYZCF6SA,44626
20
+ modal/app.py,sha256=MaWCYgNx8y2GQhmaXQBMKKAAfCYfdxrdYs6zCBoJzwI,44628
21
21
  modal/app.pyi,sha256=lxiuWzE_OLb3WHg-H7Pek9DGBuCUzZ55P594VhJL5LA,26113
22
22
  modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
23
23
  modal/client.py,sha256=8SQawr7P1PNUCq1UmJMUQXG2jIo4Nmdcs311XqrNLRE,15276
24
- modal/client.pyi,sha256=zquF7hra8lDrBysJUafRuLtmDHnUXpEU1nt9wRDDCUs,7593
24
+ modal/client.pyi,sha256=--MgDdVKPggxp3WXcqEGQZrKCma-33TxbGun6l1nnaE,7593
25
25
  modal/cloud_bucket_mount.py,sha256=YOe9nnvSr4ZbeCn587d7_VhE9IioZYRvF9VYQTQux08,5914
26
26
  modal/cloud_bucket_mount.pyi,sha256=30T3K1a89l6wzmEJ_J9iWv9SknoGqaZDx59Xs-ZQcmk,1607
27
27
  modal/cls.py,sha256=kNnZrBYVXOhgEXU0rDWk2Hr-bQRrsZkMKDgC-TD_6Bs,31063
@@ -40,14 +40,14 @@ modal/file_io.py,sha256=lcMs_E9Xfm0YX1t9U2wNIBPnqHRxmImqjLW1GHqVmyg,20945
40
40
  modal/file_io.pyi,sha256=NTRft1tbPSWf9TlWVeZmTlgB5AZ_Zhu2srWIrWr7brk,9445
41
41
  modal/file_pattern_matcher.py,sha256=1cZ4V2wSLiaXqAqStETSwp3bzDD6QZOt6pmmjk3Okz4,6505
42
42
  modal/functions.py,sha256=kcNHvqeGBxPI7Cgd57NIBBghkfbeFJzXO44WW0jSmao,325
43
- modal/functions.pyi,sha256=mtngzj8VlzMOQATe6muBN5oH_Gw9zGKxMKZ56Z-41kU,14288
43
+ modal/functions.pyi,sha256=avRIY0KOFky6tDRI5_SvnLXz7PUnG2H0hQA385cRtb0,14289
44
44
  modal/gpu.py,sha256=2qZMNnoMrjU-5Bu7fx68pANUAKTtZq0EWEEeBA9OUVQ,7426
45
- modal/image.py,sha256=Vjsi7wS9dEcoj-7m7_LmvbK5iqEuFz-SHKl2K-qWcew,90952
46
- modal/image.pyi,sha256=A5mW2dBguEhmRo815Ax1rBIMXTCriu7PqLMHoUPsez8,26372
45
+ modal/image.py,sha256=ekE2693foy30Xi1LM3swKZPW6HuaACj-OBvfspVSyIE,91509
46
+ modal/image.pyi,sha256=kdJzy1eaxNPZeCpE0TMYYLhJ6UWmkfRDeb_vzngJUoQ,26462
47
47
  modal/io_streams.py,sha256=QkQiizKRzd5bnbKQsap31LJgBYlAnj4-XkV_50xPYX0,15079
48
48
  modal/io_streams.pyi,sha256=bJ7ZLmSmJ0nKoa6r4FJpbqvzdUVa0lEe0Fa-MMpMezU,5071
49
- modal/mount.py,sha256=oXjSr0p666oBVcYBTCvAB4C6BZ4ZTXHqGtHPOB1yu-Y,32137
50
- modal/mount.pyi,sha256=dvdr4joSpW7oKnKyg9eDD0obFfekwZtW65j4NEomivQ,12523
49
+ modal/mount.py,sha256=aUa_KTsUzpbRso5XfVw2UuKl9j1KdWEIpNCl9pF1_YI,32156
50
+ modal/mount.pyi,sha256=CmHa7zKSxHA_7-vMQLnGfw_ZXvAvHlafvUEVJcQ1LQA,12535
51
51
  modal/network_file_system.py,sha256=WXdyL7du_fvjvuG6hSAREyJ83sSEP2xSLAIAhBsisdI,14869
52
52
  modal/network_file_system.pyi,sha256=4N3eqMbTSlqmS8VV_aJK-uvrgJC8xnf_YtW5FHfRfc8,8156
53
53
  modal/object.py,sha256=bTeskuY8JFrESjU4_UL_nTwYlBQdOLmVaOX3X6EMxsg,164
@@ -85,7 +85,7 @@ modal/_runtime/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
85
85
  modal/_runtime/asgi.py,sha256=c4hmaMW1pLo-cm7ouriJjieuFm4ZF6D2LMy0638sfOs,22139
86
86
  modal/_runtime/container_io_manager.py,sha256=L6qv-Mo3mN3ttR5GX-G36cUhH_oz8wdP5WG0HT5FFzg,44619
87
87
  modal/_runtime/execution_context.py,sha256=E6ofm6j1POXGPxS841X3V7JU6NheVb8OkQc7JpLq4Kg,2712
88
- modal/_runtime/gpu_memory_snapshot.py,sha256=vV6igsqN9CxOoH91kUkuaZQ32QfX5wdoXIS-6MIYX2Y,3315
88
+ modal/_runtime/gpu_memory_snapshot.py,sha256=tA3m1d1cwnmHpvpCeN_WijDd6n8byn7LWlpicbIxiOI,3144
89
89
  modal/_runtime/telemetry.py,sha256=T1RoAGyjBDr1swiM6pPsGRSITm7LI5FDK18oNXxY08U,5163
90
90
  modal/_runtime/user_code_imports.py,sha256=zl_Mq9dsrVF62x3w-iNK1YAhZKYAXeFaGpd4G7AySTc,14746
91
91
  modal/_utils/__init__.py,sha256=waLjl5c6IPDhSsdWAm9Bji4e2PVxamYABKAze6CHVXY,28
@@ -95,7 +95,7 @@ modal/_utils/blob_utils.py,sha256=N66LtZI8PpCkZ7maA7GLW5CAmYUoNJdG-GjaAUR4_NQ,14
95
95
  modal/_utils/bytes_io_segment_payload.py,sha256=uunxVJS4PE1LojF_UpURMzVK9GuvmYWRqQo_bxEj5TU,3385
96
96
  modal/_utils/deprecation.py,sha256=dycySRBxyZf3ITzEqPNM6MxXTk9-0VVLA8oCPQ5j_Os,3426
97
97
  modal/_utils/docker_utils.py,sha256=h1uETghR40mp_y3fSWuZAfbIASH1HMzuphJHghAL6DU,3722
98
- modal/_utils/function_utils.py,sha256=ue15TIvHiSSuuLQaGb3gJ5YmxdaFBhfE3Rt5frqIWhM,27185
98
+ modal/_utils/function_utils.py,sha256=fc5RKK59SxV7Vg4JyURVB2CCLUNKQVcBG60_dUxviRM,27307
99
99
  modal/_utils/grpc_testing.py,sha256=H1zHqthv19eGPJz2HKXDyWXWGSqO4BRsxah3L5Xaa8A,8619
100
100
  modal/_utils/grpc_utils.py,sha256=PPB5ay-vXencXNIWPVw5modr3EH7gfq2QPcO5YJ1lMU,7737
101
101
  modal/_utils/hash_utils.py,sha256=zg3J6OGxTFGSFri1qQ12giDz90lWk8bzaxCTUCRtiX4,3034
@@ -171,10 +171,10 @@ modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0y
171
171
  modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
172
172
  modal_version/__init__.py,sha256=wiJQ53c-OMs0Xf1UeXOxQ7FwlV1VzIjnX6o-pRYZ_Pk,470
173
173
  modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
174
- modal_version/_version_generated.py,sha256=bRP1kitLENe-C1R8SFEB0RNXUvVdmynlJRPg8FgsxXA,149
175
- modal-0.73.10.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
176
- modal-0.73.10.dist-info/METADATA,sha256=o2yy7RC_d68S0vZZyIem-3gJG0H7EDGGXtmHHcPzmEE,2330
177
- modal-0.73.10.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
178
- modal-0.73.10.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
179
- modal-0.73.10.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
180
- modal-0.73.10.dist-info/RECORD,,
174
+ modal_version/_version_generated.py,sha256=hpq9G9bj1lIN9FVnX1pPe-0C2iksk3gJ0Nb9YGUnxUc,149
175
+ modal-0.73.12.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
176
+ modal-0.73.12.dist-info/METADATA,sha256=WZ-Sz2y3pR6fU6vtUpEuaZK0XvXsSK-sQgpuFJz6h-4,2330
177
+ modal-0.73.12.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
178
+ modal-0.73.12.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
179
+ modal-0.73.12.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
180
+ modal-0.73.12.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  # Copyright Modal Labs 2025
2
2
 
3
3
  # Note: Reset this value to -1 whenever you make a minor `0.X` release of the client.
4
- build_number = 10 # git: 6951dc1
4
+ build_number = 12 # git: bcf8da8