modal 0.72.5__py3-none-any.whl → 0.72.48__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.
Files changed (73) hide show
  1. modal/_container_entrypoint.py +5 -10
  2. modal/_object.py +297 -0
  3. modal/_resolver.py +7 -5
  4. modal/_runtime/container_io_manager.py +0 -11
  5. modal/_runtime/user_code_imports.py +7 -7
  6. modal/_serialization.py +4 -3
  7. modal/_tunnel.py +1 -1
  8. modal/app.py +14 -61
  9. modal/app.pyi +25 -25
  10. modal/cli/app.py +3 -2
  11. modal/cli/container.py +1 -1
  12. modal/cli/import_refs.py +185 -113
  13. modal/cli/launch.py +10 -5
  14. modal/cli/programs/run_jupyter.py +2 -2
  15. modal/cli/programs/vscode.py +3 -3
  16. modal/cli/run.py +134 -68
  17. modal/client.py +1 -0
  18. modal/client.pyi +18 -14
  19. modal/cloud_bucket_mount.py +4 -0
  20. modal/cloud_bucket_mount.pyi +4 -0
  21. modal/cls.py +33 -5
  22. modal/cls.pyi +20 -5
  23. modal/container_process.pyi +8 -6
  24. modal/dict.py +1 -1
  25. modal/dict.pyi +32 -29
  26. modal/environments.py +1 -1
  27. modal/environments.pyi +2 -1
  28. modal/experimental.py +47 -11
  29. modal/experimental.pyi +29 -0
  30. modal/file_io.pyi +30 -28
  31. modal/file_pattern_matcher.py +3 -4
  32. modal/functions.py +31 -23
  33. modal/functions.pyi +57 -50
  34. modal/gpu.py +19 -26
  35. modal/image.py +47 -19
  36. modal/image.pyi +28 -21
  37. modal/io_streams.pyi +14 -12
  38. modal/mount.py +14 -5
  39. modal/mount.pyi +28 -25
  40. modal/network_file_system.py +7 -7
  41. modal/network_file_system.pyi +27 -24
  42. modal/object.py +2 -265
  43. modal/object.pyi +46 -130
  44. modal/parallel_map.py +2 -2
  45. modal/parallel_map.pyi +10 -7
  46. modal/partial_function.py +22 -3
  47. modal/partial_function.pyi +45 -27
  48. modal/proxy.py +1 -1
  49. modal/proxy.pyi +2 -1
  50. modal/queue.py +1 -1
  51. modal/queue.pyi +26 -23
  52. modal/runner.py +14 -3
  53. modal/sandbox.py +11 -7
  54. modal/sandbox.pyi +30 -27
  55. modal/secret.py +1 -1
  56. modal/secret.pyi +2 -1
  57. modal/token_flow.pyi +6 -4
  58. modal/volume.py +1 -1
  59. modal/volume.pyi +36 -33
  60. {modal-0.72.5.dist-info → modal-0.72.48.dist-info}/METADATA +2 -2
  61. {modal-0.72.5.dist-info → modal-0.72.48.dist-info}/RECORD +73 -71
  62. modal_proto/api.proto +151 -4
  63. modal_proto/api_grpc.py +113 -0
  64. modal_proto/api_pb2.py +998 -795
  65. modal_proto/api_pb2.pyi +430 -11
  66. modal_proto/api_pb2_grpc.py +233 -1
  67. modal_proto/api_pb2_grpc.pyi +75 -3
  68. modal_proto/modal_api_grpc.py +7 -0
  69. modal_version/_version_generated.py +1 -1
  70. {modal-0.72.5.dist-info → modal-0.72.48.dist-info}/LICENSE +0 -0
  71. {modal-0.72.5.dist-info → modal-0.72.48.dist-info}/WHEEL +0 -0
  72. {modal-0.72.5.dist-info → modal-0.72.48.dist-info}/entry_points.txt +0 -0
  73. {modal-0.72.5.dist-info → modal-0.72.48.dist-info}/top_level.txt +0 -0
modal/image.pyi CHANGED
@@ -1,5 +1,6 @@
1
1
  import collections.abc
2
2
  import google.protobuf.message
3
+ import modal._object
3
4
  import modal.client
4
5
  import modal.cloud_bucket_mount
5
6
  import modal.functions
@@ -52,11 +53,11 @@ def _get_image_builder_version(
52
53
  ) -> typing.Literal["2023.12", "2024.04", "2024.10"]: ...
53
54
  def _create_context_mount(
54
55
  docker_commands: collections.abc.Sequence[str],
55
- ignore_fn: typing.Callable[[pathlib.Path], bool],
56
+ ignore_fn: collections.abc.Callable[[pathlib.Path], bool],
56
57
  context_dir: pathlib.Path,
57
58
  ) -> typing.Optional[modal.mount._Mount]: ...
58
59
  def _create_context_mount_function(
59
- ignore: typing.Union[collections.abc.Sequence[str], typing.Callable[[pathlib.Path], bool]],
60
+ ignore: typing.Union[collections.abc.Sequence[str], collections.abc.Callable[[pathlib.Path], bool]],
60
61
  dockerfile_cmds: list[str] = [],
61
62
  dockerfile_path: typing.Optional[pathlib.Path] = None,
62
63
  context_mount: typing.Optional[modal.mount._Mount] = None,
@@ -78,7 +79,7 @@ async def _image_await_build_result(
78
79
  image_id: str, client: modal.client._Client
79
80
  ) -> modal_proto.api_pb2.ImageJoinStreamingResponse: ...
80
81
 
81
- class _Image(modal.object._Object):
82
+ class _Image(modal._object._Object):
82
83
  force_build: bool
83
84
  inside_exceptions: list[Exception]
84
85
  _serve_mounts: frozenset[modal.mount._Mount]
@@ -97,14 +98,16 @@ class _Image(modal.object._Object):
97
98
  *,
98
99
  base_images: typing.Optional[dict[str, _Image]] = None,
99
100
  dockerfile_function: typing.Optional[
100
- typing.Callable[[typing.Literal["2023.12", "2024.04", "2024.10"]], DockerfileSpec]
101
+ collections.abc.Callable[[typing.Literal["2023.12", "2024.04", "2024.10"]], DockerfileSpec]
101
102
  ] = None,
102
103
  secrets: typing.Optional[collections.abc.Sequence[modal.secret._Secret]] = None,
103
104
  gpu_config: typing.Optional[modal_proto.api_pb2.GPUConfig] = None,
104
105
  build_function: typing.Optional[modal.functions._Function] = None,
105
106
  build_function_input: typing.Optional[modal_proto.api_pb2.FunctionInput] = None,
106
107
  image_registry_config: typing.Optional[_ImageRegistryConfig] = None,
107
- context_mount_function: typing.Optional[typing.Callable[[], typing.Optional[modal.mount._Mount]]] = None,
108
+ context_mount_function: typing.Optional[
109
+ collections.abc.Callable[[], typing.Optional[modal.mount._Mount]]
110
+ ] = None,
108
111
  force_build: bool = False,
109
112
  _namespace: int = 1,
110
113
  _do_assert_no_mount_layers: bool = True,
@@ -119,7 +122,7 @@ class _Image(modal.object._Object):
119
122
  remote_path: str,
120
123
  *,
121
124
  copy: bool = False,
122
- ignore: typing.Union[collections.abc.Sequence[str], typing.Callable[[pathlib.Path], bool]] = [],
125
+ ignore: typing.Union[collections.abc.Sequence[str], collections.abc.Callable[[pathlib.Path], bool]] = [],
123
126
  ) -> _Image: ...
124
127
  def copy_local_file(
125
128
  self, local_path: typing.Union[str, pathlib.Path], remote_path: typing.Union[str, pathlib.Path] = "./"
@@ -129,14 +132,14 @@ class _Image(modal.object._Object):
129
132
  *module_names: str,
130
133
  copy: bool = False,
131
134
  ignore: typing.Union[
132
- collections.abc.Sequence[str], typing.Callable[[pathlib.Path], bool]
135
+ collections.abc.Sequence[str], collections.abc.Callable[[pathlib.Path], bool]
133
136
  ] = modal.file_pattern_matcher.NON_PYTHON_FILES,
134
137
  ) -> _Image: ...
135
138
  def copy_local_dir(
136
139
  self,
137
140
  local_path: typing.Union[str, pathlib.Path],
138
141
  remote_path: typing.Union[str, pathlib.Path] = ".",
139
- ignore: typing.Union[collections.abc.Sequence[str], typing.Callable[[pathlib.Path], bool]] = [],
142
+ ignore: typing.Union[collections.abc.Sequence[str], collections.abc.Callable[[pathlib.Path], bool]] = [],
140
143
  ) -> _Image: ...
141
144
  @staticmethod
142
145
  async def from_id(image_id: str, client: typing.Optional[modal.client._Client] = None) -> _Image: ...
@@ -215,7 +218,7 @@ class _Image(modal.object._Object):
215
218
  context_mount: typing.Optional[modal.mount._Mount] = None,
216
219
  force_build: bool = False,
217
220
  ignore: typing.Union[
218
- collections.abc.Sequence[str], typing.Callable[[pathlib.Path], bool]
221
+ collections.abc.Sequence[str], collections.abc.Callable[[pathlib.Path], bool]
219
222
  ] = modal.image.AUTO_DOCKERIGNORE,
220
223
  ) -> _Image: ...
221
224
  def entrypoint(self, entrypoint_commands: list[str]) -> _Image: ...
@@ -303,7 +306,7 @@ class _Image(modal.object._Object):
303
306
  gpu: typing.Union[None, bool, str, modal.gpu._GPUConfig] = None,
304
307
  add_python: typing.Optional[str] = None,
305
308
  ignore: typing.Union[
306
- collections.abc.Sequence[str], typing.Callable[[pathlib.Path], bool]
309
+ collections.abc.Sequence[str], collections.abc.Callable[[pathlib.Path], bool]
307
310
  ] = modal.image.AUTO_DOCKERIGNORE,
308
311
  ) -> _Image: ...
309
312
  @staticmethod
@@ -317,7 +320,7 @@ class _Image(modal.object._Object):
317
320
  ) -> _Image: ...
318
321
  def run_function(
319
322
  self,
320
- raw_f: typing.Callable[..., typing.Any],
323
+ raw_f: collections.abc.Callable[..., typing.Any],
321
324
  secrets: collections.abc.Sequence[modal.secret._Secret] = (),
322
325
  gpu: typing.Union[
323
326
  None, bool, str, modal.gpu._GPUConfig, list[typing.Union[None, bool, str, modal.gpu._GPUConfig]]
@@ -344,6 +347,8 @@ class _Image(modal.object._Object):
344
347
  def imports(self): ...
345
348
  def _logs(self) -> typing.AsyncGenerator[str, None]: ...
346
349
 
350
+ SUPERSELF = typing.TypeVar("SUPERSELF", covariant=True)
351
+
347
352
  class Image(modal.object.Object):
348
353
  force_build: bool
349
354
  inside_exceptions: list[Exception]
@@ -364,14 +369,16 @@ class Image(modal.object.Object):
364
369
  *,
365
370
  base_images: typing.Optional[dict[str, Image]] = None,
366
371
  dockerfile_function: typing.Optional[
367
- typing.Callable[[typing.Literal["2023.12", "2024.04", "2024.10"]], DockerfileSpec]
372
+ collections.abc.Callable[[typing.Literal["2023.12", "2024.04", "2024.10"]], DockerfileSpec]
368
373
  ] = None,
369
374
  secrets: typing.Optional[collections.abc.Sequence[modal.secret.Secret]] = None,
370
375
  gpu_config: typing.Optional[modal_proto.api_pb2.GPUConfig] = None,
371
376
  build_function: typing.Optional[modal.functions.Function] = None,
372
377
  build_function_input: typing.Optional[modal_proto.api_pb2.FunctionInput] = None,
373
378
  image_registry_config: typing.Optional[_ImageRegistryConfig] = None,
374
- context_mount_function: typing.Optional[typing.Callable[[], typing.Optional[modal.mount.Mount]]] = None,
379
+ context_mount_function: typing.Optional[
380
+ collections.abc.Callable[[], typing.Optional[modal.mount.Mount]]
381
+ ] = None,
375
382
  force_build: bool = False,
376
383
  _namespace: int = 1,
377
384
  _do_assert_no_mount_layers: bool = True,
@@ -386,7 +393,7 @@ class Image(modal.object.Object):
386
393
  remote_path: str,
387
394
  *,
388
395
  copy: bool = False,
389
- ignore: typing.Union[collections.abc.Sequence[str], typing.Callable[[pathlib.Path], bool]] = [],
396
+ ignore: typing.Union[collections.abc.Sequence[str], collections.abc.Callable[[pathlib.Path], bool]] = [],
390
397
  ) -> Image: ...
391
398
  def copy_local_file(
392
399
  self, local_path: typing.Union[str, pathlib.Path], remote_path: typing.Union[str, pathlib.Path] = "./"
@@ -396,14 +403,14 @@ class Image(modal.object.Object):
396
403
  *module_names: str,
397
404
  copy: bool = False,
398
405
  ignore: typing.Union[
399
- collections.abc.Sequence[str], typing.Callable[[pathlib.Path], bool]
406
+ collections.abc.Sequence[str], collections.abc.Callable[[pathlib.Path], bool]
400
407
  ] = modal.file_pattern_matcher.NON_PYTHON_FILES,
401
408
  ) -> Image: ...
402
409
  def copy_local_dir(
403
410
  self,
404
411
  local_path: typing.Union[str, pathlib.Path],
405
412
  remote_path: typing.Union[str, pathlib.Path] = ".",
406
- ignore: typing.Union[collections.abc.Sequence[str], typing.Callable[[pathlib.Path], bool]] = [],
413
+ ignore: typing.Union[collections.abc.Sequence[str], collections.abc.Callable[[pathlib.Path], bool]] = [],
407
414
  ) -> Image: ...
408
415
 
409
416
  class __from_id_spec(typing_extensions.Protocol):
@@ -487,7 +494,7 @@ class Image(modal.object.Object):
487
494
  context_mount: typing.Optional[modal.mount.Mount] = None,
488
495
  force_build: bool = False,
489
496
  ignore: typing.Union[
490
- collections.abc.Sequence[str], typing.Callable[[pathlib.Path], bool]
497
+ collections.abc.Sequence[str], collections.abc.Callable[[pathlib.Path], bool]
491
498
  ] = modal.image.AUTO_DOCKERIGNORE,
492
499
  ) -> Image: ...
493
500
  def entrypoint(self, entrypoint_commands: list[str]) -> Image: ...
@@ -575,7 +582,7 @@ class Image(modal.object.Object):
575
582
  gpu: typing.Union[None, bool, str, modal.gpu._GPUConfig] = None,
576
583
  add_python: typing.Optional[str] = None,
577
584
  ignore: typing.Union[
578
- collections.abc.Sequence[str], typing.Callable[[pathlib.Path], bool]
585
+ collections.abc.Sequence[str], collections.abc.Callable[[pathlib.Path], bool]
579
586
  ] = modal.image.AUTO_DOCKERIGNORE,
580
587
  ) -> Image: ...
581
588
  @staticmethod
@@ -589,7 +596,7 @@ class Image(modal.object.Object):
589
596
  ) -> Image: ...
590
597
  def run_function(
591
598
  self,
592
- raw_f: typing.Callable[..., typing.Any],
599
+ raw_f: collections.abc.Callable[..., typing.Any],
593
600
  secrets: collections.abc.Sequence[modal.secret.Secret] = (),
594
601
  gpu: typing.Union[
595
602
  None, bool, str, modal.gpu._GPUConfig, list[typing.Union[None, bool, str, modal.gpu._GPUConfig]]
@@ -615,10 +622,10 @@ class Image(modal.object.Object):
615
622
  def workdir(self, path: typing.Union[str, pathlib.PurePosixPath]) -> Image: ...
616
623
  def imports(self): ...
617
624
 
618
- class ___logs_spec(typing_extensions.Protocol):
625
+ class ___logs_spec(typing_extensions.Protocol[SUPERSELF]):
619
626
  def __call__(self) -> typing.Generator[str, None, None]: ...
620
627
  def aio(self) -> typing.AsyncGenerator[str, None]: ...
621
628
 
622
- _logs: ___logs_spec
629
+ _logs: ___logs_spec[typing_extensions.Self]
623
630
 
624
631
  SUPPORTED_PYTHON_SERIES: dict[typing.Literal["2023.12", "2024.04", "2024.10"], list[str]]
modal/io_streams.pyi CHANGED
@@ -50,6 +50,8 @@ class _StreamWriter:
50
50
 
51
51
  T_INNER = typing.TypeVar("T_INNER", covariant=True)
52
52
 
53
+ SUPERSELF = typing.TypeVar("SUPERSELF", covariant=True)
54
+
53
55
  class StreamReader(typing.Generic[T]):
54
56
  _stream: typing.Optional[collections.abc.AsyncGenerator[typing.Optional[bytes], None]]
55
57
 
@@ -66,25 +68,25 @@ class StreamReader(typing.Generic[T]):
66
68
  @property
67
69
  def file_descriptor(self) -> int: ...
68
70
 
69
- class __read_spec(typing_extensions.Protocol[T_INNER]):
71
+ class __read_spec(typing_extensions.Protocol[T_INNER, SUPERSELF]):
70
72
  def __call__(self) -> T_INNER: ...
71
73
  async def aio(self) -> T_INNER: ...
72
74
 
73
- read: __read_spec[T]
75
+ read: __read_spec[T, typing_extensions.Self]
74
76
 
75
- class ___consume_container_process_stream_spec(typing_extensions.Protocol):
77
+ class ___consume_container_process_stream_spec(typing_extensions.Protocol[SUPERSELF]):
76
78
  def __call__(self): ...
77
79
  async def aio(self): ...
78
80
 
79
- _consume_container_process_stream: ___consume_container_process_stream_spec
81
+ _consume_container_process_stream: ___consume_container_process_stream_spec[typing_extensions.Self]
80
82
 
81
- class ___stream_container_process_spec(typing_extensions.Protocol):
83
+ class ___stream_container_process_spec(typing_extensions.Protocol[SUPERSELF]):
82
84
  def __call__(self) -> typing.Generator[tuple[typing.Optional[bytes], str], None, None]: ...
83
85
  def aio(self) -> collections.abc.AsyncGenerator[tuple[typing.Optional[bytes], str], None]: ...
84
86
 
85
- _stream_container_process: ___stream_container_process_spec
87
+ _stream_container_process: ___stream_container_process_spec[typing_extensions.Self]
86
88
 
87
- class ___get_logs_spec(typing_extensions.Protocol):
89
+ class ___get_logs_spec(typing_extensions.Protocol[SUPERSELF]):
88
90
  def __call__(
89
91
  self, skip_empty_messages: bool = True
90
92
  ) -> typing.Generator[typing.Optional[bytes], None, None]: ...
@@ -92,13 +94,13 @@ class StreamReader(typing.Generic[T]):
92
94
  self, skip_empty_messages: bool = True
93
95
  ) -> collections.abc.AsyncGenerator[typing.Optional[bytes], None]: ...
94
96
 
95
- _get_logs: ___get_logs_spec
97
+ _get_logs: ___get_logs_spec[typing_extensions.Self]
96
98
 
97
- class ___get_logs_by_line_spec(typing_extensions.Protocol):
99
+ class ___get_logs_by_line_spec(typing_extensions.Protocol[SUPERSELF]):
98
100
  def __call__(self) -> typing.Generator[typing.Optional[bytes], None, None]: ...
99
101
  def aio(self) -> collections.abc.AsyncGenerator[typing.Optional[bytes], None]: ...
100
102
 
101
- _get_logs_by_line: ___get_logs_by_line_spec
103
+ _get_logs_by_line: ___get_logs_by_line_spec[typing_extensions.Self]
102
104
 
103
105
  def __iter__(self) -> typing.Iterator[T]: ...
104
106
  def __aiter__(self) -> collections.abc.AsyncIterator[T]: ...
@@ -115,8 +117,8 @@ class StreamWriter:
115
117
  def write(self, data: typing.Union[bytes, bytearray, memoryview, str]) -> None: ...
116
118
  def write_eof(self) -> None: ...
117
119
 
118
- class __drain_spec(typing_extensions.Protocol):
120
+ class __drain_spec(typing_extensions.Protocol[SUPERSELF]):
119
121
  def __call__(self) -> None: ...
120
122
  async def aio(self) -> None: ...
121
123
 
122
- drain: __drain_spec
124
+ drain: __drain_spec[typing_extensions.Self]
modal/mount.py CHANGED
@@ -20,6 +20,7 @@ import modal.file_pattern_matcher
20
20
  from modal_proto import api_pb2
21
21
  from modal_version import __version__
22
22
 
23
+ from ._object import _get_environment_name, _Object
23
24
  from ._resolver import Resolver
24
25
  from ._utils.async_utils import aclosing, async_map, synchronize_api
25
26
  from ._utils.blob_utils import FileUploadSpec, blob_upload_file, get_file_upload_spec_from_path
@@ -31,7 +32,6 @@ from .client import _Client
31
32
  from .config import config, logger
32
33
  from .exception import InvalidError, ModuleNotMountable
33
34
  from .file_pattern_matcher import FilePatternMatcher
34
- from .object import _get_environment_name, _Object
35
35
 
36
36
  ROOT_DIR: PurePosixPath = PurePosixPath("/root")
37
37
  MOUNT_PUT_FILE_CLIENT_TIMEOUT = 10 * 60 # 10 min max for transferring files
@@ -258,12 +258,15 @@ class NonLocalMountError(Exception):
258
258
 
259
259
 
260
260
  class _Mount(_Object, type_prefix="mo"):
261
- """Create a mount for a local directory or file that can be attached
261
+ """
262
+ **Deprecated**: Mounts should not be used explicitly anymore, use `Image.add_local_*` commands instead.
263
+
264
+ Create a mount for a local directory or file that can be attached
262
265
  to one or more Modal functions.
263
266
 
264
267
  **Usage**
265
268
 
266
- ```python
269
+ ```python notest
267
270
  import modal
268
271
  import os
269
272
  app = modal.App()
@@ -394,11 +397,13 @@ class _Mount(_Object, type_prefix="mo"):
394
397
  recursive: bool = True,
395
398
  ) -> "_Mount":
396
399
  """
400
+ **Deprecated:** Use image.add_local_dir() instead
401
+
397
402
  Create a `Mount` from a local directory.
398
403
 
399
404
  **Usage**
400
405
 
401
- ```python
406
+ ```python notest
402
407
  assets = modal.Mount.from_local_dir(
403
408
  "~/assets",
404
409
  condition=lambda pth: not ".venv" in pth,
@@ -449,11 +454,13 @@ class _Mount(_Object, type_prefix="mo"):
449
454
  @staticmethod
450
455
  def from_local_file(local_path: Union[str, Path], remote_path: Union[str, PurePosixPath, None] = None) -> "_Mount":
451
456
  """
457
+ **Deprecated**: Use image.add_local_file() instead
458
+
452
459
  Create a `Mount` mounting a single local file.
453
460
 
454
461
  **Usage**
455
462
 
456
- ```python
463
+ ```python notest
457
464
  # Mount the DBT profile in user's home directory into container.
458
465
  dbt_profiles = modal.Mount.from_local_file(
459
466
  local_path="~/profiles.yml",
@@ -611,6 +618,8 @@ class _Mount(_Object, type_prefix="mo"):
611
618
  ignore: Optional[Union[Sequence[str], Callable[[Path], bool]]] = None,
612
619
  ) -> "_Mount":
613
620
  """
621
+ **Deprecated**: Use image.add_local_python_source instead
622
+
614
623
  Returns a `modal.Mount` that makes local modules listed in `module_names` available inside the container.
615
624
  This works by mounting the local path of each module's package to a directory inside the container
616
625
  that's on `PYTHONPATH`.
modal/mount.pyi CHANGED
@@ -1,5 +1,6 @@
1
1
  import collections.abc
2
2
  import google.protobuf.message
3
+ import modal._object
3
4
  import modal._resolver
4
5
  import modal._utils.blob_utils
5
6
  import modal.client
@@ -35,7 +36,7 @@ class _MountFile(_MountEntry):
35
36
  class _MountDir(_MountEntry):
36
37
  local_dir: pathlib.Path
37
38
  remote_path: pathlib.PurePosixPath
38
- ignore: typing.Callable[[pathlib.Path], bool]
39
+ ignore: collections.abc.Callable[[pathlib.Path], bool]
39
40
  recursive: bool
40
41
 
41
42
  def description(self): ...
@@ -46,7 +47,7 @@ class _MountDir(_MountEntry):
46
47
  self,
47
48
  local_dir: pathlib.Path,
48
49
  remote_path: pathlib.PurePosixPath,
49
- ignore: typing.Callable[[pathlib.Path], bool],
50
+ ignore: collections.abc.Callable[[pathlib.Path], bool],
50
51
  recursive: bool,
51
52
  ) -> None: ...
52
53
  def __repr__(self): ...
@@ -58,7 +59,7 @@ def module_mount_ignore_condition(module_base: pathlib.Path): ...
58
59
  class _MountedPythonModule(_MountEntry):
59
60
  module_name: str
60
61
  remote_dir: typing.Union[pathlib.PurePosixPath, str]
61
- ignore: typing.Optional[typing.Callable[[pathlib.Path], bool]]
62
+ ignore: typing.Optional[collections.abc.Callable[[pathlib.Path], bool]]
62
63
 
63
64
  def description(self) -> str: ...
64
65
  def _proxy_entries(self) -> list[_MountEntry]: ...
@@ -69,14 +70,14 @@ class _MountedPythonModule(_MountEntry):
69
70
  self,
70
71
  module_name: str,
71
72
  remote_dir: typing.Union[pathlib.PurePosixPath, str] = "/root",
72
- ignore: typing.Optional[typing.Callable[[pathlib.Path], bool]] = None,
73
+ ignore: typing.Optional[collections.abc.Callable[[pathlib.Path], bool]] = None,
73
74
  ) -> None: ...
74
75
  def __repr__(self): ...
75
76
  def __eq__(self, other): ...
76
77
 
77
78
  class NonLocalMountError(Exception): ...
78
79
 
79
- class _Mount(modal.object._Object):
80
+ class _Mount(modal._object._Object):
80
81
  _entries: typing.Optional[list[_MountEntry]]
81
82
  _deployment_name: typing.Optional[str]
82
83
  _namespace: typing.Optional[int]
@@ -95,14 +96,14 @@ class _Mount(modal.object._Object):
95
96
  def _add_local_dir(
96
97
  local_path: pathlib.Path,
97
98
  remote_path: pathlib.PurePosixPath,
98
- ignore: typing.Callable[[pathlib.Path], bool] = modal.file_pattern_matcher._NOTHING,
99
+ ignore: collections.abc.Callable[[pathlib.Path], bool] = modal.file_pattern_matcher._NOTHING,
99
100
  ): ...
100
101
  def add_local_dir(
101
102
  self,
102
103
  local_path: typing.Union[str, pathlib.Path],
103
104
  *,
104
105
  remote_path: typing.Union[str, pathlib.PurePosixPath, None] = None,
105
- condition: typing.Optional[typing.Callable[[str], bool]] = None,
106
+ condition: typing.Optional[collections.abc.Callable[[str], bool]] = None,
106
107
  recursive: bool = True,
107
108
  ) -> _Mount: ...
108
109
  @staticmethod
@@ -110,7 +111,7 @@ class _Mount(modal.object._Object):
110
111
  local_path: typing.Union[str, pathlib.Path],
111
112
  *,
112
113
  remote_path: typing.Union[str, pathlib.PurePosixPath, None] = None,
113
- condition: typing.Optional[typing.Callable[[str], bool]] = None,
114
+ condition: typing.Optional[collections.abc.Callable[[str], bool]] = None,
114
115
  recursive: bool = True,
115
116
  ) -> _Mount: ...
116
117
  @staticmethod
@@ -118,7 +119,7 @@ class _Mount(modal.object._Object):
118
119
  local_path: typing.Union[str, pathlib.Path],
119
120
  *,
120
121
  remote_path: typing.Union[str, pathlib.PurePosixPath, None] = None,
121
- condition: typing.Optional[typing.Callable[[str], bool]] = None,
122
+ condition: typing.Optional[collections.abc.Callable[[str], bool]] = None,
122
123
  recursive: bool = True,
123
124
  ) -> _Mount: ...
124
125
  def add_local_file(
@@ -147,15 +148,15 @@ class _Mount(modal.object._Object):
147
148
  def from_local_python_packages(
148
149
  *module_names: str,
149
150
  remote_dir: typing.Union[str, pathlib.PurePosixPath] = "/root",
150
- condition: typing.Optional[typing.Callable[[str], bool]] = None,
151
- ignore: typing.Union[typing.Sequence[str], typing.Callable[[pathlib.Path], bool], None] = None,
151
+ condition: typing.Optional[collections.abc.Callable[[str], bool]] = None,
152
+ ignore: typing.Union[typing.Sequence[str], collections.abc.Callable[[pathlib.Path], bool], None] = None,
152
153
  ) -> _Mount: ...
153
154
  @staticmethod
154
155
  def _from_local_python_packages(
155
156
  *module_names: str,
156
157
  remote_dir: typing.Union[str, pathlib.PurePosixPath] = "/root",
157
- condition: typing.Optional[typing.Callable[[str], bool]] = None,
158
- ignore: typing.Union[typing.Sequence[str], typing.Callable[[pathlib.Path], bool], None] = None,
158
+ condition: typing.Optional[collections.abc.Callable[[str], bool]] = None,
159
+ ignore: typing.Union[typing.Sequence[str], collections.abc.Callable[[pathlib.Path], bool], None] = None,
159
160
  ) -> _Mount: ...
160
161
  @staticmethod
161
162
  def from_name(name: str, namespace=1, environment_name: typing.Optional[str] = None) -> _Mount: ...
@@ -176,6 +177,8 @@ class _Mount(modal.object._Object):
176
177
  ) -> None: ...
177
178
  def _get_metadata(self) -> modal_proto.api_pb2.MountHandleMetadata: ...
178
179
 
180
+ SUPERSELF = typing.TypeVar("SUPERSELF", covariant=True)
181
+
179
182
  class Mount(modal.object.Object):
180
183
  _entries: typing.Optional[list[_MountEntry]]
181
184
  _deployment_name: typing.Optional[str]
@@ -196,14 +199,14 @@ class Mount(modal.object.Object):
196
199
  def _add_local_dir(
197
200
  local_path: pathlib.Path,
198
201
  remote_path: pathlib.PurePosixPath,
199
- ignore: typing.Callable[[pathlib.Path], bool] = modal.file_pattern_matcher._NOTHING,
202
+ ignore: collections.abc.Callable[[pathlib.Path], bool] = modal.file_pattern_matcher._NOTHING,
200
203
  ): ...
201
204
  def add_local_dir(
202
205
  self,
203
206
  local_path: typing.Union[str, pathlib.Path],
204
207
  *,
205
208
  remote_path: typing.Union[str, pathlib.PurePosixPath, None] = None,
206
- condition: typing.Optional[typing.Callable[[str], bool]] = None,
209
+ condition: typing.Optional[collections.abc.Callable[[str], bool]] = None,
207
210
  recursive: bool = True,
208
211
  ) -> Mount: ...
209
212
  @staticmethod
@@ -211,7 +214,7 @@ class Mount(modal.object.Object):
211
214
  local_path: typing.Union[str, pathlib.Path],
212
215
  *,
213
216
  remote_path: typing.Union[str, pathlib.PurePosixPath, None] = None,
214
- condition: typing.Optional[typing.Callable[[str], bool]] = None,
217
+ condition: typing.Optional[collections.abc.Callable[[str], bool]] = None,
215
218
  recursive: bool = True,
216
219
  ) -> Mount: ...
217
220
  @staticmethod
@@ -219,7 +222,7 @@ class Mount(modal.object.Object):
219
222
  local_path: typing.Union[str, pathlib.Path],
220
223
  *,
221
224
  remote_path: typing.Union[str, pathlib.PurePosixPath, None] = None,
222
- condition: typing.Optional[typing.Callable[[str], bool]] = None,
225
+ condition: typing.Optional[collections.abc.Callable[[str], bool]] = None,
223
226
  recursive: bool = True,
224
227
  ) -> Mount: ...
225
228
  def add_local_file(
@@ -248,25 +251,25 @@ class Mount(modal.object.Object):
248
251
 
249
252
  _get_files: ___get_files_spec
250
253
 
251
- class ___load_mount_spec(typing_extensions.Protocol):
254
+ class ___load_mount_spec(typing_extensions.Protocol[SUPERSELF]):
252
255
  def __call__(self, resolver: modal._resolver.Resolver, existing_object_id: typing.Optional[str]): ...
253
256
  async def aio(self, resolver: modal._resolver.Resolver, existing_object_id: typing.Optional[str]): ...
254
257
 
255
- _load_mount: ___load_mount_spec
258
+ _load_mount: ___load_mount_spec[typing_extensions.Self]
256
259
 
257
260
  @staticmethod
258
261
  def from_local_python_packages(
259
262
  *module_names: str,
260
263
  remote_dir: typing.Union[str, pathlib.PurePosixPath] = "/root",
261
- condition: typing.Optional[typing.Callable[[str], bool]] = None,
262
- ignore: typing.Union[typing.Sequence[str], typing.Callable[[pathlib.Path], bool], None] = None,
264
+ condition: typing.Optional[collections.abc.Callable[[str], bool]] = None,
265
+ ignore: typing.Union[typing.Sequence[str], collections.abc.Callable[[pathlib.Path], bool], None] = None,
263
266
  ) -> Mount: ...
264
267
  @staticmethod
265
268
  def _from_local_python_packages(
266
269
  *module_names: str,
267
270
  remote_dir: typing.Union[str, pathlib.PurePosixPath] = "/root",
268
- condition: typing.Optional[typing.Callable[[str], bool]] = None,
269
- ignore: typing.Union[typing.Sequence[str], typing.Callable[[pathlib.Path], bool], None] = None,
271
+ condition: typing.Optional[collections.abc.Callable[[str], bool]] = None,
272
+ ignore: typing.Union[typing.Sequence[str], collections.abc.Callable[[pathlib.Path], bool], None] = None,
270
273
  ) -> Mount: ...
271
274
  @staticmethod
272
275
  def from_name(name: str, namespace=1, environment_name: typing.Optional[str] = None) -> Mount: ...
@@ -279,7 +282,7 @@ class Mount(modal.object.Object):
279
282
  environment_name: typing.Optional[str] = None,
280
283
  ) -> Mount: ...
281
284
 
282
- class ___deploy_spec(typing_extensions.Protocol):
285
+ class ___deploy_spec(typing_extensions.Protocol[SUPERSELF]):
283
286
  def __call__(
284
287
  self,
285
288
  deployment_name: typing.Optional[str] = None,
@@ -295,7 +298,7 @@ class Mount(modal.object.Object):
295
298
  client: typing.Optional[modal.client.Client] = None,
296
299
  ) -> None: ...
297
300
 
298
- _deploy: ___deploy_spec
301
+ _deploy: ___deploy_spec[typing_extensions.Self]
299
302
 
300
303
  def _get_metadata(self) -> modal_proto.api_pb2.MountHandleMetadata: ...
301
304
 
@@ -12,6 +12,13 @@ from synchronicity.async_wrap import asynccontextmanager
12
12
  import modal
13
13
  from modal_proto import api_pb2
14
14
 
15
+ from ._object import (
16
+ EPHEMERAL_OBJECT_HEARTBEAT_SLEEP,
17
+ _get_environment_name,
18
+ _Object,
19
+ live_method,
20
+ live_method_gen,
21
+ )
15
22
  from ._resolver import Resolver
16
23
  from ._utils.async_utils import TaskContext, aclosing, async_map, sync_or_async_iter, synchronize_api
17
24
  from ._utils.blob_utils import LARGE_FILE_LIMIT, blob_iter, blob_upload_file
@@ -21,13 +28,6 @@ from ._utils.hash_utils import get_sha256_hex
21
28
  from ._utils.name_utils import check_object_name
22
29
  from .client import _Client
23
30
  from .exception import InvalidError
24
- from .object import (
25
- EPHEMERAL_OBJECT_HEARTBEAT_SLEEP,
26
- _get_environment_name,
27
- _Object,
28
- live_method,
29
- live_method_gen,
30
- )
31
31
  from .volume import FileEntry
32
32
 
33
33
  NETWORK_FILE_SYSTEM_PUT_FILE_CLIENT_TIMEOUT = (