modal 0.74.6__tar.gz → 0.74.7__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 (183) hide show
  1. {modal-0.74.6 → modal-0.74.7}/PKG-INFO +1 -1
  2. {modal-0.74.6 → modal-0.74.7}/modal/_resolver.py +12 -0
  3. {modal-0.74.6 → modal-0.74.7}/modal/_utils/blob_utils.py +2 -0
  4. {modal-0.74.6 → modal-0.74.7}/modal/client.pyi +2 -2
  5. {modal-0.74.6 → modal-0.74.7}/modal/config.py +20 -3
  6. {modal-0.74.6 → modal-0.74.7}/modal/mount.py +12 -0
  7. {modal-0.74.6 → modal-0.74.7}/modal.egg-info/PKG-INFO +1 -1
  8. {modal-0.74.6 → modal-0.74.7}/modal_version/_version_generated.py +1 -1
  9. {modal-0.74.6 → modal-0.74.7}/LICENSE +0 -0
  10. {modal-0.74.6 → modal-0.74.7}/README.md +0 -0
  11. {modal-0.74.6 → modal-0.74.7}/modal/__init__.py +0 -0
  12. {modal-0.74.6 → modal-0.74.7}/modal/__main__.py +0 -0
  13. {modal-0.74.6 → modal-0.74.7}/modal/_clustered_functions.py +0 -0
  14. {modal-0.74.6 → modal-0.74.7}/modal/_clustered_functions.pyi +0 -0
  15. {modal-0.74.6 → modal-0.74.7}/modal/_container_entrypoint.py +0 -0
  16. {modal-0.74.6 → modal-0.74.7}/modal/_functions.py +0 -0
  17. {modal-0.74.6 → modal-0.74.7}/modal/_ipython.py +0 -0
  18. {modal-0.74.6 → modal-0.74.7}/modal/_location.py +0 -0
  19. {modal-0.74.6 → modal-0.74.7}/modal/_object.py +0 -0
  20. {modal-0.74.6 → modal-0.74.7}/modal/_output.py +0 -0
  21. {modal-0.74.6 → modal-0.74.7}/modal/_partial_function.py +0 -0
  22. {modal-0.74.6 → modal-0.74.7}/modal/_pty.py +0 -0
  23. {modal-0.74.6 → modal-0.74.7}/modal/_resources.py +0 -0
  24. {modal-0.74.6 → modal-0.74.7}/modal/_runtime/__init__.py +0 -0
  25. {modal-0.74.6 → modal-0.74.7}/modal/_runtime/asgi.py +0 -0
  26. {modal-0.74.6 → modal-0.74.7}/modal/_runtime/container_io_manager.py +0 -0
  27. {modal-0.74.6 → modal-0.74.7}/modal/_runtime/container_io_manager.pyi +0 -0
  28. {modal-0.74.6 → modal-0.74.7}/modal/_runtime/execution_context.py +0 -0
  29. {modal-0.74.6 → modal-0.74.7}/modal/_runtime/execution_context.pyi +0 -0
  30. {modal-0.74.6 → modal-0.74.7}/modal/_runtime/gpu_memory_snapshot.py +0 -0
  31. {modal-0.74.6 → modal-0.74.7}/modal/_runtime/telemetry.py +0 -0
  32. {modal-0.74.6 → modal-0.74.7}/modal/_runtime/user_code_imports.py +0 -0
  33. {modal-0.74.6 → modal-0.74.7}/modal/_serialization.py +0 -0
  34. {modal-0.74.6 → modal-0.74.7}/modal/_traceback.py +0 -0
  35. {modal-0.74.6 → modal-0.74.7}/modal/_tunnel.py +0 -0
  36. {modal-0.74.6 → modal-0.74.7}/modal/_tunnel.pyi +0 -0
  37. {modal-0.74.6 → modal-0.74.7}/modal/_type_manager.py +0 -0
  38. {modal-0.74.6 → modal-0.74.7}/modal/_utils/__init__.py +0 -0
  39. {modal-0.74.6 → modal-0.74.7}/modal/_utils/app_utils.py +0 -0
  40. {modal-0.74.6 → modal-0.74.7}/modal/_utils/async_utils.py +0 -0
  41. {modal-0.74.6 → modal-0.74.7}/modal/_utils/bytes_io_segment_payload.py +0 -0
  42. {modal-0.74.6 → modal-0.74.7}/modal/_utils/deprecation.py +0 -0
  43. {modal-0.74.6 → modal-0.74.7}/modal/_utils/docker_utils.py +0 -0
  44. {modal-0.74.6 → modal-0.74.7}/modal/_utils/function_utils.py +0 -0
  45. {modal-0.74.6 → modal-0.74.7}/modal/_utils/git_utils.py +0 -0
  46. {modal-0.74.6 → modal-0.74.7}/modal/_utils/grpc_testing.py +0 -0
  47. {modal-0.74.6 → modal-0.74.7}/modal/_utils/grpc_utils.py +0 -0
  48. {modal-0.74.6 → modal-0.74.7}/modal/_utils/hash_utils.py +0 -0
  49. {modal-0.74.6 → modal-0.74.7}/modal/_utils/http_utils.py +0 -0
  50. {modal-0.74.6 → modal-0.74.7}/modal/_utils/jwt_utils.py +0 -0
  51. {modal-0.74.6 → modal-0.74.7}/modal/_utils/logger.py +0 -0
  52. {modal-0.74.6 → modal-0.74.7}/modal/_utils/mount_utils.py +0 -0
  53. {modal-0.74.6 → modal-0.74.7}/modal/_utils/name_utils.py +0 -0
  54. {modal-0.74.6 → modal-0.74.7}/modal/_utils/package_utils.py +0 -0
  55. {modal-0.74.6 → modal-0.74.7}/modal/_utils/pattern_utils.py +0 -0
  56. {modal-0.74.6 → modal-0.74.7}/modal/_utils/rand_pb_testing.py +0 -0
  57. {modal-0.74.6 → modal-0.74.7}/modal/_utils/shell_utils.py +0 -0
  58. {modal-0.74.6 → modal-0.74.7}/modal/_vendor/__init__.py +0 -0
  59. {modal-0.74.6 → modal-0.74.7}/modal/_vendor/a2wsgi_wsgi.py +0 -0
  60. {modal-0.74.6 → modal-0.74.7}/modal/_vendor/cloudpickle.py +0 -0
  61. {modal-0.74.6 → modal-0.74.7}/modal/_vendor/tblib.py +0 -0
  62. {modal-0.74.6 → modal-0.74.7}/modal/_watcher.py +0 -0
  63. {modal-0.74.6 → modal-0.74.7}/modal/app.py +0 -0
  64. {modal-0.74.6 → modal-0.74.7}/modal/app.pyi +0 -0
  65. {modal-0.74.6 → modal-0.74.7}/modal/call_graph.py +0 -0
  66. {modal-0.74.6 → modal-0.74.7}/modal/cli/__init__.py +0 -0
  67. {modal-0.74.6 → modal-0.74.7}/modal/cli/_download.py +0 -0
  68. {modal-0.74.6 → modal-0.74.7}/modal/cli/_traceback.py +0 -0
  69. {modal-0.74.6 → modal-0.74.7}/modal/cli/app.py +0 -0
  70. {modal-0.74.6 → modal-0.74.7}/modal/cli/config.py +0 -0
  71. {modal-0.74.6 → modal-0.74.7}/modal/cli/container.py +0 -0
  72. {modal-0.74.6 → modal-0.74.7}/modal/cli/dict.py +0 -0
  73. {modal-0.74.6 → modal-0.74.7}/modal/cli/entry_point.py +0 -0
  74. {modal-0.74.6 → modal-0.74.7}/modal/cli/environment.py +0 -0
  75. {modal-0.74.6 → modal-0.74.7}/modal/cli/import_refs.py +0 -0
  76. {modal-0.74.6 → modal-0.74.7}/modal/cli/launch.py +0 -0
  77. {modal-0.74.6 → modal-0.74.7}/modal/cli/network_file_system.py +0 -0
  78. {modal-0.74.6 → modal-0.74.7}/modal/cli/profile.py +0 -0
  79. {modal-0.74.6 → modal-0.74.7}/modal/cli/programs/__init__.py +0 -0
  80. {modal-0.74.6 → modal-0.74.7}/modal/cli/programs/run_jupyter.py +0 -0
  81. {modal-0.74.6 → modal-0.74.7}/modal/cli/programs/vscode.py +0 -0
  82. {modal-0.74.6 → modal-0.74.7}/modal/cli/queues.py +0 -0
  83. {modal-0.74.6 → modal-0.74.7}/modal/cli/run.py +0 -0
  84. {modal-0.74.6 → modal-0.74.7}/modal/cli/secret.py +0 -0
  85. {modal-0.74.6 → modal-0.74.7}/modal/cli/token.py +0 -0
  86. {modal-0.74.6 → modal-0.74.7}/modal/cli/utils.py +0 -0
  87. {modal-0.74.6 → modal-0.74.7}/modal/cli/volume.py +0 -0
  88. {modal-0.74.6 → modal-0.74.7}/modal/client.py +0 -0
  89. {modal-0.74.6 → modal-0.74.7}/modal/cloud_bucket_mount.py +0 -0
  90. {modal-0.74.6 → modal-0.74.7}/modal/cloud_bucket_mount.pyi +0 -0
  91. {modal-0.74.6 → modal-0.74.7}/modal/cls.py +0 -0
  92. {modal-0.74.6 → modal-0.74.7}/modal/cls.pyi +0 -0
  93. {modal-0.74.6 → modal-0.74.7}/modal/container_process.py +0 -0
  94. {modal-0.74.6 → modal-0.74.7}/modal/container_process.pyi +0 -0
  95. {modal-0.74.6 → modal-0.74.7}/modal/dict.py +0 -0
  96. {modal-0.74.6 → modal-0.74.7}/modal/dict.pyi +0 -0
  97. {modal-0.74.6 → modal-0.74.7}/modal/environments.py +0 -0
  98. {modal-0.74.6 → modal-0.74.7}/modal/environments.pyi +0 -0
  99. {modal-0.74.6 → modal-0.74.7}/modal/exception.py +0 -0
  100. {modal-0.74.6 → modal-0.74.7}/modal/experimental/__init__.py +0 -0
  101. {modal-0.74.6 → modal-0.74.7}/modal/experimental/ipython.py +0 -0
  102. {modal-0.74.6 → modal-0.74.7}/modal/file_io.py +0 -0
  103. {modal-0.74.6 → modal-0.74.7}/modal/file_io.pyi +0 -0
  104. {modal-0.74.6 → modal-0.74.7}/modal/file_pattern_matcher.py +0 -0
  105. {modal-0.74.6 → modal-0.74.7}/modal/functions.py +0 -0
  106. {modal-0.74.6 → modal-0.74.7}/modal/functions.pyi +0 -0
  107. {modal-0.74.6 → modal-0.74.7}/modal/gpu.py +0 -0
  108. {modal-0.74.6 → modal-0.74.7}/modal/image.py +0 -0
  109. {modal-0.74.6 → modal-0.74.7}/modal/image.pyi +0 -0
  110. {modal-0.74.6 → modal-0.74.7}/modal/io_streams.py +0 -0
  111. {modal-0.74.6 → modal-0.74.7}/modal/io_streams.pyi +0 -0
  112. {modal-0.74.6 → modal-0.74.7}/modal/mount.pyi +0 -0
  113. {modal-0.74.6 → modal-0.74.7}/modal/network_file_system.py +0 -0
  114. {modal-0.74.6 → modal-0.74.7}/modal/network_file_system.pyi +0 -0
  115. {modal-0.74.6 → modal-0.74.7}/modal/object.py +0 -0
  116. {modal-0.74.6 → modal-0.74.7}/modal/object.pyi +0 -0
  117. {modal-0.74.6 → modal-0.74.7}/modal/output.py +0 -0
  118. {modal-0.74.6 → modal-0.74.7}/modal/parallel_map.py +0 -0
  119. {modal-0.74.6 → modal-0.74.7}/modal/parallel_map.pyi +0 -0
  120. {modal-0.74.6 → modal-0.74.7}/modal/partial_function.py +0 -0
  121. {modal-0.74.6 → modal-0.74.7}/modal/partial_function.pyi +0 -0
  122. {modal-0.74.6 → modal-0.74.7}/modal/proxy.py +0 -0
  123. {modal-0.74.6 → modal-0.74.7}/modal/proxy.pyi +0 -0
  124. {modal-0.74.6 → modal-0.74.7}/modal/py.typed +0 -0
  125. {modal-0.74.6 → modal-0.74.7}/modal/queue.py +0 -0
  126. {modal-0.74.6 → modal-0.74.7}/modal/queue.pyi +0 -0
  127. {modal-0.74.6 → modal-0.74.7}/modal/requirements/2023.12.312.txt +0 -0
  128. {modal-0.74.6 → modal-0.74.7}/modal/requirements/2023.12.txt +0 -0
  129. {modal-0.74.6 → modal-0.74.7}/modal/requirements/2024.04.txt +0 -0
  130. {modal-0.74.6 → modal-0.74.7}/modal/requirements/2024.10.txt +0 -0
  131. {modal-0.74.6 → modal-0.74.7}/modal/requirements/PREVIEW.txt +0 -0
  132. {modal-0.74.6 → modal-0.74.7}/modal/requirements/README.md +0 -0
  133. {modal-0.74.6 → modal-0.74.7}/modal/requirements/base-images.json +0 -0
  134. {modal-0.74.6 → modal-0.74.7}/modal/retries.py +0 -0
  135. {modal-0.74.6 → modal-0.74.7}/modal/runner.py +0 -0
  136. {modal-0.74.6 → modal-0.74.7}/modal/runner.pyi +0 -0
  137. {modal-0.74.6 → modal-0.74.7}/modal/running_app.py +0 -0
  138. {modal-0.74.6 → modal-0.74.7}/modal/sandbox.py +0 -0
  139. {modal-0.74.6 → modal-0.74.7}/modal/sandbox.pyi +0 -0
  140. {modal-0.74.6 → modal-0.74.7}/modal/schedule.py +0 -0
  141. {modal-0.74.6 → modal-0.74.7}/modal/scheduler_placement.py +0 -0
  142. {modal-0.74.6 → modal-0.74.7}/modal/secret.py +0 -0
  143. {modal-0.74.6 → modal-0.74.7}/modal/secret.pyi +0 -0
  144. {modal-0.74.6 → modal-0.74.7}/modal/serving.py +0 -0
  145. {modal-0.74.6 → modal-0.74.7}/modal/serving.pyi +0 -0
  146. {modal-0.74.6 → modal-0.74.7}/modal/snapshot.py +0 -0
  147. {modal-0.74.6 → modal-0.74.7}/modal/snapshot.pyi +0 -0
  148. {modal-0.74.6 → modal-0.74.7}/modal/stream_type.py +0 -0
  149. {modal-0.74.6 → modal-0.74.7}/modal/token_flow.py +0 -0
  150. {modal-0.74.6 → modal-0.74.7}/modal/token_flow.pyi +0 -0
  151. {modal-0.74.6 → modal-0.74.7}/modal/volume.py +0 -0
  152. {modal-0.74.6 → modal-0.74.7}/modal/volume.pyi +0 -0
  153. {modal-0.74.6 → modal-0.74.7}/modal.egg-info/SOURCES.txt +0 -0
  154. {modal-0.74.6 → modal-0.74.7}/modal.egg-info/dependency_links.txt +0 -0
  155. {modal-0.74.6 → modal-0.74.7}/modal.egg-info/entry_points.txt +0 -0
  156. {modal-0.74.6 → modal-0.74.7}/modal.egg-info/requires.txt +0 -0
  157. {modal-0.74.6 → modal-0.74.7}/modal.egg-info/top_level.txt +0 -0
  158. {modal-0.74.6 → modal-0.74.7}/modal_docs/__init__.py +0 -0
  159. {modal-0.74.6 → modal-0.74.7}/modal_docs/gen_cli_docs.py +0 -0
  160. {modal-0.74.6 → modal-0.74.7}/modal_docs/gen_reference_docs.py +0 -0
  161. {modal-0.74.6 → modal-0.74.7}/modal_docs/mdmd/__init__.py +0 -0
  162. {modal-0.74.6 → modal-0.74.7}/modal_docs/mdmd/mdmd.py +0 -0
  163. {modal-0.74.6 → modal-0.74.7}/modal_docs/mdmd/signatures.py +0 -0
  164. {modal-0.74.6 → modal-0.74.7}/modal_proto/__init__.py +0 -0
  165. {modal-0.74.6 → modal-0.74.7}/modal_proto/api.proto +0 -0
  166. {modal-0.74.6 → modal-0.74.7}/modal_proto/api_grpc.py +0 -0
  167. {modal-0.74.6 → modal-0.74.7}/modal_proto/api_pb2.py +0 -0
  168. {modal-0.74.6 → modal-0.74.7}/modal_proto/api_pb2.pyi +0 -0
  169. {modal-0.74.6 → modal-0.74.7}/modal_proto/api_pb2_grpc.py +0 -0
  170. {modal-0.74.6 → modal-0.74.7}/modal_proto/api_pb2_grpc.pyi +0 -0
  171. {modal-0.74.6 → modal-0.74.7}/modal_proto/modal_api_grpc.py +0 -0
  172. {modal-0.74.6 → modal-0.74.7}/modal_proto/modal_options_grpc.py +0 -0
  173. {modal-0.74.6 → modal-0.74.7}/modal_proto/options.proto +0 -0
  174. {modal-0.74.6 → modal-0.74.7}/modal_proto/options_grpc.py +0 -0
  175. {modal-0.74.6 → modal-0.74.7}/modal_proto/options_pb2.py +0 -0
  176. {modal-0.74.6 → modal-0.74.7}/modal_proto/options_pb2.pyi +0 -0
  177. {modal-0.74.6 → modal-0.74.7}/modal_proto/options_pb2_grpc.py +0 -0
  178. {modal-0.74.6 → modal-0.74.7}/modal_proto/options_pb2_grpc.pyi +0 -0
  179. {modal-0.74.6 → modal-0.74.7}/modal_proto/py.typed +0 -0
  180. {modal-0.74.6 → modal-0.74.7}/modal_version/__init__.py +0 -0
  181. {modal-0.74.6 → modal-0.74.7}/modal_version/__main__.py +0 -0
  182. {modal-0.74.6 → modal-0.74.7}/pyproject.toml +0 -0
  183. {modal-0.74.6 → modal-0.74.7}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 0.74.6
3
+ Version: 0.74.7
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -1,6 +1,8 @@
1
1
  # Copyright Modal Labs 2023
2
2
  import asyncio
3
3
  import contextlib
4
+ import os
5
+ import tempfile
4
6
  import typing
5
7
  from asyncio import Future
6
8
  from collections.abc import Hashable
@@ -46,6 +48,7 @@ class Resolver:
46
48
  _app_id: Optional[str]
47
49
  _deduplication_cache: dict[Hashable, Future]
48
50
  _client: _Client
51
+ _build_start: float
49
52
 
50
53
  def __init__(
51
54
  self,
@@ -73,6 +76,11 @@ class Resolver:
73
76
  self._environment_name = environment_name
74
77
  self._deduplication_cache = {}
75
78
 
79
+ with tempfile.TemporaryFile() as temp_file:
80
+ # Use file mtime to track build start time because we will later compare this baseline
81
+ # to the mtime on mounted files, and want those measurements to have the same resolution.
82
+ self._build_start = os.fstat(temp_file.fileno()).st_mtime
83
+
76
84
  @property
77
85
  def app_id(self) -> Optional[str]:
78
86
  return self._app_id
@@ -85,6 +93,10 @@ class Resolver:
85
93
  def environment_name(self):
86
94
  return self._environment_name
87
95
 
96
+ @property
97
+ def build_start(self) -> float:
98
+ return self._build_start
99
+
88
100
  async def preload(self, obj, existing_object_id: Optional[str]):
89
101
  if obj._preload is not None:
90
102
  await obj._preload(obj, self, existing_object_id)
@@ -292,6 +292,7 @@ async def blob_iter(blob_id: str, stub: ModalClientModal) -> AsyncIterator[bytes
292
292
  class FileUploadSpec:
293
293
  source: Callable[[], Union[AbstractContextManager, BinaryIO]]
294
294
  source_description: Any
295
+ source_is_path: bool
295
296
  mount_filename: str
296
297
 
297
298
  use_blob: bool
@@ -328,6 +329,7 @@ def _get_file_upload_spec(
328
329
  return FileUploadSpec(
329
330
  source=source,
330
331
  source_description=source_description,
332
+ source_is_path=isinstance(source_description, Path),
331
333
  mount_filename=mount_filename.as_posix(),
332
334
  use_blob=use_blob,
333
335
  content=content,
@@ -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.74.6"
30
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.74.7"
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.74.6"
88
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.74.7"
89
89
  ): ...
90
90
  def is_closed(self) -> bool: ...
91
91
  @property
@@ -87,7 +87,7 @@ import os
87
87
  import typing
88
88
  import warnings
89
89
  from textwrap import dedent
90
- from typing import Any, Optional
90
+ from typing import Any, Callable, Optional
91
91
 
92
92
  from google.protobuf.empty_pb2 import Empty
93
93
 
@@ -199,6 +199,15 @@ def _to_boolean(x: object) -> bool:
199
199
  return str(x).lower() not in {"", "0", "false"}
200
200
 
201
201
 
202
+ def _check_value(options: list[str]) -> Callable[[str], str]:
203
+ def checker(x: str) -> str:
204
+ if x not in options:
205
+ raise ValueError(f"Must be one of {options}.")
206
+ return x
207
+
208
+ return checker
209
+
210
+
202
211
  class _Setting(typing.NamedTuple):
203
212
  default: typing.Any = None
204
213
  transform: typing.Callable[[str], typing.Any] = lambda x: x # noqa: E731
@@ -232,6 +241,7 @@ _SETTINGS = {
232
241
  "snapshot_debug": _Setting(False, transform=_to_boolean),
233
242
  "cuda_checkpoint_path": _Setting("/__modal/.bin/cuda-checkpoint"), # Used for snapshotting GPU memory.
234
243
  "function_schemas": _Setting(False, transform=_to_boolean),
244
+ "build_validation": _Setting("error", transform=_check_value(["error", "warn", "ignore"])),
235
245
  }
236
246
 
237
247
 
@@ -253,10 +263,17 @@ class Config:
253
263
  profile = _profile
254
264
  s = _SETTINGS[key]
255
265
  env_var_key = "MODAL_" + key.upper()
266
+
267
+ def transform(val: str) -> Any:
268
+ try:
269
+ return s.transform(val)
270
+ except Exception as e:
271
+ raise InvalidError(f"Invalid value for {key} config ({val!r}): {e}")
272
+
256
273
  if use_env and env_var_key in os.environ:
257
- return s.transform(os.environ[env_var_key])
274
+ return transform(os.environ[env_var_key])
258
275
  elif profile in _user_config and key in _user_config[profile]:
259
- return s.transform(_user_config[profile][key])
276
+ return transform(_user_config[profile][key])
260
277
  else:
261
278
  return s.default
262
279
 
@@ -9,6 +9,7 @@ import sys
9
9
  import sysconfig
10
10
  import time
11
11
  import typing
12
+ import warnings
12
13
  from collections.abc import AsyncGenerator
13
14
  from pathlib import Path, PurePosixPath
14
15
  from typing import Callable, Optional, Sequence, Union
@@ -532,6 +533,17 @@ class _Mount(_Object, type_prefix="mo"):
532
533
  n_finished += 1
533
534
  return mount_file
534
535
 
536
+ # Try to catch cases where user modified their local files (e.g. changed git branches)
537
+ # between triggering a build and Modal actually uploading the file
538
+ if config.get("build_validation") != "ignore" and file_spec.source_is_path:
539
+ mtime = os.stat(file_spec.source_description).st_mtime
540
+ if mtime > resolver.build_start:
541
+ msg = f"{file_spec.source_description} was modified during build process."
542
+ if config.get("build_validation") == "error":
543
+ raise modal.exception.ExecutionError(msg)
544
+ elif config.get("build_validation") == "warn":
545
+ warnings.warn(msg)
546
+
535
547
  request = api_pb2.MountPutFileRequest(sha256_hex=file_spec.sha256_hex)
536
548
  accounted_hashes.add(file_spec.sha256_hex)
537
549
  response = await retry_transient_errors(resolver.client.stub.MountPutFile, request, base_delay=1)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 0.74.6
3
+ Version: 0.74.7
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -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 = 6 # git: e51abe8
4
+ build_number = 7 # git: 52311ba
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes