modal 1.1.5.dev49__tar.gz → 1.1.5.dev50__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.

Potentially problematic release.


This version of modal might be problematic. Click here for more details.

Files changed (196) hide show
  1. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/PKG-INFO +1 -1
  2. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_output.py +27 -12
  3. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/client.pyi +2 -2
  4. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal.egg-info/PKG-INFO +1 -1
  5. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_version/__init__.py +1 -1
  6. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/LICENSE +0 -0
  7. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/README.md +0 -0
  8. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/__init__.py +0 -0
  9. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/__main__.py +0 -0
  10. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_clustered_functions.py +0 -0
  11. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_clustered_functions.pyi +0 -0
  12. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_container_entrypoint.py +0 -0
  13. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_functions.py +0 -0
  14. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_ipython.py +0 -0
  15. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_location.py +0 -0
  16. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_object.py +0 -0
  17. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_partial_function.py +0 -0
  18. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_pty.py +0 -0
  19. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_resolver.py +0 -0
  20. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_resources.py +0 -0
  21. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_runtime/__init__.py +0 -0
  22. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_runtime/asgi.py +0 -0
  23. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_runtime/container_io_manager.py +0 -0
  24. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_runtime/container_io_manager.pyi +0 -0
  25. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_runtime/execution_context.py +0 -0
  26. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_runtime/execution_context.pyi +0 -0
  27. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_runtime/gpu_memory_snapshot.py +0 -0
  28. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_runtime/telemetry.py +0 -0
  29. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_runtime/user_code_imports.py +0 -0
  30. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_serialization.py +0 -0
  31. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_traceback.py +0 -0
  32. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_tunnel.py +0 -0
  33. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_tunnel.pyi +0 -0
  34. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_type_manager.py +0 -0
  35. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_utils/__init__.py +0 -0
  36. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_utils/app_utils.py +0 -0
  37. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_utils/async_utils.py +0 -0
  38. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_utils/auth_token_manager.py +0 -0
  39. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_utils/blob_utils.py +0 -0
  40. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_utils/bytes_io_segment_payload.py +0 -0
  41. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_utils/deprecation.py +0 -0
  42. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_utils/docker_utils.py +0 -0
  43. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_utils/function_utils.py +0 -0
  44. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_utils/git_utils.py +0 -0
  45. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_utils/grpc_testing.py +0 -0
  46. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_utils/grpc_utils.py +0 -0
  47. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_utils/hash_utils.py +0 -0
  48. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_utils/http_utils.py +0 -0
  49. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_utils/jwt_utils.py +0 -0
  50. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_utils/logger.py +0 -0
  51. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_utils/mount_utils.py +0 -0
  52. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_utils/name_utils.py +0 -0
  53. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_utils/package_utils.py +0 -0
  54. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_utils/pattern_utils.py +0 -0
  55. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_utils/rand_pb_testing.py +0 -0
  56. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_utils/shell_utils.py +0 -0
  57. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_utils/time_utils.py +0 -0
  58. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_vendor/__init__.py +0 -0
  59. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_vendor/a2wsgi_wsgi.py +0 -0
  60. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_vendor/cloudpickle.py +0 -0
  61. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_vendor/tblib.py +0 -0
  62. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/_watcher.py +0 -0
  63. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/app.py +0 -0
  64. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/app.pyi +0 -0
  65. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/builder/2023.12.312.txt +0 -0
  66. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/builder/2023.12.txt +0 -0
  67. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/builder/2024.04.txt +0 -0
  68. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/builder/2024.10.txt +0 -0
  69. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/builder/2025.06.txt +0 -0
  70. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/builder/PREVIEW.txt +0 -0
  71. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/builder/README.md +0 -0
  72. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/builder/base-images.json +0 -0
  73. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/call_graph.py +0 -0
  74. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cli/__init__.py +0 -0
  75. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cli/_download.py +0 -0
  76. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cli/_traceback.py +0 -0
  77. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cli/app.py +0 -0
  78. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cli/cluster.py +0 -0
  79. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cli/config.py +0 -0
  80. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cli/container.py +0 -0
  81. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cli/dict.py +0 -0
  82. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cli/entry_point.py +0 -0
  83. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cli/environment.py +0 -0
  84. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cli/import_refs.py +0 -0
  85. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cli/launch.py +0 -0
  86. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cli/network_file_system.py +0 -0
  87. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cli/profile.py +0 -0
  88. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cli/programs/__init__.py +0 -0
  89. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cli/programs/launch_instance_ssh.py +0 -0
  90. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cli/programs/run_jupyter.py +0 -0
  91. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cli/programs/run_marimo.py +0 -0
  92. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cli/programs/vscode.py +0 -0
  93. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cli/queues.py +0 -0
  94. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cli/run.py +0 -0
  95. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cli/secret.py +0 -0
  96. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cli/token.py +0 -0
  97. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cli/utils.py +0 -0
  98. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cli/volume.py +0 -0
  99. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/client.py +0 -0
  100. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cloud_bucket_mount.py +0 -0
  101. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cloud_bucket_mount.pyi +0 -0
  102. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cls.py +0 -0
  103. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/cls.pyi +0 -0
  104. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/config.py +0 -0
  105. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/container_process.py +0 -0
  106. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/container_process.pyi +0 -0
  107. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/dict.py +0 -0
  108. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/dict.pyi +0 -0
  109. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/environments.py +0 -0
  110. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/environments.pyi +0 -0
  111. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/exception.py +0 -0
  112. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/experimental/__init__.py +0 -0
  113. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/experimental/flash.py +0 -0
  114. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/experimental/flash.pyi +0 -0
  115. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/experimental/ipython.py +0 -0
  116. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/file_io.py +0 -0
  117. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/file_io.pyi +0 -0
  118. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/file_pattern_matcher.py +0 -0
  119. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/functions.py +0 -0
  120. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/functions.pyi +0 -0
  121. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/gpu.py +0 -0
  122. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/image.py +0 -0
  123. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/image.pyi +0 -0
  124. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/io_streams.py +0 -0
  125. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/io_streams.pyi +0 -0
  126. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/mount.py +0 -0
  127. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/mount.pyi +0 -0
  128. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/network_file_system.py +0 -0
  129. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/network_file_system.pyi +0 -0
  130. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/object.py +0 -0
  131. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/object.pyi +0 -0
  132. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/output.py +0 -0
  133. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/parallel_map.py +0 -0
  134. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/parallel_map.pyi +0 -0
  135. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/partial_function.py +0 -0
  136. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/partial_function.pyi +0 -0
  137. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/proxy.py +0 -0
  138. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/proxy.pyi +0 -0
  139. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/py.typed +0 -0
  140. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/queue.py +0 -0
  141. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/queue.pyi +0 -0
  142. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/retries.py +0 -0
  143. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/runner.py +0 -0
  144. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/runner.pyi +0 -0
  145. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/running_app.py +0 -0
  146. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/sandbox.py +0 -0
  147. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/sandbox.pyi +0 -0
  148. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/schedule.py +0 -0
  149. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/scheduler_placement.py +0 -0
  150. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/secret.py +0 -0
  151. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/secret.pyi +0 -0
  152. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/serving.py +0 -0
  153. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/serving.pyi +0 -0
  154. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/snapshot.py +0 -0
  155. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/snapshot.pyi +0 -0
  156. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/stream_type.py +0 -0
  157. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/token_flow.py +0 -0
  158. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/token_flow.pyi +0 -0
  159. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/volume.py +0 -0
  160. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal/volume.pyi +0 -0
  161. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal.egg-info/SOURCES.txt +0 -0
  162. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal.egg-info/dependency_links.txt +0 -0
  163. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal.egg-info/entry_points.txt +0 -0
  164. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal.egg-info/requires.txt +0 -0
  165. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal.egg-info/top_level.txt +0 -0
  166. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_docs/__init__.py +0 -0
  167. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_docs/gen_cli_docs.py +0 -0
  168. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_docs/gen_reference_docs.py +0 -0
  169. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_docs/mdmd/__init__.py +0 -0
  170. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_docs/mdmd/mdmd.py +0 -0
  171. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_docs/mdmd/signatures.py +0 -0
  172. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_proto/__init__.py +0 -0
  173. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_proto/api.proto +0 -0
  174. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_proto/api_grpc.py +0 -0
  175. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_proto/api_pb2.py +0 -0
  176. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_proto/api_pb2.pyi +0 -0
  177. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_proto/api_pb2_grpc.py +0 -0
  178. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_proto/api_pb2_grpc.pyi +0 -0
  179. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_proto/modal_api_grpc.py +0 -0
  180. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_proto/modal_options_grpc.py +0 -0
  181. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_proto/options.proto +0 -0
  182. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_proto/options_grpc.py +0 -0
  183. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_proto/options_pb2.py +0 -0
  184. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_proto/options_pb2.pyi +0 -0
  185. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_proto/options_pb2_grpc.py +0 -0
  186. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_proto/options_pb2_grpc.pyi +0 -0
  187. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_proto/py.typed +0 -0
  188. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_proto/sandbox_router.proto +0 -0
  189. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_proto/sandbox_router_grpc.py +0 -0
  190. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_proto/sandbox_router_pb2.py +0 -0
  191. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_proto/sandbox_router_pb2.pyi +0 -0
  192. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_proto/sandbox_router_pb2_grpc.py +0 -0
  193. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_proto/sandbox_router_pb2_grpc.pyi +0 -0
  194. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/modal_version/__main__.py +0 -0
  195. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/pyproject.toml +0 -0
  196. {modal-1.1.5.dev49 → modal-1.1.5.dev50}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.1.5.dev49
3
+ Version: 1.1.5.dev50
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -35,7 +35,7 @@ from modal._utils.time_utils import timestamp_to_localized_str
35
35
  from modal_proto import api_pb2
36
36
 
37
37
  from ._utils.grpc_utils import RETRYABLE_GRPC_STATUS_CODES, retry_transient_errors
38
- from ._utils.shell_utils import stream_from_stdin
38
+ from ._utils.shell_utils import stream_from_stdin, write_to_fd
39
39
  from .client import _Client
40
40
  from .config import logger
41
41
 
@@ -507,17 +507,32 @@ async def put_pty_content(log: api_pb2.TaskLogs, stdout):
507
507
  # because the progress spinner can't interfere with output.
508
508
 
509
509
  data = log.data.encode("utf-8")
510
- written = 0
511
- n_retries = 0
512
- while written < len(data):
513
- try:
514
- written += stdout.buffer.write(data[written:])
515
- stdout.flush()
516
- except BlockingIOError:
517
- if n_retries >= 5:
518
- raise
519
- n_retries += 1
520
- await asyncio.sleep(0.1)
510
+ # Non-blocking terminals can fill the kernel buffer on output bursts, making flush() raise
511
+ # BlockingIOError (EAGAIN) and appear frozen until a key is pressed (this happened e.g. when
512
+ # printing large data from a pdb breakpoint). If stdout has a real fd, we await a
513
+ # non-blocking fd write (write_to_fd) instead.
514
+ fd = None
515
+ try:
516
+ if hasattr(stdout, "fileno"):
517
+ fd = stdout.fileno()
518
+ except Exception:
519
+ fd = None
520
+
521
+ if fd is not None:
522
+ await write_to_fd(fd, data)
523
+ else:
524
+ # For streams without fileno(), use the normal write/flush path.
525
+ written = 0
526
+ n_retries = 0
527
+ while written < len(data):
528
+ try:
529
+ written += stdout.buffer.write(data[written:])
530
+ stdout.flush()
531
+ except BlockingIOError:
532
+ if n_retries >= 5:
533
+ raise
534
+ n_retries += 1
535
+ await asyncio.sleep(0.1)
521
536
  else:
522
537
  # `stdout` isn't always buffered (e.g. %%capture in Jupyter notebooks redirects it to
523
538
  # io.StringIO).
@@ -33,7 +33,7 @@ class _Client:
33
33
  server_url: str,
34
34
  client_type: int,
35
35
  credentials: typing.Optional[tuple[str, str]],
36
- version: str = "1.1.5.dev49",
36
+ version: str = "1.1.5.dev50",
37
37
  ):
38
38
  """mdmd:hidden
39
39
  The Modal client object is not intended to be instantiated directly by users.
@@ -164,7 +164,7 @@ class Client:
164
164
  server_url: str,
165
165
  client_type: int,
166
166
  credentials: typing.Optional[tuple[str, str]],
167
- version: str = "1.1.5.dev49",
167
+ version: str = "1.1.5.dev50",
168
168
  ):
169
169
  """mdmd:hidden
170
170
  The Modal client object is not intended to be instantiated directly by users.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.1.5.dev49
3
+ Version: 1.1.5.dev50
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
  """Supplies the current version of the modal client library."""
3
3
 
4
- __version__ = "1.1.5.dev49"
4
+ __version__ = "1.1.5.dev50"
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