modal 1.5.3.dev12__tar.gz → 1.5.3.dev13__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 (236) hide show
  1. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/PKG-INFO +1 -1
  2. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_environments.py +1 -1
  3. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_grpc_client.py +1 -1
  4. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_object.py +5 -4
  5. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_output/rich.py +3 -3
  6. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_resources.py +4 -4
  7. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_runtime/user_code_imports.py +2 -1
  8. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_traceback.py +1 -1
  9. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/async_utils.py +5 -0
  10. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/blob_utils.py +1 -0
  11. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/bytes_io_segment_payload.py +2 -1
  12. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/pattern_utils.py +2 -2
  13. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/time_utils.py +3 -1
  14. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/app.py +3 -1
  15. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/app.pyi +4 -0
  16. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/cluster.py +1 -1
  17. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/dashboard.py +1 -1
  18. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/endpoint.py +2 -2
  19. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/environment.py +1 -1
  20. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/launch.py +1 -1
  21. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/network_file_system.py +1 -1
  22. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/profile.py +3 -3
  23. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/shell.py +2 -2
  24. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/client.pyi +2 -2
  25. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cloud_bucket_mount.py +3 -2
  26. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/experimental/__init__.py +2 -0
  27. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/file_pattern_matcher.py +1 -1
  28. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/functions.pyi +6 -6
  29. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/mount.py +89 -31
  30. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/mount.pyi +18 -6
  31. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/secret.py +2 -2
  32. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/serving.py +3 -3
  33. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal.egg-info/PKG-INFO +1 -1
  34. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal_proto/task_command_router_pb2.py +32 -32
  35. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal_proto/task_command_router_pb2.pyi +5 -1
  36. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal_version/__init__.py +1 -1
  37. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/pyproject.toml +48 -1
  38. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/LICENSE +0 -0
  39. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/README.md +0 -0
  40. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/__init__.py +0 -0
  41. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/__main__.py +0 -0
  42. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_billing.py +0 -0
  43. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_clustered_functions.py +0 -0
  44. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_clustered_functions.pyi +0 -0
  45. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_container_entrypoint.py +0 -0
  46. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_function_variants.py +0 -0
  47. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_functions.py +0 -0
  48. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_image.py +0 -0
  49. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_ipython.py +0 -0
  50. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_load_context.py +0 -0
  51. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_location.py +0 -0
  52. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_logs.py +0 -0
  53. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_logs_manager.py +0 -0
  54. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_logs_manager.pyi +0 -0
  55. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_output/__init__.py +0 -0
  56. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_output/manager.py +0 -0
  57. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_output/pty.py +0 -0
  58. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_output/status.py +0 -0
  59. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_partial_function.py +0 -0
  60. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_resolver.py +0 -0
  61. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_runtime/__init__.py +0 -0
  62. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_runtime/asgi.py +0 -0
  63. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_runtime/container_io_manager.py +0 -0
  64. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_runtime/container_io_manager.pyi +0 -0
  65. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_runtime/execution_context.py +0 -0
  66. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_runtime/execution_context.pyi +0 -0
  67. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_runtime/gpu_memory_snapshot.py +0 -0
  68. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_runtime/task_lifecycle_manager.py +0 -0
  69. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_runtime/task_lifecycle_manager.pyi +0 -0
  70. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_runtime/telemetry.py +0 -0
  71. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_runtime/user_code_event_loop.py +0 -0
  72. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_serialization.py +0 -0
  73. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_server.py +0 -0
  74. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_supports_logs.py +0 -0
  75. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_tunnel.py +0 -0
  76. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_tunnel.pyi +0 -0
  77. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_type_manager.py +0 -0
  78. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/__init__.py +0 -0
  79. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/app_utils.py +0 -0
  80. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/auth_token_manager.py +0 -0
  81. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/browser_utils.py +0 -0
  82. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/curl_utils.py +0 -0
  83. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/deprecation.py +0 -0
  84. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/display_utils.py +0 -0
  85. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/docker_utils.py +0 -0
  86. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/function_utils.py +0 -0
  87. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/git_utils.py +0 -0
  88. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/grpc_testing.py +0 -0
  89. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/grpc_utils.py +0 -0
  90. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/hash_utils.py +0 -0
  91. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/http_utils.py +0 -0
  92. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/jwt_utils.py +0 -0
  93. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/logger.py +0 -0
  94. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/mount_utils.py +0 -0
  95. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/name_utils.py +0 -0
  96. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/package_utils.py +0 -0
  97. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/proxy_support.py +0 -0
  98. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/rand_pb_testing.py +0 -0
  99. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/sandbox_fs_utils.py +0 -0
  100. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/shell_utils.py +0 -0
  101. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_utils/task_command_router_client.py +0 -0
  102. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_vendor/__init__.py +0 -0
  103. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_vendor/a2wsgi_wsgi.py +0 -0
  104. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_vendor/cloudpickle.py +0 -0
  105. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_vendor/tblib.py +0 -0
  106. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_vendor/version.py +0 -0
  107. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_watcher.py +0 -0
  108. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/_workspace.py +0 -0
  109. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/billing.py +0 -0
  110. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/billing.pyi +0 -0
  111. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/builder/2023.12.312.txt +0 -0
  112. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/builder/2023.12.txt +0 -0
  113. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/builder/2024.04.txt +0 -0
  114. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/builder/2024.10.txt +0 -0
  115. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/builder/2025.06.txt +0 -0
  116. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/builder/PREVIEW.txt +0 -0
  117. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/builder/README.md +0 -0
  118. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/builder/base-images.json +0 -0
  119. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/call_graph.py +0 -0
  120. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/__init__.py +0 -0
  121. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/_download.py +0 -0
  122. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/_help.py +0 -0
  123. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/_traceback.py +0 -0
  124. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/app.py +0 -0
  125. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/billing.py +0 -0
  126. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/bootstrap.py +0 -0
  127. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/changelog.py +0 -0
  128. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/config.py +0 -0
  129. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/container.py +0 -0
  130. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/curl.py +0 -0
  131. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/dict.py +0 -0
  132. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/entry_point.py +0 -0
  133. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/image.py +0 -0
  134. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/import_refs.py +0 -0
  135. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/logo.py +0 -0
  136. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/programs/__init__.py +0 -0
  137. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/programs/run_jupyter.py +0 -0
  138. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/programs/vscode.py +0 -0
  139. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/queues.py +0 -0
  140. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/run.py +0 -0
  141. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/secret.py +0 -0
  142. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/selector.py +0 -0
  143. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/skills.py +0 -0
  144. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/token.py +0 -0
  145. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/utils.py +0 -0
  146. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/volume.py +0 -0
  147. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cli/workspace.py +0 -0
  148. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/client.py +0 -0
  149. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cloud_bucket_mount.pyi +0 -0
  150. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cls.py +0 -0
  151. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/cls.pyi +0 -0
  152. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/config.py +0 -0
  153. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/container_process.py +0 -0
  154. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/container_process.pyi +0 -0
  155. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/dict.py +0 -0
  156. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/dict.pyi +0 -0
  157. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/environments.py +0 -0
  158. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/environments.pyi +0 -0
  159. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/exception.py +0 -0
  160. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/experimental/flash.py +0 -0
  161. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/experimental/flash.pyi +0 -0
  162. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/experimental/ipython.py +0 -0
  163. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/file_io.py +0 -0
  164. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/file_io.pyi +0 -0
  165. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/functions.py +0 -0
  166. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/image.py +0 -0
  167. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/image.pyi +0 -0
  168. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/io_streams.py +0 -0
  169. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/io_streams.pyi +0 -0
  170. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/network_file_system.py +0 -0
  171. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/network_file_system.pyi +0 -0
  172. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/object.py +0 -0
  173. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/object.pyi +0 -0
  174. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/output.py +0 -0
  175. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/parallel_map.py +0 -0
  176. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/parallel_map.pyi +0 -0
  177. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/partial_function.py +0 -0
  178. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/partial_function.pyi +0 -0
  179. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/proxy.py +0 -0
  180. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/proxy.pyi +0 -0
  181. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/py.typed +0 -0
  182. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/queue.py +0 -0
  183. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/queue.pyi +0 -0
  184. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/retries.py +0 -0
  185. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/runner.py +0 -0
  186. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/runner.pyi +0 -0
  187. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/running_app.py +0 -0
  188. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/sandbox.py +0 -0
  189. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/sandbox.pyi +0 -0
  190. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/sandbox_fs.py +0 -0
  191. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/sandbox_fs.pyi +0 -0
  192. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/schedule.py +0 -0
  193. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/scheduler_placement.py +0 -0
  194. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/secret.pyi +0 -0
  195. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/server.py +0 -0
  196. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/server.pyi +0 -0
  197. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/serving.pyi +0 -0
  198. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/skills/modal/SKILL.md +0 -0
  199. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/snapshot.py +0 -0
  200. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/snapshot.pyi +0 -0
  201. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/stream_type.py +0 -0
  202. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/token_flow.py +0 -0
  203. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/token_flow.pyi +0 -0
  204. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/types.py +0 -0
  205. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/volume.py +0 -0
  206. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/volume.pyi +0 -0
  207. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/workspace.py +0 -0
  208. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal/workspace.pyi +0 -0
  209. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal.egg-info/SOURCES.txt +0 -0
  210. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal.egg-info/dependency_links.txt +0 -0
  211. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal.egg-info/entry_points.txt +0 -0
  212. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal.egg-info/requires.txt +0 -0
  213. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal.egg-info/top_level.txt +0 -0
  214. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal_docs/__init__.py +0 -0
  215. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal_docs/gen_cli_docs.py +0 -0
  216. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal_docs/gen_cli_docs_main.py +0 -0
  217. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal_docs/gen_reference_docs.py +0 -0
  218. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal_docs/gen_reference_docs_main.py +0 -0
  219. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal_docs/mdmd/__init__.py +0 -0
  220. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal_docs/mdmd/mdmd.py +0 -0
  221. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal_docs/mdmd/signatures.py +0 -0
  222. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal_docs/mdmd/types.py +0 -0
  223. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal_docs/reference_intro.md +0 -0
  224. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal_proto/__init__.py +0 -0
  225. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal_proto/api_grpc.py +0 -0
  226. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal_proto/api_pb2.py +0 -0
  227. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal_proto/api_pb2.pyi +0 -0
  228. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal_proto/api_pb2_grpc.py +0 -0
  229. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal_proto/api_pb2_grpc.pyi +0 -0
  230. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal_proto/modal_api_grpc.py +0 -0
  231. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal_proto/py.typed +0 -0
  232. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal_proto/task_command_router_grpc.py +0 -0
  233. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal_proto/task_command_router_pb2_grpc.py +0 -0
  234. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
  235. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/modal_version/__main__.py +0 -0
  236. {modal-1.5.3.dev12 → modal-1.5.3.dev13}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.5.3.dev12
3
+ Version: 1.5.3.dev13
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License-Expression: Apache-2.0
@@ -591,4 +591,4 @@ def ensure_env(environment_name: str | None = None) -> str:
591
591
  if environment_name is not None:
592
592
  config.override_locally("environment", environment_name)
593
593
 
594
- return config.get("environment")
594
+ return config.get("environment") or ""
@@ -54,7 +54,7 @@ class grpc_error_converter:
54
54
  with suppress_tb_frame():
55
55
  if isinstance(exc, GRPCError):
56
56
  modal_exc = _STATUS_TO_EXCEPTION[exc.status](exc.message)
57
- modal_exc._grpc_message = exc.message
57
+ modal_exc._grpc_message = exc.message or ""
58
58
  modal_exc._grpc_status = exc.status
59
59
  modal_exc._grpc_details = exc.details
60
60
  if use_full_traceback:
@@ -23,19 +23,20 @@ EPHEMERAL_OBJECT_HEARTBEAT_SLEEP: int = 300
23
23
 
24
24
  def _get_environment_name(
25
25
  environment_name: str | None = None,
26
- ) -> str | None:
26
+ ) -> str:
27
27
  """Get environment name from various sources.
28
28
 
29
29
  Args:
30
- environment_name: Explicitly provided environment name (highest priority)
30
+ environment_name: Explicitly provided environment name (highest priority).
31
31
 
32
32
  Returns:
33
- Environment name from first available source, or config default
33
+ Environment name from as passed in, from config, or as a null string
34
+ (which implies workspace-level default).
34
35
  """
35
36
  if environment_name:
36
37
  return environment_name
37
38
  else:
38
- return config.get("environment")
39
+ return config.get("environment") or ""
39
40
 
40
41
 
41
42
  def live_method(method):
@@ -81,11 +81,11 @@ class FunctionQueuingColumn(ProgressColumn):
81
81
  super().__init__()
82
82
 
83
83
  def render(self, task) -> Text:
84
- self.lag = max(task.completed - task.elapsed, self.lag)
84
+ self.lag = max(task.completed - (task.elapsed or 0), self.lag)
85
85
  if task.finished:
86
- elapsed = max(task.finished_time, task.completed)
86
+ elapsed = max(task.finished_time or 0, task.completed)
87
87
  else:
88
- elapsed = task.elapsed + self.lag
88
+ elapsed = (task.elapsed or 0) + self.lag
89
89
  delta = timedelta(seconds=int(elapsed))
90
90
  return Text(str(delta), style="progress.elapsed")
91
91
 
@@ -26,10 +26,10 @@ def convert_fn_config_to_resources_config(
26
26
  raise InvalidError(f"Cannot specify a CPU limit lower than request: {milli_cpu_max} < {milli_cpu}")
27
27
  elif cpu and isinstance(cpu, (float, int)):
28
28
  milli_cpu = int(1000 * cpu)
29
- milli_cpu_max = None
29
+ milli_cpu_max = 0
30
30
  else:
31
- milli_cpu = None
32
- milli_cpu_max = None
31
+ milli_cpu = 0
32
+ milli_cpu_max = 0
33
33
 
34
34
  if memory and isinstance(memory, int):
35
35
  memory_mb = memory
@@ -47,6 +47,6 @@ def convert_fn_config_to_resources_config(
47
47
  gpu_config=parse_gpu_config(gpu),
48
48
  memory_mb=memory_mb,
49
49
  memory_mb_max=memory_mb_max,
50
- ephemeral_disk_mb=ephemeral_disk,
50
+ ephemeral_disk_mb=ephemeral_disk or 0,
51
51
  rdma=rdma or False,
52
52
  )
@@ -549,7 +549,8 @@ def _get_cls_or_user_cls(
549
549
  else:
550
550
  # Load the module dynamically for non-serialized class.
551
551
  module = importlib.import_module(function_def.module_name)
552
- qual_name: str = function_def.function_name
552
+ # Always use implementation_name to find the class, default to function_name if implementation_name not set.
553
+ qual_name: str = function_def.implementation_name or function_def.function_name
553
554
 
554
555
  if not is_global_object(qual_name):
555
556
  raise LocalFunctionError("Attempted to load a class defined in a function scope")
@@ -75,7 +75,7 @@ def append_modal_tb(exc: BaseException, tb_dict: TBDictType, line_cache: LineCac
75
75
  setattr(exc, "__line_cache__", line_cache)
76
76
 
77
77
 
78
- def reduce_traceback_to_user_code(tb: TracebackType | None, user_source: str) -> TracebackType:
78
+ def reduce_traceback_to_user_code(tb: TracebackType | None, user_source: str) -> TracebackType | None:
79
79
  """Return a traceback that does not contain modal entrypoint or synchronicity frames."""
80
80
 
81
81
  # Step forward all the way through the traceback and drop any "Modal support" frames
@@ -1266,3 +1266,8 @@ def deprecate_aio_usage(deprecation_date: tuple[int, int, int], readable_sync_ca
1266
1266
  return MethodWithAio(sync_implementation, _async_proxy, synchronizer, is_classmethod=is_classmethod)
1267
1267
 
1268
1268
  return deco
1269
+
1270
+
1271
+ async def async_generator_from_sync(lst: Iterable[T]) -> AsyncGenerator[T, None]:
1272
+ for item in lst:
1273
+ yield item
@@ -444,6 +444,7 @@ class FileUploadSpec:
444
444
  mode: int # file permission bits (last 12 bits of st_mode)
445
445
  size: int
446
446
  content: bytes | None = None # Set for very small files to avoid double-read
447
+ exists_in_store: bool | None = None # set after existence check
447
448
 
448
449
  def read_content(self) -> bytes:
449
450
  """Read content from source."""
@@ -45,7 +45,8 @@ class BytesIOSegmentPayload(Payload):
45
45
  self.segment_length = segment_length
46
46
  # seek to start of file segment we are interested in, in order to make .size() evaluate correctly
47
47
  self._value.seek(self.initial_seek_pos + segment_start)
48
- assert self.segment_length <= super().size
48
+ base_size = super().size
49
+ assert base_size is not None and self.segment_length <= base_size
49
50
  self.chunk_size = chunk_size
50
51
  self.progress_report_cb = progress_report_cb or (lambda *_, **__: None)
51
52
  self.reset_state()
@@ -143,12 +143,12 @@ class Pattern:
143
143
  else:
144
144
  return False
145
145
  elif self.match_type == MatchType.REGEXP:
146
- return self.regexp.match(path) is not None
146
+ return self.regexp is not None and self.regexp.match(path) is not None
147
147
  else:
148
148
  return False
149
149
 
150
150
 
151
- def read_ignorefile(reader: TextIO) -> list[str]:
151
+ def read_ignorefile(reader: TextIO | None) -> list[str]:
152
152
  """Read an ignore file from a reader and return the list of file patterns to
153
153
  ignore, applying the following rules:
154
154
 
@@ -294,7 +294,9 @@ def relative_timestamp(dt: datetime) -> str:
294
294
 
295
295
 
296
296
  def locale_tz() -> tzinfo:
297
- return datetime.now().astimezone().tzinfo
297
+ tz = datetime.now().astimezone().tzinfo
298
+ assert tz is not None
299
+ return tz
298
300
 
299
301
 
300
302
  def as_timestamp(arg: datetime | str | None) -> float:
@@ -1295,6 +1295,7 @@ class _App:
1295
1295
  scaleup_window: int | None = None, # Stabilization window (seconds) of sustained demand before scaling up
1296
1296
  scaledown_window: int | None = None, # Max idle time before scaling down (seconds)
1297
1297
  startup_timeout: int = 30, # Maximum container startup time in seconds
1298
+ name: str | None = None, # Name of the server
1298
1299
  port: int = 8000, # Port the HTTP server listens on
1299
1300
  unauthenticated: bool = False, # Whether the endpoint requires proxy authentication, required by default.
1300
1301
  h2_enabled: bool = False, # Enable HTTP/2
@@ -1341,6 +1342,7 @@ class _App:
1341
1342
  scaleup_window: Seconds of sustained demand required before scaling up new containers.
1342
1343
  scaledown_window: Maximum duration (in seconds) idle containers wait before scaling down.
1343
1344
  startup_timeout: Maximum container startup time in seconds.
1345
+ name: Sets the Modal name of the function within the app, defaults to class name.
1344
1346
  port: Port the HTTP server listens on.
1345
1347
  unauthenticated: Whether the endpoint requires proxy authentication; required by default.
1346
1348
  h2_enabled: Enable HTTP/2.
@@ -1423,7 +1425,7 @@ class _App:
1423
1425
  local_state = self._local_state
1424
1426
 
1425
1427
  # Create the FunctionInfo for the server, note we treat FunctionInfo as a class for servers
1426
- info = FunctionInfo(None, serialized=serialized, user_cls=user_cls, name_override=user_cls.__name__)
1428
+ info = FunctionInfo(None, serialized=serialized, user_cls=user_cls, name_override=name or user_cls.__name__)
1427
1429
  # Create the service function
1428
1430
  service_function = _Function.from_local(
1429
1431
  info,
@@ -751,6 +751,7 @@ class _App:
751
751
  scaleup_window: typing.Optional[int] = None,
752
752
  scaledown_window: typing.Optional[int] = None,
753
753
  startup_timeout: int = 30,
754
+ name: typing.Optional[str] = None,
754
755
  port: int = 8000,
755
756
  unauthenticated: bool = False,
756
757
  h2_enabled: bool = False,
@@ -797,6 +798,7 @@ class _App:
797
798
  scaleup_window: Seconds of sustained demand required before scaling up new containers.
798
799
  scaledown_window: Maximum duration (in seconds) idle containers wait before scaling down.
799
800
  startup_timeout: Maximum container startup time in seconds.
801
+ name: Sets the Modal name of the function within the app, defaults to class name.
800
802
  port: Port the HTTP server listens on.
801
803
  unauthenticated: Whether the endpoint requires proxy authentication; required by default.
802
804
  h2_enabled: Enable HTTP/2.
@@ -1755,6 +1757,7 @@ class App:
1755
1757
  scaleup_window: typing.Optional[int] = None,
1756
1758
  scaledown_window: typing.Optional[int] = None,
1757
1759
  startup_timeout: int = 30,
1760
+ name: typing.Optional[str] = None,
1758
1761
  port: int = 8000,
1759
1762
  unauthenticated: bool = False,
1760
1763
  h2_enabled: bool = False,
@@ -1799,6 +1802,7 @@ class App:
1799
1802
  scaleup_window: Seconds of sustained demand required before scaling up new containers.
1800
1803
  scaledown_window: Maximum duration (in seconds) idle containers wait before scaling down.
1801
1804
  startup_timeout: Maximum container startup time in seconds.
1805
+ name: Sets the Modal name of the function within the app, defaults to class name.
1802
1806
  port: Port the HTTP server listens on.
1803
1807
  unauthenticated: Whether the endpoint requires proxy authentication; required by default.
1804
1808
  h2_enabled: Enable HTTP/2.
@@ -51,7 +51,7 @@ async def list_(env: str | None = None, json: bool = False):
51
51
  [
52
52
  c.cluster_id,
53
53
  c.app_id,
54
- timestamp_to_localized_str(c.started_at, json) if c.started_at else "Pending",
54
+ timestamp_to_localized_str(c.started_at, json) or "Pending",
55
55
  str(len(c.task_ids)),
56
56
  ]
57
57
  )
@@ -21,7 +21,7 @@ async def dashboard(
21
21
  if object_id:
22
22
  url = f"https://modal.com/id/{object_id}"
23
23
  else:
24
- env = config.get("environment")
24
+ env = config.get("environment") or ""
25
25
  request = api_pb2.WorkspaceDashboardUrlRequest(environment_name=env)
26
26
  client = await _Client.from_env()
27
27
  response = await client.stub.WorkspaceDashboardUrlGet(request)
@@ -207,7 +207,7 @@ async def create(
207
207
  raise click.UsageError("--custom-volume-path requires --custom-volume-name.")
208
208
 
209
209
  env_name = ensure_env(env)
210
- environment_name = _get_environment_name(env_name) or ""
210
+ environment_name = _get_environment_name(env_name)
211
211
  client = await _Client.from_env()
212
212
 
213
213
  compute_region_spec = api_pb2.EndpointComputeRegionSpec()
@@ -271,7 +271,7 @@ async def create(
271
271
  async def list_(*, json: bool = False, env: Optional[str] = None):
272
272
  """List Endpoints that are provisioning or running in an environment."""
273
273
  env_name = ensure_env(env)
274
- environment_name = _get_environment_name(env_name) or ""
274
+ environment_name = _get_environment_name(env_name)
275
275
  client = await _Client.from_env()
276
276
 
277
277
  items: list[api_pb2.EndpointListItem] = []
@@ -53,7 +53,7 @@ def list_(json: bool = False):
53
53
 
54
54
  # determine which environment is currently active, prioritizing the local default
55
55
  # over the server default
56
- active_env = config.get("environment")
56
+ active_env = config.get("environment") or ""
57
57
  for env in envs:
58
58
  if env.default is True and active_env is None:
59
59
  active_env = env.name
@@ -52,7 +52,7 @@ def _launch_program(
52
52
  else:
53
53
  func()
54
54
  except Exception as exc:
55
- raise _CliUserExecutionError(inspect.getsourcefile(func)) from exc
55
+ raise _CliUserExecutionError(inspect.getsourcefile(func) or "<unknown>") from exc
56
56
 
57
57
 
58
58
  @launch_cli.command("jupyter", help="Start Jupyter Lab on Modal.")
@@ -29,7 +29,7 @@ nfs_cli = ModalGroup(name="nfs", help="Read and edit `modal.NetworkFileSystem` f
29
29
  @env_option
30
30
  @click.option("--json", is_flag=True, default=False)
31
31
  @synchronizer.create_blocking
32
- async def list_(env: str | None = None, json: bool | None = False):
32
+ async def list_(env: str | None = None, json: bool = False):
33
33
  env = ensure_env(env)
34
34
 
35
35
  client = await _Client.from_env()
@@ -71,7 +71,7 @@ async def list_(json: bool | None = False):
71
71
  # Catch-all for other exceptions, like incorrect server url
72
72
  workspace = "Unknown (profile misconfigured)"
73
73
  else:
74
- assert hasattr(resp, "username")
74
+ assert not isinstance(resp, BaseException)
75
75
  workspace = resp.username
76
76
  content = ["•" if active else "", profile, workspace]
77
77
  rows.append((active, content))
@@ -81,8 +81,8 @@ async def list_(json: bool | None = False):
81
81
  try:
82
82
  env_based_resp = await _lookup_workspace(
83
83
  config.get("server_url", profile=_profile),
84
- os.environ.get("MODAL_TOKEN_ID"),
85
- os.environ.get("MODAL_TOKEN_SECRET"),
84
+ os.environ["MODAL_TOKEN_ID"],
85
+ os.environ.get("MODAL_TOKEN_SECRET", ""),
86
86
  )
87
87
  env_based_workspace = env_based_resp.username
88
88
  except AuthError:
@@ -48,7 +48,7 @@ def _passed_forbidden_args(
48
48
  passed_forbidden: list[str] = []
49
49
  for param in params:
50
50
  name = param.name
51
- if name is None or allowed(name):
51
+ if not name or allowed(name):
52
52
  continue
53
53
  default = param.process_value(ctx, param.get_default(ctx))
54
54
  if passed_args.get(name) != default:
@@ -150,7 +150,7 @@ def _start_shell_in_running_container(ref: str, cmd: str, pty: bool) -> None:
150
150
 
151
151
  assert _is_valid_modal_id(ref, "ta-")
152
152
  try:
153
- _exec_impl(container_id=ref, command=shlex.split(cmd), pty=pty, object_id_for_v2=object_id_for_v2)
153
+ _ = _exec_impl(container_id=ref, command=tuple(shlex.split(cmd)), pty=pty, object_id_for_v2=object_id_for_v2)
154
154
  except NotFoundError:
155
155
  raise ClickException(f"Container '{ref}' not found (is it still running?)")
156
156
  except Exception as e:
@@ -37,7 +37,7 @@ class _Client:
37
37
  server_url: str,
38
38
  client_type: int,
39
39
  credentials: typing.Optional[tuple[str, str]],
40
- version: str = "1.5.3.dev12",
40
+ version: str = "1.5.3.dev13",
41
41
  ):
42
42
  """mdmd:hidden
43
43
  The Modal client object is not intended to be instantiated directly by users.
@@ -207,7 +207,7 @@ class Client:
207
207
  server_url: str,
208
208
  client_type: int,
209
209
  credentials: typing.Optional[tuple[str, str]],
210
- version: str = "1.5.3.dev12",
210
+ version: str = "1.5.3.dev13",
211
211
  ):
212
212
  """mdmd:hidden
213
213
  The Modal client object is not intended to be instantiated directly by users.
@@ -134,9 +134,10 @@ def cloud_bucket_mounts_to_proto(
134
134
  # crude mapping from mount arguments to type.
135
135
  if mount.bucket_endpoint_url:
136
136
  parse_result = urlparse(mount.bucket_endpoint_url)
137
- if parse_result.hostname.endswith("r2.cloudflarestorage.com"):
137
+ hostname = parse_result.hostname or ""
138
+ if hostname.endswith("r2.cloudflarestorage.com"):
138
139
  bucket_type = api_pb2.CloudBucketMount.BucketType.R2
139
- elif parse_result.hostname.endswith("storage.googleapis.com"):
140
+ elif hostname.endswith("storage.googleapis.com"):
140
141
  bucket_type = api_pb2.CloudBucketMount.BucketType.GCP
141
142
  else:
142
143
  logger.info(
@@ -141,6 +141,7 @@ async def stop_app(name: str, *, environment_name: str | None = None, client: _C
141
141
  """
142
142
  client_ = client or await _Client.from_env()
143
143
  app = await _App.lookup(name, environment_name=environment_name, client=client_)
144
+ assert app.app_id
144
145
  req = api_pb2.AppStopRequest(app_id=app.app_id, source=api_pb2.APP_STOP_SOURCE_PYTHON_CLIENT)
145
146
  await client_.stub.AppStop(req)
146
147
 
@@ -174,6 +175,7 @@ async def get_app_objects(
174
175
  client = await _Client.from_env()
175
176
 
176
177
  app = await _App.lookup(app_name, environment_name=environment_name, client=client)
178
+ assert app.app_id
177
179
  req = api_pb2.AppGetLayoutRequest(app_id=app.app_id)
178
180
  app_layout_resp = await client.stub.AppGetLayout(req)
179
181
 
@@ -201,7 +201,7 @@ class FilePatternMatcher(_AbstractPatternMatcher):
201
201
  pattern_strings = Path(self._file_path).read_text("utf8").splitlines()
202
202
  else:
203
203
  # Use patterns provided in __init__
204
- pattern_strings = list(self._pattern_strings)
204
+ pattern_strings = list(self._pattern_strings or [])
205
205
 
206
206
  return self._parse_patterns(pattern_strings)
207
207
 
@@ -516,7 +516,7 @@ class Function(
516
516
 
517
517
  _call_generator: ___call_generator_spec
518
518
 
519
- class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
519
+ class __remote_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
520
520
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER:
521
521
  """Calls the function remotely, executing it with the given arguments and returning the execution's result.
522
522
 
@@ -541,7 +541,7 @@ class Function(
541
541
  """
542
542
  ...
543
543
 
544
- remote: __remote_spec[modal._functions.ReturnType, modal._functions.P]
544
+ remote: __remote_spec[modal._functions.P, modal._functions.ReturnType]
545
545
 
546
546
  class __remote_gen_spec(typing_extensions.Protocol):
547
547
  def __call__(self, /, *args, **kwargs) -> typing.Generator[typing.Any, None, None]:
@@ -591,7 +591,7 @@ class Function(
591
591
  """
592
592
  ...
593
593
 
594
- class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
594
+ class ___experimental_spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
595
595
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
596
596
  """[Experimental] Calls the function with the given arguments, without waiting for the results.
597
597
 
@@ -624,7 +624,7 @@ class Function(
624
624
  """
625
625
  ...
626
626
 
627
- _experimental_spawn: ___experimental_spawn_spec[modal._functions.ReturnType, modal._functions.P]
627
+ _experimental_spawn: ___experimental_spawn_spec[modal._functions.P, modal._functions.ReturnType]
628
628
 
629
629
  class ___spawn_map_inner_spec(typing_extensions.Protocol[P_INNER]):
630
630
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> None: ...
@@ -632,7 +632,7 @@ class Function(
632
632
 
633
633
  _spawn_map_inner: ___spawn_map_inner_spec[modal._functions.P]
634
634
 
635
- class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
635
+ class __spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
636
636
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
637
637
  """Calls the function with the given arguments, without waiting for the results.
638
638
 
@@ -665,7 +665,7 @@ class Function(
665
665
  """
666
666
  ...
667
667
 
668
- spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P]
668
+ spawn: __spawn_spec[modal._functions.P, modal._functions.ReturnType]
669
669
 
670
670
  def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]:
671
671
  """Return the inner Python object wrapped by this Modal Function.