Files.com 2.0.9__tar.gz → 2.0.11__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. {files_com-2.0.9/files_com.egg-info → files_com-2.0.11}/PKG-INFO +1 -1
  2. {files_com-2.0.9 → files_com-2.0.11/files_com.egg-info}/PKG-INFO +1 -1
  3. {files_com-2.0.9 → files_com-2.0.11}/files_com.egg-info/SOURCES.txt +1 -0
  4. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/__init__.py +1 -1
  5. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/adaptive.py +9 -4
  6. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/checkpoint.py +18 -0
  7. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/jobs.py +17 -3
  8. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/file.py +11 -4
  9. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/upload.py +344 -87
  10. files_com-2.0.11/files_sdk/windows_file.py +544 -0
  11. {files_com-2.0.9 → files_com-2.0.11}/pyproject.toml +2 -2
  12. {files_com-2.0.9 → files_com-2.0.11}/LICENSE +0 -0
  13. {files_com-2.0.9 → files_com-2.0.11}/MANIFEST.in +0 -0
  14. {files_com-2.0.9 → files_com-2.0.11}/README.md +0 -0
  15. {files_com-2.0.9 → files_com-2.0.11}/files_com.egg-info/dependency_links.txt +0 -0
  16. {files_com-2.0.9 → files_com-2.0.11}/files_com.egg-info/requires.txt +0 -0
  17. {files_com-2.0.9 → files_com-2.0.11}/files_com.egg-info/top_level.txt +0 -0
  18. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/access.py +0 -0
  19. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/api.py +0 -0
  20. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/api_client.py +0 -0
  21. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/attachment.py +0 -0
  22. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/client.py +0 -0
  23. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/context.py +0 -0
  24. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/download.py +0 -0
  25. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/download_status.py +0 -0
  26. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/error.py +0 -0
  27. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/lifetime.py +0 -0
  28. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/list_obj.py +0 -0
  29. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/localfs.py +0 -0
  30. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/migration.py +0 -0
  31. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/__init__.py +0 -0
  32. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/account_line_item.py +0 -0
  33. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/action.py +0 -0
  34. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/action_log.py +0 -0
  35. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/action_notification_export.py +0 -0
  36. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/action_notification_export_result.py +0 -0
  37. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/agent_node.py +0 -0
  38. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/agent_node_connection.py +0 -0
  39. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/agent_node_instance.py +0 -0
  40. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/agent_push_update.py +0 -0
  41. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/ai_assistant_personality.py +0 -0
  42. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/ai_task.py +0 -0
  43. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/api_key.py +0 -0
  44. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/api_request_log.py +0 -0
  45. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/app.py +0 -0
  46. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/as2_incoming_message.py +0 -0
  47. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/as2_outgoing_message.py +0 -0
  48. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/as2_partner.py +0 -0
  49. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/as2_station.py +0 -0
  50. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/auto.py +0 -0
  51. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/automation.py +0 -0
  52. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/automation_authoring_schema.py +0 -0
  53. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/automation_execution_node.py +0 -0
  54. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/automation_log.py +0 -0
  55. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/automation_run.py +0 -0
  56. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/bandwidth_snapshot.py +0 -0
  57. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/behavior.py +0 -0
  58. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/bundle.py +0 -0
  59. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/bundle_action.py +0 -0
  60. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/bundle_download.py +0 -0
  61. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/bundle_notification.py +0 -0
  62. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/bundle_path.py +0 -0
  63. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/bundle_recipient.py +0 -0
  64. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/bundle_registration.py +0 -0
  65. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/chat_message.py +0 -0
  66. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/chat_session.py +0 -0
  67. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/child_site_management_policy.py +0 -0
  68. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/clickwrap.py +0 -0
  69. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/custom_domain.py +0 -0
  70. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/desktop_configuration_profile.py +0 -0
  71. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/direct_connection_info.py +0 -0
  72. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/dns_record.py +0 -0
  73. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/email_incoming_message.py +0 -0
  74. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/email_log.py +0 -0
  75. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/errors.py +0 -0
  76. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/event_channel.py +0 -0
  77. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/event_delivery_attempt.py +0 -0
  78. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/event_record.py +0 -0
  79. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/event_subscription.py +0 -0
  80. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/event_target.py +0 -0
  81. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/exavault_api_request_log.py +0 -0
  82. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/expectation.py +0 -0
  83. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/expectation_evaluation.py +0 -0
  84. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/expectation_incident.py +0 -0
  85. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/external_event.py +0 -0
  86. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/file_action.py +0 -0
  87. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/file_comment.py +0 -0
  88. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/file_comment_reaction.py +0 -0
  89. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/file_migration.py +0 -0
  90. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/file_migration_log.py +0 -0
  91. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/file_upload_part.py +0 -0
  92. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/folder.py +0 -0
  93. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/form_field.py +0 -0
  94. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/form_field_set.py +0 -0
  95. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/ftp_action_log.py +0 -0
  96. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/gpg_key.py +0 -0
  97. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/group.py +0 -0
  98. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/group_user.py +0 -0
  99. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/history.py +0 -0
  100. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/history_export.py +0 -0
  101. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/history_export_result.py +0 -0
  102. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/holiday_calendar.py +0 -0
  103. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/holiday_region.py +0 -0
  104. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/image.py +0 -0
  105. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/inbound_s3_log.py +0 -0
  106. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/inbox_recipient.py +0 -0
  107. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/inbox_registration.py +0 -0
  108. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/inbox_upload.py +0 -0
  109. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/integration_centric_profile.py +0 -0
  110. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/invoice.py +0 -0
  111. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/invoice_line_item.py +0 -0
  112. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/ip_address.py +0 -0
  113. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/key_lifecycle_rule.py +0 -0
  114. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/lock.py +0 -0
  115. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/metadata_category.py +0 -0
  116. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/notification.py +0 -0
  117. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/outbound_connection_log.py +0 -0
  118. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/partner.py +0 -0
  119. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/partner_channel.py +0 -0
  120. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/partner_channel_template.py +0 -0
  121. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/partner_connection.py +0 -0
  122. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/partner_site.py +0 -0
  123. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/partner_site_request.py +0 -0
  124. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/payment.py +0 -0
  125. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/payment_line_item.py +0 -0
  126. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/pending_work_event.py +0 -0
  127. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/permission.py +0 -0
  128. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/preview.py +0 -0
  129. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/public_hosting_request_log.py +0 -0
  130. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/public_ip_address.py +0 -0
  131. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/public_key.py +0 -0
  132. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/remote_bandwidth_snapshot.py +0 -0
  133. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/remote_mount_backend.py +0 -0
  134. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/remote_server.py +0 -0
  135. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/remote_server_configuration_file.py +0 -0
  136. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/remote_server_credential.py +0 -0
  137. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/request.py +0 -0
  138. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/restore.py +0 -0
  139. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/schedule.py +0 -0
  140. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/scheduled_export.py +0 -0
  141. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/scim_log.py +0 -0
  142. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/secret.py +0 -0
  143. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/session.py +0 -0
  144. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/settings_change.py +0 -0
  145. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/sftp_action_log.py +0 -0
  146. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/sftp_host_key.py +0 -0
  147. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/share_group.py +0 -0
  148. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/share_group_member.py +0 -0
  149. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/siem_http_destination.py +0 -0
  150. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/siem_http_destination_event.py +0 -0
  151. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/site.py +0 -0
  152. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/site_subdomain_redirect.py +0 -0
  153. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/snapshot.py +0 -0
  154. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/sso_event.py +0 -0
  155. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/sso_strategy.py +0 -0
  156. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/status.py +0 -0
  157. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/style.py +0 -0
  158. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/sync.py +0 -0
  159. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/sync_log.py +0 -0
  160. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/sync_run.py +0 -0
  161. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/sync_run_live_transfer.py +0 -0
  162. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/usage_by_top_level_dir.py +0 -0
  163. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/usage_daily_snapshot.py +0 -0
  164. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/usage_snapshot.py +0 -0
  165. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/user.py +0 -0
  166. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/user_additional_email_recipient.py +0 -0
  167. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/user_cipher_use.py +0 -0
  168. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/user_lifecycle_rule.py +0 -0
  169. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/user_request.py +0 -0
  170. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/user_security_event.py +0 -0
  171. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/user_sftp_client_use.py +0 -0
  172. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/web_dav_action_log.py +0 -0
  173. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/webhook_test.py +0 -0
  174. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/workspace.py +0 -0
  175. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/models/zip_list_entry.py +0 -0
  176. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/path_comparison.json +0 -0
  177. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/path_util.py +0 -0
  178. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/py.typed +0 -0
  179. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/region.py +0 -0
  180. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/transport.py +0 -0
  181. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/util.py +0 -0
  182. {files_com-2.0.9 → files_com-2.0.11}/files_sdk/writing.py +0 -0
  183. {files_com-2.0.9 → files_com-2.0.11}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: files_com
3
- Version: 2.0.9
3
+ Version: 2.0.11
4
4
  Summary: Python bindings for the Files.com API
5
5
  License-Expression: MIT
6
6
  Project-URL: Documentation, https://developers.files.com/python/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: files_com
3
- Version: 2.0.9
3
+ Version: 2.0.11
4
4
  Summary: Python bindings for the Files.com API
5
5
  License-Expression: MIT
6
6
  Project-URL: Documentation, https://developers.files.com/python/
@@ -31,6 +31,7 @@ files_sdk/region.py
31
31
  files_sdk/transport.py
32
32
  files_sdk/upload.py
33
33
  files_sdk/util.py
34
+ files_sdk/windows_file.py
34
35
  files_sdk/writing.py
35
36
  files_sdk/models/__init__.py
36
37
  files_sdk/models/account_line_item.py
@@ -479,7 +479,7 @@ source_ip = None
479
479
  workspace_id = None
480
480
  base_url = "https://app.files.com"
481
481
  base_path = "api/rest/v1"
482
- version = "2.0.9"
482
+ version = "2.0.11"
483
483
 
484
484
  __version__ = version
485
485
 
@@ -2129,7 +2129,10 @@ class UploadObservation:
2129
2129
  with the process's resources) or "finish" (details: the record of the
2130
2130
  whole upload, whatever its outcome, with the settings it used and the
2131
2131
  SDK and Python that ran it). elapsed counts seconds from the upload's
2132
- start; the counts are those at the moment observed. parts_in_progress
2132
+ start; target_concurrency and the counts are those when the observation
2133
+ is delivered, which for a decision can be after later decisions:
2134
+ decision_target_concurrency is the controller's target immediately after
2135
+ that decision, and None for every other kind. parts_in_progress
2133
2136
  counts the upload's parts handed to workers and not yet finished, which
2134
2137
  includes parts waiting to be sent again; attempts_in_progress counts the
2135
2138
  attempts its controller has on the network (for a job, all of its
@@ -2161,6 +2164,7 @@ class UploadObservation:
2161
2164
  shortfall: str | None = None
2162
2165
  queue_estimate: float | None = None
2163
2166
  attempts_in_progress: int | None = None
2167
+ decision_target_concurrency: int | None = None
2164
2168
 
2165
2169
 
2166
2170
  def process_resources() -> dict[str, float] | None:
@@ -2258,12 +2262,12 @@ class Observer:
2258
2262
 
2259
2263
  def poll(self):
2260
2264
  """Note the upload's state, as it goes and whenever a part starts or
2261
- ends, and deliver the decisions made since and a sample when one is
2262
- due."""
2265
+ ends, and deliver the decisions made since, each with the target it
2266
+ left, and a sample when one is due."""
2263
2267
  self._now()
2264
2268
  heard = self._heard
2265
2269
  while heard:
2266
- decision, _target, cooldown, epoch, shortfall, queue = (
2270
+ decision, target, cooldown, epoch, shortfall, queue = (
2267
2271
  heard.popleft()
2268
2272
  )
2269
2273
  self.decisions[decision] += 1
@@ -2274,6 +2278,7 @@ class Observer:
2274
2278
  epoch=epoch,
2275
2279
  shortfall=shortfall,
2276
2280
  queue_estimate=queue,
2281
+ decision_target_concurrency=target,
2277
2282
  )
2278
2283
  now = time.monotonic()
2279
2284
  if now - self.sampled_at >= _SAMPLE_INTERVAL:
@@ -623,6 +623,15 @@ class _Slot:
623
623
  self.job.pending.pop(self.name, None)
624
624
  self.job.dirty = True
625
625
 
626
+ def invalidate(self):
627
+ """Forget the file's state, on disk now: its transfer saw its source
628
+ change, so nothing of it may be resumed. The job's checkpoint is
629
+ saved without it, keeping every other file's."""
630
+ with self.job._state_lock:
631
+ self.job.pending.pop(self.name, None)
632
+ self.job.dirty = True
633
+ self.job.save_job(final=True)
634
+
626
635
 
627
636
  class _FileStore:
628
637
  """A CheckpointFile as a transfer's checkpoint: the state it held when
@@ -645,6 +654,15 @@ class _FileStore:
645
654
  def clear(self):
646
655
  self.checkpoint.clear()
647
656
 
657
+ def invalidate(self):
658
+ """Record, on disk now, that there is nothing to resume: the
659
+ transfer saw its source change, so what it recorded must not be
660
+ resumed. Saved in place rather than removed, since a removal can
661
+ leave the file there (_remove, on Windows); a later call finds no
662
+ state and starts again."""
663
+ self._state = None
664
+ self.checkpoint.save(None, True)
665
+
648
666
 
649
667
  def file_store(path, kind, key) -> tuple[CheckpointFile, _FileStore]:
650
668
  """Open the checkpoint at path for one transfer."""
@@ -651,12 +651,24 @@ def _remote_join(root, relative):
651
651
  )
652
652
 
653
653
 
654
+ def _entry_status(directory, name):
655
+ """The entry name in directory itself, never through a link, with the
656
+ device and inode its upload checks (a DirEntry's are zero on Windows);
657
+ or the error looking at it raised, as when it is gone since it was
658
+ listed, for it alone."""
659
+ try:
660
+ return directory.lstat(name)
661
+ except OSError as error:
662
+ return error
663
+
664
+
654
665
  def _local_items(tree, remote_root) -> Iterator[_Item]:
655
666
  """The files and empty folders under tree's directory, a directory at a
656
667
  time, in name order. Each directory is opened from the job's directory
657
668
  one folder at a time, never through a link; links and special files are
658
669
  skipped, not followed. Each file is uploaded only if it is still the
659
- file found here."""
670
+ file found here. An entry that cannot be looked at fails alone; a
671
+ folder that cannot be opened or listed fails as a whole."""
660
672
  stack: list[tuple[str, ...]] = [()]
661
673
  while stack:
662
674
  parts = stack.pop()
@@ -671,7 +683,7 @@ def _local_items(tree, remote_root) -> Iterator[_Item]:
671
683
  ) as scanner:
672
684
  entries = sorted(
673
685
  (
674
- (entry.name, entry.stat(follow_symlinks=False))
686
+ (entry.name, _entry_status(directory, entry.name))
675
687
  for entry in scanner
676
688
  ),
677
689
  key=lambda pair: pair[0],
@@ -699,7 +711,9 @@ def _local_items(tree, remote_root) -> Iterator[_Item]:
699
711
  )
700
712
  local = os.path.join(path, entry_name)
701
713
  remote = _remote_join(remote_root, name)
702
- if stat.S_ISLNK(found.st_mode):
714
+ if isinstance(found, OSError):
715
+ yield _Item("skip", name, local, remote, error=found)
716
+ elif stat.S_ISLNK(found.st_mode):
703
717
  yield _Item(
704
718
  "skip", name, local, remote, reason="symbolic link"
705
719
  )
@@ -2105,8 +2105,12 @@ class FileResource:
2105
2105
  adapts to how the upload is going, up to max_concurrency; tuning
2106
2106
  (an UploadTuning) changes how, or turns adapting off. progress, if
2107
2107
  given, is called on this thread with an UploadProgress as parts
2108
- arrive. The file must not change while it uploads: a change is
2109
- detected and fails the upload instead of completing it. One
2108
+ arrive. The file must not change while it uploads. The SDK checks
2109
+ it as it reads it and before completing the upload, by its size,
2110
+ times and identity and, on Windows, by Windows' notice of a write
2111
+ to a file on a local disk where Windows gives one, and a change it
2112
+ finds fails the upload instead of completing it; but no check finds
2113
+ every change. One
2110
2114
  operation covers every request of the upload, and the client's
2111
2115
  transfer_limiter bounds its parts in progress. params can set
2112
2116
  mkdir_parents, with_rename, buffered_upload, custom_metadata and
@@ -2114,8 +2118,11 @@ class FileResource:
2114
2118
 
2115
2119
  checkpoint, a local path, keeps what the upload has done so far, so
2116
2120
  that calling upload_file again with it resumes the upload if it
2117
- stopped; pause_token (a PauseToken) pauses it, raising
2118
- TransferPausedError once its parts in progress have finished."""
2121
+ stopped, while the file's size, times and identity are as they were,
2122
+ which cannot prove its bytes are; an upload that found the file
2123
+ changed keeps nothing to resume. pause_token (a PauseToken) pauses
2124
+ it, raising TransferPausedError once its parts in progress have
2125
+ finished."""
2119
2126
  operation = Operation.start(self._scope, options)
2120
2127
  operation.require_single_completion()
2121
2128
  if destination is None: