modal 1.4.4.dev6__tar.gz → 1.4.4.dev7__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 (214) hide show
  1. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/PKG-INFO +1 -1
  2. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_runtime/asgi.py +1 -1
  3. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/shell.py +6 -4
  4. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/client.pyi +2 -2
  5. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/io_streams.py +1 -1
  6. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/io_streams.pyi +2 -0
  7. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/sandbox.py +44 -0
  8. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/sandbox.pyi +65 -12
  9. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/sandbox_fs.py +21 -16
  10. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/sandbox_fs.pyi +9 -2
  11. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal.egg-info/PKG-INFO +1 -1
  12. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal_version/__init__.py +1 -1
  13. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/LICENSE +0 -0
  14. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/README.md +0 -0
  15. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/__init__.py +0 -0
  16. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/__main__.py +0 -0
  17. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_billing.py +0 -0
  18. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_clustered_functions.py +0 -0
  19. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_clustered_functions.pyi +0 -0
  20. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_container_entrypoint.py +0 -0
  21. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_environments.py +0 -0
  22. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_function_variants.py +0 -0
  23. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_functions.py +0 -0
  24. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_grpc_client.py +0 -0
  25. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_ipython.py +0 -0
  26. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_load_context.py +0 -0
  27. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_location.py +0 -0
  28. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_logs.py +0 -0
  29. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_object.py +0 -0
  30. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_output/__init__.py +0 -0
  31. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_output/manager.py +0 -0
  32. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_output/pty.py +0 -0
  33. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_output/rich.py +0 -0
  34. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_output/status.py +0 -0
  35. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_partial_function.py +0 -0
  36. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_resolver.py +0 -0
  37. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_resources.py +0 -0
  38. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_runtime/__init__.py +0 -0
  39. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_runtime/container_io_manager.py +0 -0
  40. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_runtime/container_io_manager.pyi +0 -0
  41. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_runtime/execution_context.py +0 -0
  42. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_runtime/execution_context.pyi +0 -0
  43. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_runtime/gpu_memory_snapshot.py +0 -0
  44. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_runtime/telemetry.py +0 -0
  45. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_runtime/user_code_event_loop.py +0 -0
  46. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_runtime/user_code_imports.py +0 -0
  47. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_serialization.py +0 -0
  48. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_server.py +0 -0
  49. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_traceback.py +0 -0
  50. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_tunnel.py +0 -0
  51. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_tunnel.pyi +0 -0
  52. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_type_manager.py +0 -0
  53. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/__init__.py +0 -0
  54. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/app_utils.py +0 -0
  55. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/async_utils.py +0 -0
  56. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/auth_token_manager.py +0 -0
  57. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/blob_utils.py +0 -0
  58. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/browser_utils.py +0 -0
  59. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/bytes_io_segment_payload.py +0 -0
  60. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/deprecation.py +0 -0
  61. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/docker_utils.py +0 -0
  62. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/function_utils.py +0 -0
  63. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/git_utils.py +0 -0
  64. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/grpc_testing.py +0 -0
  65. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/grpc_utils.py +0 -0
  66. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/hash_utils.py +0 -0
  67. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/http_utils.py +0 -0
  68. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/jwt_utils.py +0 -0
  69. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/logger.py +0 -0
  70. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/mount_utils.py +0 -0
  71. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/name_utils.py +0 -0
  72. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/package_utils.py +0 -0
  73. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/pattern_utils.py +0 -0
  74. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/rand_pb_testing.py +0 -0
  75. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/sandbox_fs_utils.py +0 -0
  76. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/shell_utils.py +0 -0
  77. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/task_command_router_client.py +0 -0
  78. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_utils/time_utils.py +0 -0
  79. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_vendor/__init__.py +0 -0
  80. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_vendor/a2wsgi_wsgi.py +0 -0
  81. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_vendor/cloudpickle.py +0 -0
  82. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_vendor/tblib.py +0 -0
  83. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_vendor/version.py +0 -0
  84. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/_watcher.py +0 -0
  85. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/app.py +0 -0
  86. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/app.pyi +0 -0
  87. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/billing.py +0 -0
  88. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/builder/2023.12.312.txt +0 -0
  89. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/builder/2023.12.txt +0 -0
  90. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/builder/2024.04.txt +0 -0
  91. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/builder/2024.10.txt +0 -0
  92. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/builder/2025.06.txt +0 -0
  93. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/builder/PREVIEW.txt +0 -0
  94. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/builder/README.md +0 -0
  95. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/builder/base-images.json +0 -0
  96. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/call_graph.py +0 -0
  97. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/__init__.py +0 -0
  98. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/_download.py +0 -0
  99. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/_help.py +0 -0
  100. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/_traceback.py +0 -0
  101. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/app.py +0 -0
  102. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/billing.py +0 -0
  103. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/bootstrap.py +0 -0
  104. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/changelog.py +0 -0
  105. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/cluster.py +0 -0
  106. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/config.py +0 -0
  107. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/container.py +0 -0
  108. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/dashboard.py +0 -0
  109. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/dict.py +0 -0
  110. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/entry_point.py +0 -0
  111. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/environment.py +0 -0
  112. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/import_refs.py +0 -0
  113. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/launch.py +0 -0
  114. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/logo.py +0 -0
  115. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/network_file_system.py +0 -0
  116. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/profile.py +0 -0
  117. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/programs/__init__.py +0 -0
  118. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/programs/run_jupyter.py +0 -0
  119. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/programs/vscode.py +0 -0
  120. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/queues.py +0 -0
  121. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/run.py +0 -0
  122. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/secret.py +0 -0
  123. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/selector.py +0 -0
  124. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/token.py +0 -0
  125. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/utils.py +0 -0
  126. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cli/volume.py +0 -0
  127. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/client.py +0 -0
  128. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cloud_bucket_mount.py +0 -0
  129. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cloud_bucket_mount.pyi +0 -0
  130. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cls.py +0 -0
  131. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/cls.pyi +0 -0
  132. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/config.py +0 -0
  133. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/container_process.py +0 -0
  134. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/container_process.pyi +0 -0
  135. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/dict.py +0 -0
  136. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/dict.pyi +0 -0
  137. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/environments.py +0 -0
  138. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/environments.pyi +0 -0
  139. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/exception.py +0 -0
  140. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/experimental/__init__.py +0 -0
  141. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/experimental/flash.py +0 -0
  142. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/experimental/flash.pyi +0 -0
  143. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/experimental/ipython.py +0 -0
  144. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/file_io.py +0 -0
  145. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/file_io.pyi +0 -0
  146. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/file_pattern_matcher.py +0 -0
  147. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/functions.py +0 -0
  148. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/functions.pyi +0 -0
  149. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/image.py +0 -0
  150. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/image.pyi +0 -0
  151. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/mount.py +0 -0
  152. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/mount.pyi +0 -0
  153. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/network_file_system.py +0 -0
  154. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/network_file_system.pyi +0 -0
  155. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/object.py +0 -0
  156. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/object.pyi +0 -0
  157. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/output.py +0 -0
  158. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/parallel_map.py +0 -0
  159. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/parallel_map.pyi +0 -0
  160. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/partial_function.py +0 -0
  161. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/partial_function.pyi +0 -0
  162. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/proxy.py +0 -0
  163. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/proxy.pyi +0 -0
  164. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/py.typed +0 -0
  165. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/queue.py +0 -0
  166. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/queue.pyi +0 -0
  167. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/retries.py +0 -0
  168. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/runner.py +0 -0
  169. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/runner.pyi +0 -0
  170. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/running_app.py +0 -0
  171. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/schedule.py +0 -0
  172. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/scheduler_placement.py +0 -0
  173. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/secret.py +0 -0
  174. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/secret.pyi +0 -0
  175. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/server.py +0 -0
  176. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/server.pyi +0 -0
  177. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/serving.py +0 -0
  178. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/serving.pyi +0 -0
  179. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/snapshot.py +0 -0
  180. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/snapshot.pyi +0 -0
  181. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/stream_type.py +0 -0
  182. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/token_flow.py +0 -0
  183. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/token_flow.pyi +0 -0
  184. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/volume.py +0 -0
  185. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal/volume.pyi +0 -0
  186. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal.egg-info/SOURCES.txt +0 -0
  187. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal.egg-info/dependency_links.txt +0 -0
  188. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal.egg-info/entry_points.txt +0 -0
  189. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal.egg-info/requires.txt +0 -0
  190. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal.egg-info/top_level.txt +0 -0
  191. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal_docs/__init__.py +0 -0
  192. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal_docs/gen_cli_docs.py +0 -0
  193. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal_docs/gen_cli_docs_main.py +0 -0
  194. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal_docs/gen_reference_docs.py +0 -0
  195. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal_docs/gen_reference_docs_main.py +0 -0
  196. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal_docs/mdmd/__init__.py +0 -0
  197. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal_docs/mdmd/mdmd.py +0 -0
  198. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal_docs/mdmd/signatures.py +0 -0
  199. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal_proto/__init__.py +0 -0
  200. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal_proto/api_grpc.py +0 -0
  201. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal_proto/api_pb2.py +0 -0
  202. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal_proto/api_pb2.pyi +0 -0
  203. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal_proto/api_pb2_grpc.py +0 -0
  204. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal_proto/api_pb2_grpc.pyi +0 -0
  205. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal_proto/modal_api_grpc.py +0 -0
  206. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal_proto/py.typed +0 -0
  207. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal_proto/task_command_router_grpc.py +0 -0
  208. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal_proto/task_command_router_pb2.py +0 -0
  209. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal_proto/task_command_router_pb2.pyi +0 -0
  210. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal_proto/task_command_router_pb2_grpc.py +0 -0
  211. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
  212. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/modal_version/__main__.py +0 -0
  213. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/pyproject.toml +0 -0
  214. {modal-1.4.4.dev6 → modal-1.4.4.dev7}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.4.4.dev6
3
+ Version: 1.4.4.dev7
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License-Expression: Apache-2.0
@@ -285,7 +285,7 @@ def wait_for_web_server(host: str, port: int, *, timeout: float) -> None:
285
285
  start_time = time.monotonic()
286
286
  while True:
287
287
  try:
288
- with socket.create_connection((host, port), timeout=timeout):
288
+ with socket.create_connection((host, port), timeout=min(timeout, 1.0)):
289
289
  break
290
290
  except OSError as ex:
291
291
  time.sleep(0.01)
@@ -2,7 +2,7 @@
2
2
  import platform
3
3
  import shlex
4
4
  from pathlib import Path, PurePosixPath
5
- from typing import Any, Callable, Iterable, Optional
5
+ from typing import Any, Callable, Iterable, Optional, Union
6
6
 
7
7
  import click
8
8
  from click import ClickException
@@ -10,6 +10,7 @@ from click import ClickException
10
10
  from .._environments import ensure_env
11
11
  from .._functions import _FunctionSpec
12
12
  from ..app import App
13
+ from ..container_process import ContainerProcess
13
14
  from ..exception import InvalidError, NotFoundError
14
15
  from ..functions import Function
15
16
  from ..image import Image
@@ -116,17 +117,18 @@ def _start_shell_in_sandbox_container(sandbox_id: str, container_name: str, cmd:
116
117
 
117
118
  try:
118
119
  sandbox_container = sandbox._experimental_containers.get(name=container_name)
120
+ process: Union[ContainerProcess[bytes], ContainerProcess[str]]
119
121
  if pty:
120
122
  # PTY output is raw terminal bytes, not text; strict UTF-8 decode
121
123
  # crashes on the first non-UTF-8 byte (e.g. vim drawing a Latin-1
122
124
  # file under LC_CTYPE=C). See the matching call in `_exec_impl`.
123
- process = sandbox_container.exec(*shlex.split(cmd), pty=pty, text=False)
125
+ process = sandbox_container.exec(*shlex.split(cmd), pty=True, text=False)
124
126
  process.attach()
125
127
  else:
126
128
  process = sandbox_container.exec(
127
- *shlex.split(cmd), pty=pty, stdout=StreamType.STDOUT, stderr=StreamType.STDOUT
129
+ *shlex.split(cmd), pty=False, text=False, stdout=StreamType.STDOUT, stderr=StreamType.STDOUT
128
130
  )
129
- process.wait()
131
+ _ = process.wait()
130
132
  except NotFoundError:
131
133
  raise ClickException(f"Container '{container_name}' not found in Sandbox '{sandbox_id}'.")
132
134
  except Exception as e:
@@ -35,7 +35,7 @@ class _Client:
35
35
  server_url: str,
36
36
  client_type: int,
37
37
  credentials: typing.Optional[tuple[str, str]],
38
- version: str = "1.4.4.dev6",
38
+ version: str = "1.4.4.dev7",
39
39
  ):
40
40
  """mdmd:hidden
41
41
  The Modal client object is not intended to be instantiated directly by users.
@@ -175,7 +175,7 @@ class Client:
175
175
  server_url: str,
176
176
  client_type: int,
177
177
  credentials: typing.Optional[tuple[str, str]],
178
- version: str = "1.4.4.dev6",
178
+ version: str = "1.4.4.dev7",
179
179
  ):
180
180
  """mdmd:hidden
181
181
  The Modal client object is not intended to be instantiated directly by users.
@@ -501,7 +501,7 @@ class _StreamReader(Generic[T]):
501
501
  MAX_BUFFER_SIZE = 2 * 1024 * 1024
502
502
  # Larger buffer limit for the exec path via the task command router.
503
503
  # This applies only to task_exec_stdin_write; sandbox stdin via the server keeps MAX_BUFFER_SIZE.
504
- TASK_COMMAND_ROUTER_MAX_BUFFER_SIZE = 16 * 1024 * 1024
504
+ TASK_COMMAND_ROUTER_MAX_BUFFER_SIZE: int = 16 * 1024 * 1024
505
505
 
506
506
 
507
507
  @dataclass(frozen=True)
@@ -589,3 +589,5 @@ class StreamWriter:
589
589
  ...
590
590
 
591
591
  drain: __drain_spec
592
+
593
+ TASK_COMMAND_ROUTER_MAX_BUFFER_SIZE: int
@@ -5,6 +5,7 @@ import enum
5
5
  import json
6
6
  import os
7
7
  import time
8
+ import typing
8
9
  import uuid
9
10
  from collections.abc import AsyncGenerator, Collection, Sequence
10
11
  from dataclasses import dataclass
@@ -1857,6 +1858,7 @@ class _SandboxContainer:
1857
1858
  """Handle to an additional container running in a Sandbox."""
1858
1859
 
1859
1860
  _result: Optional[api_pb2.GenericResult]
1861
+ _filesystem: Optional[_SandboxFilesystem]
1860
1862
 
1861
1863
  def __init__(
1862
1864
  self,
@@ -1869,6 +1871,7 @@ class _SandboxContainer:
1869
1871
  self._container_id = container_id
1870
1872
  self._container_name = container_name
1871
1873
  self._result = result
1874
+ self._filesystem = None
1872
1875
 
1873
1876
  @property
1874
1877
  def object_id(self) -> str:
@@ -1889,6 +1892,40 @@ class _SandboxContainer:
1889
1892
  command_router_client = await self._sandbox._get_command_router_client(task_id)
1890
1893
  return task_id, command_router_client
1891
1894
 
1895
+ @typing.overload
1896
+ async def exec(
1897
+ self,
1898
+ *args: str,
1899
+ stdout: StreamType = StreamType.PIPE,
1900
+ stderr: StreamType = StreamType.PIPE,
1901
+ timeout: Optional[int] = None,
1902
+ workdir: Optional[str] = None,
1903
+ env: Optional[dict[str, Optional[str]]] = None,
1904
+ secrets: Optional[Collection[_Secret]] = None,
1905
+ text: Literal[True] = True,
1906
+ bufsize: Literal[-1, 1] = -1,
1907
+ # Enable a PTY for the command. When enabled, all output (stdout and stderr from the
1908
+ # process) is multiplexed into stdout, and the stderr stream is effectively empty.
1909
+ pty: bool = False,
1910
+ ) -> _ContainerProcess[str]: ...
1911
+
1912
+ @typing.overload
1913
+ async def exec(
1914
+ self,
1915
+ *args: str,
1916
+ stdout: StreamType = StreamType.PIPE,
1917
+ stderr: StreamType = StreamType.PIPE,
1918
+ timeout: Optional[int] = None,
1919
+ workdir: Optional[str] = None,
1920
+ env: Optional[dict[str, Optional[str]]] = None,
1921
+ secrets: Optional[Collection[_Secret]] = None,
1922
+ text: Literal[False],
1923
+ bufsize: Literal[-1, 1] = -1,
1924
+ # Enable a PTY for the command. When enabled, all output (stdout and stderr from the
1925
+ # process) is multiplexed into stdout, and the stderr stream is effectively empty.
1926
+ pty: bool = False,
1927
+ ) -> _ContainerProcess[bytes]: ...
1928
+
1892
1929
  async def exec(
1893
1930
  self,
1894
1931
  *args: str,
@@ -1919,6 +1956,13 @@ class _SandboxContainer:
1919
1956
  container_id=self._container_id,
1920
1957
  )
1921
1958
 
1959
+ @property
1960
+ def filesystem(self) -> _SandboxFilesystem:
1961
+ """Namespace for filesystem APIs."""
1962
+ if self._filesystem is None:
1963
+ self._filesystem = _SandboxFilesystem(self)
1964
+ return self._filesystem
1965
+
1922
1966
  async def wait(self, raise_on_termination: bool = True) -> None:
1923
1967
  if self._result is not None and self._result.status != api_pb2.GenericResult.GENERIC_STATUS_UNSPECIFIED:
1924
1968
  if self._result.status == api_pb2.GenericResult.GENERIC_STATUS_TERMINATED and raise_on_termination:
@@ -701,6 +701,7 @@ class _SandboxContainer:
701
701
  """Handle to an additional container running in a Sandbox."""
702
702
 
703
703
  _result: typing.Optional[modal_proto.api_pb2.GenericResult]
704
+ _filesystem: typing.Optional[modal.sandbox_fs._SandboxFilesystem]
704
705
 
705
706
  def __init__(
706
707
  self,
@@ -724,6 +725,7 @@ class _SandboxContainer:
724
725
  """Get task ID and command router client."""
725
726
  ...
726
727
 
728
+ @typing.overload
727
729
  async def exec(
728
730
  self,
729
731
  *args: str,
@@ -733,12 +735,29 @@ class _SandboxContainer:
733
735
  workdir: typing.Optional[str] = None,
734
736
  env: typing.Optional[dict[str, typing.Optional[str]]] = None,
735
737
  secrets: typing.Optional[collections.abc.Collection[modal.secret._Secret]] = None,
736
- text: bool = True,
738
+ text: typing.Literal[True] = True,
739
+ bufsize: typing.Literal[-1, 1] = -1,
740
+ pty: bool = False,
741
+ ) -> modal.container_process._ContainerProcess[str]: ...
742
+ @typing.overload
743
+ async def exec(
744
+ self,
745
+ *args: str,
746
+ stdout: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
747
+ stderr: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
748
+ timeout: typing.Optional[int] = None,
749
+ workdir: typing.Optional[str] = None,
750
+ env: typing.Optional[dict[str, typing.Optional[str]]] = None,
751
+ secrets: typing.Optional[collections.abc.Collection[modal.secret._Secret]] = None,
752
+ text: typing.Literal[False],
737
753
  bufsize: typing.Literal[-1, 1] = -1,
738
754
  pty: bool = False,
739
- ) -> typing.Union[
740
- modal.container_process._ContainerProcess[bytes], modal.container_process._ContainerProcess[str]
741
- ]: ...
755
+ ) -> modal.container_process._ContainerProcess[bytes]: ...
756
+ @property
757
+ def filesystem(self) -> modal.sandbox_fs._SandboxFilesystem:
758
+ """Namespace for filesystem APIs."""
759
+ ...
760
+
742
761
  async def wait(self, raise_on_termination: bool = True) -> None: ...
743
762
  async def poll(self) -> typing.Optional[int]: ...
744
763
  @typing.overload
@@ -772,6 +791,7 @@ class SandboxContainer:
772
791
  """Handle to an additional container running in a Sandbox."""
773
792
 
774
793
  _result: typing.Optional[modal_proto.api_pb2.GenericResult]
794
+ _filesystem: typing.Optional[modal.sandbox_fs.SandboxFilesystem]
775
795
 
776
796
  def __init__(
777
797
  self,
@@ -801,6 +821,7 @@ class SandboxContainer:
801
821
  _get_command_router: ___get_command_router_spec
802
822
 
803
823
  class __exec_spec(typing_extensions.Protocol):
824
+ @typing.overload
804
825
  def __call__(
805
826
  self,
806
827
  /,
@@ -811,12 +832,26 @@ class SandboxContainer:
811
832
  workdir: typing.Optional[str] = None,
812
833
  env: typing.Optional[dict[str, typing.Optional[str]]] = None,
813
834
  secrets: typing.Optional[collections.abc.Collection[modal.secret.Secret]] = None,
814
- text: bool = True,
835
+ text: typing.Literal[True] = True,
815
836
  bufsize: typing.Literal[-1, 1] = -1,
816
837
  pty: bool = False,
817
- ) -> typing.Union[
818
- modal.container_process.ContainerProcess[bytes], modal.container_process.ContainerProcess[str]
819
- ]: ...
838
+ ) -> modal.container_process.ContainerProcess[str]: ...
839
+ @typing.overload
840
+ def __call__(
841
+ self,
842
+ /,
843
+ *args: str,
844
+ stdout: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
845
+ stderr: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
846
+ timeout: typing.Optional[int] = None,
847
+ workdir: typing.Optional[str] = None,
848
+ env: typing.Optional[dict[str, typing.Optional[str]]] = None,
849
+ secrets: typing.Optional[collections.abc.Collection[modal.secret.Secret]] = None,
850
+ text: typing.Literal[False],
851
+ bufsize: typing.Literal[-1, 1] = -1,
852
+ pty: bool = False,
853
+ ) -> modal.container_process.ContainerProcess[bytes]: ...
854
+ @typing.overload
820
855
  async def aio(
821
856
  self,
822
857
  /,
@@ -827,15 +862,33 @@ class SandboxContainer:
827
862
  workdir: typing.Optional[str] = None,
828
863
  env: typing.Optional[dict[str, typing.Optional[str]]] = None,
829
864
  secrets: typing.Optional[collections.abc.Collection[modal.secret.Secret]] = None,
830
- text: bool = True,
865
+ text: typing.Literal[True] = True,
831
866
  bufsize: typing.Literal[-1, 1] = -1,
832
867
  pty: bool = False,
833
- ) -> typing.Union[
834
- modal.container_process.ContainerProcess[bytes], modal.container_process.ContainerProcess[str]
835
- ]: ...
868
+ ) -> modal.container_process.ContainerProcess[str]: ...
869
+ @typing.overload
870
+ async def aio(
871
+ self,
872
+ /,
873
+ *args: str,
874
+ stdout: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
875
+ stderr: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
876
+ timeout: typing.Optional[int] = None,
877
+ workdir: typing.Optional[str] = None,
878
+ env: typing.Optional[dict[str, typing.Optional[str]]] = None,
879
+ secrets: typing.Optional[collections.abc.Collection[modal.secret.Secret]] = None,
880
+ text: typing.Literal[False],
881
+ bufsize: typing.Literal[-1, 1] = -1,
882
+ pty: bool = False,
883
+ ) -> modal.container_process.ContainerProcess[bytes]: ...
836
884
 
837
885
  exec: __exec_spec
838
886
 
887
+ @property
888
+ def filesystem(self) -> modal.sandbox_fs.SandboxFilesystem:
889
+ """Namespace for filesystem APIs."""
890
+ ...
891
+
839
892
  class __wait_spec(typing_extensions.Protocol):
840
893
  def __call__(self, /, raise_on_termination: bool = True) -> None: ...
841
894
  async def aio(self, /, raise_on_termination: bool = True) -> None: ...
@@ -9,7 +9,10 @@ import time
9
9
  import weakref
10
10
  from dataclasses import dataclass
11
11
  from pathlib import Path
12
- from typing import Union, cast
12
+ from typing import TYPE_CHECKING, Union, cast
13
+
14
+ if TYPE_CHECKING:
15
+ import modal.sandbox
13
16
 
14
17
  from ._utils.async_utils import synchronize_api
15
18
  from ._utils.logger import logger
@@ -84,14 +87,14 @@ class _SandboxFilesystem:
84
87
  """mdmd:namespace
85
88
  Namespace for Sandbox filesystem APIs."""
86
89
 
87
- def __init__(self, sandbox):
90
+ _container: Union["modal.sandbox._Sandbox", "modal.sandbox._SandboxContainer"]
91
+
92
+ def __init__(self, container: Union["modal.sandbox._Sandbox", "modal.sandbox._SandboxContainer"]) -> None:
88
93
  """mdmd:hidden"""
89
- from modal.sandbox import _Sandbox
94
+ from modal.sandbox import _Sandbox, _SandboxContainer
90
95
 
91
- # inv type-stubs does not work with importing _Sandbox with TYPE_CHECKING,
92
- # so we'll use `cast` as a workaround.
93
- # Use a weakref proxy to avoid circular references between Sandbox and SandboxFilesystem.
94
- self._sandbox = cast(_Sandbox, weakref.proxy(sandbox))
96
+ # Use a weakref proxy to avoid circular references between Sandbox/SandboxContainer and SandboxFilesystem.
97
+ self._container = cast(Union[_Sandbox, _SandboxContainer], weakref.proxy(container))
95
98
 
96
99
  async def copy_from_local(self, local_path: Union[str, os.PathLike], remote_path: str) -> None:
97
100
  """Copy a local file into the Sandbox.
@@ -127,7 +130,7 @@ class _SandboxFilesystem:
127
130
  total_bytes = 0
128
131
  with open(local_path, "rb") as file_obj:
129
132
  with translate_exec_errors("copy_from_local", remote_path):
130
- process = await self._sandbox.exec(_SANDBOX_FS_TOOLS_PATH, make_write_file_command(remote_path))
133
+ process = await self._container.exec(_SANDBOX_FS_TOOLS_PATH, make_write_file_command(remote_path))
131
134
  try:
132
135
  while True:
133
136
  # TODO(saltzm): If this fails, the ContainerProcess will remain alive indefinitely since
@@ -190,7 +193,7 @@ class _SandboxFilesystem:
190
193
  t0 = time.monotonic()
191
194
  try:
192
195
  with translate_exec_errors("copy_to_local", remote_path):
193
- process = await self._sandbox.exec(
196
+ process = await self._container.exec(
194
197
  _SANDBOX_FS_TOOLS_PATH, make_read_file_command(remote_path), text=False
195
198
  )
196
199
 
@@ -243,7 +246,7 @@ class _SandboxFilesystem:
243
246
 
244
247
  t0 = time.monotonic()
245
248
  with translate_exec_errors("list_files", remote_path):
246
- process = await self._sandbox.exec(_SANDBOX_FS_TOOLS_PATH, make_list_files_command(remote_path))
249
+ process = await self._container.exec(_SANDBOX_FS_TOOLS_PATH, make_list_files_command(remote_path))
247
250
  stdout, stderr, returncode = await asyncio.gather(
248
251
  process.stdout.read(), process.stderr.read(), process.wait()
249
252
  )
@@ -299,7 +302,7 @@ class _SandboxFilesystem:
299
302
  validate_absolute_remote_path(remote_path, "make_directory")
300
303
 
301
304
  with translate_exec_errors("make_directory", remote_path):
302
- process = await self._sandbox.exec(
305
+ process = await self._container.exec(
303
306
  _SANDBOX_FS_TOOLS_PATH, make_make_directory_command(remote_path, create_parents)
304
307
  )
305
308
  stderr, returncode = await asyncio.gather(process.stderr.read(), process.wait())
@@ -331,7 +334,9 @@ class _SandboxFilesystem:
331
334
 
332
335
  t0 = time.monotonic()
333
336
  with translate_exec_errors("read_bytes", remote_path):
334
- process = await self._sandbox.exec(_SANDBOX_FS_TOOLS_PATH, make_read_file_command(remote_path), text=False)
337
+ process = await self._container.exec(
338
+ _SANDBOX_FS_TOOLS_PATH, make_read_file_command(remote_path), text=False
339
+ )
335
340
  stdout, stderr, returncode = await asyncio.gather(
336
341
  process.stdout.read(), process.stderr.read(), process.wait()
337
342
  )
@@ -367,7 +372,7 @@ class _SandboxFilesystem:
367
372
 
368
373
  t0 = time.monotonic()
369
374
  with translate_exec_errors("read_text", remote_path):
370
- process = await self._sandbox.exec(_SANDBOX_FS_TOOLS_PATH, make_read_file_command(remote_path))
375
+ process = await self._container.exec(_SANDBOX_FS_TOOLS_PATH, make_read_file_command(remote_path))
371
376
  stdout, stderr, returncode = await asyncio.gather(
372
377
  process.stdout.read(), process.stderr.read(), process.wait()
373
378
  )
@@ -421,7 +426,7 @@ class _SandboxFilesystem:
421
426
  validate_absolute_remote_path(remote_path, "remove")
422
427
 
423
428
  with translate_exec_errors("remove", remote_path):
424
- process = await self._sandbox.exec(_SANDBOX_FS_TOOLS_PATH, make_remove_command(remote_path, recursive))
429
+ process = await self._container.exec(_SANDBOX_FS_TOOLS_PATH, make_remove_command(remote_path, recursive))
425
430
  stderr, returncode = await asyncio.gather(process.stderr.read(), process.wait())
426
431
 
427
432
  if returncode != 0:
@@ -452,7 +457,7 @@ class _SandboxFilesystem:
452
457
 
453
458
  t0 = time.monotonic()
454
459
  with translate_exec_errors("stat", remote_path):
455
- process = await self._sandbox.exec(_SANDBOX_FS_TOOLS_PATH, make_stat_command(remote_path))
460
+ process = await self._container.exec(_SANDBOX_FS_TOOLS_PATH, make_stat_command(remote_path))
456
461
  stdout, stderr, returncode = await asyncio.gather(
457
462
  process.stdout.read(), process.stderr.read(), process.wait()
458
463
  )
@@ -504,7 +509,7 @@ class _SandboxFilesystem:
504
509
 
505
510
  t0 = time.monotonic()
506
511
  with translate_exec_errors("write_bytes", remote_path):
507
- process = await self._sandbox.exec(_SANDBOX_FS_TOOLS_PATH, make_write_file_command(remote_path))
512
+ process = await self._container.exec(_SANDBOX_FS_TOOLS_PATH, make_write_file_command(remote_path))
508
513
  try:
509
514
  for offset in range(0, max(len(data), 1), TASK_COMMAND_ROUTER_MAX_BUFFER_SIZE):
510
515
  process.stdin.write(data[offset : offset + TASK_COMMAND_ROUTER_MAX_BUFFER_SIZE])
@@ -1,4 +1,5 @@
1
1
  import enum
2
+ import modal.sandbox
2
3
  import os
3
4
  import typing
4
5
  import typing_extensions
@@ -78,7 +79,10 @@ class _SandboxFilesystem:
78
79
  """mdmd:namespace
79
80
  Namespace for Sandbox filesystem APIs.
80
81
  """
81
- def __init__(self, sandbox):
82
+
83
+ _container: typing.Union[modal.sandbox._Sandbox, modal.sandbox._SandboxContainer]
84
+
85
+ def __init__(self, container: typing.Union[modal.sandbox._Sandbox, modal.sandbox._SandboxContainer]) -> None:
82
86
  """mdmd:hidden"""
83
87
  ...
84
88
 
@@ -341,7 +345,10 @@ class SandboxFilesystem:
341
345
  """mdmd:namespace
342
346
  Namespace for Sandbox filesystem APIs.
343
347
  """
344
- def __init__(self, sandbox):
348
+
349
+ _container: typing.Union[modal.sandbox.Sandbox, modal.sandbox.SandboxContainer]
350
+
351
+ def __init__(self, container: typing.Union[modal.sandbox.Sandbox, modal.sandbox.SandboxContainer]) -> None:
345
352
  """mdmd:hidden"""
346
353
  ...
347
354
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.4.4.dev6
3
+ Version: 1.4.4.dev7
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License-Expression: Apache-2.0
@@ -1,4 +1,4 @@
1
1
  # Copyright Modal Labs 2026
2
2
  """Supplies the current version of the modal client library."""
3
3
 
4
- __version__ = "1.4.4.dev6"
4
+ __version__ = "1.4.4.dev7"
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