parsl 2025.9.22__tar.gz → 2025.9.29__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 parsl might be problematic. Click here for more details.

Files changed (467) hide show
  1. {parsl-2025.9.22/parsl.egg-info → parsl-2025.9.29}/PKG-INFO +3 -4
  2. {parsl-2025.9.22 → parsl-2025.9.29}/README.rst +5 -2
  3. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/benchmark/perf.py +22 -9
  4. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/dataflow/dflow.py +2 -3
  5. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/dataflow/memoization.py +9 -19
  6. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/high_throughput/executor.py +10 -7
  7. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/high_throughput/interchange.py +4 -3
  8. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/high_throughput/mpi_executor.py +1 -2
  9. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/high_throughput/mpi_resource_management.py +3 -4
  10. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/high_throughput/process_worker_pool.py +10 -2
  11. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/high_throughput/zmq_pipes.py +7 -24
  12. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/taskvine/executor.py +5 -1
  13. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/taskvine_ex.py +1 -1
  14. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_checkpointing/test_periodic.py +15 -9
  15. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_htex/test_interchange_exit_bad_registration.py +0 -1
  16. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_mpi_apps/test_mpi_scheduler.py +12 -12
  17. parsl-2025.9.29/parsl/tests/test_regression/test_3874.py +47 -0
  18. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/version.py +1 -1
  19. {parsl-2025.9.22 → parsl-2025.9.29/parsl.egg-info}/PKG-INFO +3 -4
  20. {parsl-2025.9.22 → parsl-2025.9.29}/parsl.egg-info/SOURCES.txt +1 -1
  21. {parsl-2025.9.22 → parsl-2025.9.29}/setup.py +1 -2
  22. parsl-2025.9.22/parsl/tests/configs/local_threads_checkpoint_periodic.py +0 -11
  23. {parsl-2025.9.22 → parsl-2025.9.29}/LICENSE +0 -0
  24. {parsl-2025.9.22 → parsl-2025.9.29}/MANIFEST.in +0 -0
  25. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/__init__.py +0 -0
  26. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/addresses.py +0 -0
  27. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/app/__init__.py +0 -0
  28. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/app/app.py +0 -0
  29. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/app/bash.py +0 -0
  30. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/app/errors.py +0 -0
  31. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/app/futures.py +0 -0
  32. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/app/python.py +0 -0
  33. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/benchmark/__init__.py +0 -0
  34. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/concurrent/__init__.py +0 -0
  35. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/config.py +0 -0
  36. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/configs/ASPIRE1.py +0 -0
  37. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/configs/Azure.py +0 -0
  38. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/configs/__init__.py +0 -0
  39. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/configs/anvil.py +0 -0
  40. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/configs/bridges.py +0 -0
  41. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/configs/cc_in2p3.py +0 -0
  42. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/configs/delta.py +0 -0
  43. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/configs/ec2.py +0 -0
  44. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/configs/expanse.py +0 -0
  45. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/configs/frontera.py +0 -0
  46. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/configs/gc_multisite.py +0 -0
  47. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/configs/gc_tutorial.py +0 -0
  48. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/configs/htex_local.py +0 -0
  49. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/configs/illinoiscluster.py +0 -0
  50. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/configs/improv.py +0 -0
  51. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/configs/kubernetes.py +0 -0
  52. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/configs/local_threads.py +0 -0
  53. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/configs/midway.py +0 -0
  54. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/configs/osg.py +0 -0
  55. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/configs/polaris.py +0 -0
  56. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/configs/stampede2.py +0 -0
  57. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/configs/summit.py +0 -0
  58. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/configs/toss3_llnl.py +0 -0
  59. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/configs/vineex_local.py +0 -0
  60. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/configs/wqex_local.py +0 -0
  61. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/curvezmq.py +0 -0
  62. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/data_provider/__init__.py +0 -0
  63. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/data_provider/data_manager.py +0 -0
  64. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/data_provider/file_noop.py +0 -0
  65. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/data_provider/files.py +0 -0
  66. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/data_provider/ftp.py +0 -0
  67. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/data_provider/globus.py +0 -0
  68. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/data_provider/http.py +0 -0
  69. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/data_provider/rsync.py +0 -0
  70. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/data_provider/staging.py +0 -0
  71. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/data_provider/zip.py +0 -0
  72. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/dataflow/__init__.py +0 -0
  73. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/dataflow/dependency_resolvers.py +0 -0
  74. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/dataflow/errors.py +0 -0
  75. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/dataflow/futures.py +0 -0
  76. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/dataflow/rundirs.py +0 -0
  77. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/dataflow/states.py +0 -0
  78. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/dataflow/taskrecord.py +0 -0
  79. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/errors.py +0 -0
  80. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/__init__.py +0 -0
  81. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/base.py +0 -0
  82. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/errors.py +0 -0
  83. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/execute_task.py +0 -0
  84. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/flux/__init__.py +0 -0
  85. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/flux/execute_parsl_task.py +0 -0
  86. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/flux/executor.py +0 -0
  87. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/flux/flux_instance_manager.py +0 -0
  88. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/globus_compute.py +0 -0
  89. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/high_throughput/__init__.py +0 -0
  90. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/high_throughput/errors.py +0 -0
  91. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/high_throughput/manager_record.py +0 -0
  92. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/high_throughput/manager_selector.py +0 -0
  93. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/high_throughput/monitoring_info.py +0 -0
  94. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/high_throughput/mpi_prefix_composer.py +0 -0
  95. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/high_throughput/probe.py +0 -0
  96. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/radical/__init__.py +0 -0
  97. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/radical/executor.py +0 -0
  98. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/radical/rpex_resources.py +0 -0
  99. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/radical/rpex_worker.py +0 -0
  100. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/status_handling.py +0 -0
  101. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/taskvine/__init__.py +0 -0
  102. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/taskvine/errors.py +0 -0
  103. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/taskvine/exec_parsl_function.py +0 -0
  104. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/taskvine/factory.py +0 -0
  105. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/taskvine/factory_config.py +0 -0
  106. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/taskvine/manager.py +0 -0
  107. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/taskvine/manager_config.py +0 -0
  108. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/taskvine/utils.py +0 -0
  109. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/threads.py +0 -0
  110. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/workqueue/__init__.py +0 -0
  111. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/workqueue/errors.py +0 -0
  112. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/workqueue/exec_parsl_function.py +0 -0
  113. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/workqueue/executor.py +0 -0
  114. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/workqueue/parsl_coprocess.py +0 -0
  115. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/executors/workqueue/parsl_coprocess_stub.py +0 -0
  116. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/jobs/__init__.py +0 -0
  117. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/jobs/error_handlers.py +0 -0
  118. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/jobs/errors.py +0 -0
  119. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/jobs/job_status_poller.py +0 -0
  120. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/jobs/states.py +0 -0
  121. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/jobs/strategy.py +0 -0
  122. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/launchers/__init__.py +0 -0
  123. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/launchers/base.py +0 -0
  124. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/launchers/errors.py +0 -0
  125. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/launchers/launchers.py +0 -0
  126. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/log_utils.py +0 -0
  127. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/__init__.py +0 -0
  128. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/db_manager.py +0 -0
  129. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/errors.py +0 -0
  130. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/message_type.py +0 -0
  131. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/monitoring.py +0 -0
  132. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/queries/__init__.py +0 -0
  133. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/queries/pandas.py +0 -0
  134. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/radios/__init__.py +0 -0
  135. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/radios/base.py +0 -0
  136. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/radios/filesystem.py +0 -0
  137. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/radios/filesystem_router.py +0 -0
  138. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/radios/htex.py +0 -0
  139. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/radios/multiprocessing.py +0 -0
  140. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/radios/udp.py +0 -0
  141. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/radios/udp_router.py +0 -0
  142. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/radios/zmq.py +0 -0
  143. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/radios/zmq_router.py +0 -0
  144. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/remote.py +0 -0
  145. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/types.py +0 -0
  146. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/visualization/__init__.py +0 -0
  147. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/visualization/app.py +0 -0
  148. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/visualization/models.py +0 -0
  149. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/visualization/plots/__init__.py +0 -0
  150. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/visualization/plots/default/__init__.py +0 -0
  151. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/visualization/plots/default/task_plots.py +0 -0
  152. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/visualization/plots/default/workflow_plots.py +0 -0
  153. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/visualization/plots/default/workflow_resource_plots.py +0 -0
  154. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/visualization/static/parsl-logo-white.png +0 -0
  155. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/visualization/static/parsl-monitor.css +0 -0
  156. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/visualization/templates/app.html +0 -0
  157. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/visualization/templates/dag.html +0 -0
  158. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/visualization/templates/error.html +0 -0
  159. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/visualization/templates/layout.html +0 -0
  160. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/visualization/templates/resource_usage.html +0 -0
  161. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/visualization/templates/task.html +0 -0
  162. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/visualization/templates/workflow.html +0 -0
  163. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/visualization/templates/workflows_summary.html +0 -0
  164. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/visualization/utils.py +0 -0
  165. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/visualization/version.py +0 -0
  166. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/monitoring/visualization/views.py +0 -0
  167. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/multiprocessing.py +0 -0
  168. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/process_loggers.py +0 -0
  169. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/__init__.py +0 -0
  170. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/aws/__init__.py +0 -0
  171. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/aws/aws.py +0 -0
  172. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/aws/template.py +0 -0
  173. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/azure/__init__.py +0 -0
  174. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/azure/azure.py +0 -0
  175. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/azure/template.py +0 -0
  176. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/base.py +0 -0
  177. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/cluster_provider.py +0 -0
  178. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/condor/__init__.py +0 -0
  179. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/condor/condor.py +0 -0
  180. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/condor/template.py +0 -0
  181. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/errors.py +0 -0
  182. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/googlecloud/__init__.py +0 -0
  183. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/googlecloud/googlecloud.py +0 -0
  184. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/grid_engine/__init__.py +0 -0
  185. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/grid_engine/grid_engine.py +0 -0
  186. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/grid_engine/template.py +0 -0
  187. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/kubernetes/__init__.py +0 -0
  188. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/kubernetes/kube.py +0 -0
  189. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/kubernetes/template.py +0 -0
  190. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/local/__init__.py +0 -0
  191. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/local/local.py +0 -0
  192. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/lsf/__init__.py +0 -0
  193. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/lsf/lsf.py +0 -0
  194. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/lsf/template.py +0 -0
  195. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/pbspro/__init__.py +0 -0
  196. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/pbspro/pbspro.py +0 -0
  197. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/pbspro/template.py +0 -0
  198. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/slurm/__init__.py +0 -0
  199. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/slurm/slurm.py +0 -0
  200. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/slurm/template.py +0 -0
  201. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/torque/__init__.py +0 -0
  202. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/torque/template.py +0 -0
  203. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/providers/torque/torque.py +0 -0
  204. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/py.typed +0 -0
  205. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/serialize/__init__.py +0 -0
  206. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/serialize/base.py +0 -0
  207. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/serialize/concretes.py +0 -0
  208. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/serialize/errors.py +0 -0
  209. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/serialize/facade.py +0 -0
  210. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/serialize/proxystore.py +0 -0
  211. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/__init__.py +0 -0
  212. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/callables_helper.py +0 -0
  213. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/__init__.py +0 -0
  214. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/azure_single_node.py +0 -0
  215. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/bluewaters.py +0 -0
  216. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/bridges.py +0 -0
  217. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/cc_in2p3.py +0 -0
  218. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/comet.py +0 -0
  219. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/ec2_single_node.py +0 -0
  220. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/ec2_spot.py +0 -0
  221. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/flux_local.py +0 -0
  222. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/frontera.py +0 -0
  223. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/globus_compute.py +0 -0
  224. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/htex_local.py +0 -0
  225. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/htex_local_alternate.py +0 -0
  226. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/htex_local_intask_staging.py +0 -0
  227. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/htex_local_rsync_staging.py +0 -0
  228. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/local_radical.py +0 -0
  229. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/local_radical_mpi.py +0 -0
  230. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/local_threads.py +0 -0
  231. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/local_threads_checkpoint.py +0 -0
  232. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/local_threads_checkpoint_dfk_exit.py +0 -0
  233. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/local_threads_checkpoint_task_exit.py +0 -0
  234. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/local_threads_ftp_in_task.py +0 -0
  235. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/local_threads_globus.py +0 -0
  236. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/local_threads_http_in_task.py +0 -0
  237. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/local_threads_no_cache.py +0 -0
  238. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/midway.py +0 -0
  239. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/nscc_singapore.py +0 -0
  240. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/osg_htex.py +0 -0
  241. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/petrelkube.py +0 -0
  242. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/slurm_local.py +0 -0
  243. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/summit.py +0 -0
  244. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/user_opts.py +0 -0
  245. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/configs/workqueue_ex.py +0 -0
  246. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/conftest.py +0 -0
  247. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/integration/__init__.py +0 -0
  248. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/integration/latency.py +0 -0
  249. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/integration/test_apps/__init__.py +0 -0
  250. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/integration/test_parsl_load_default_config.py +0 -0
  251. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/integration/test_stress/__init__.py +0 -0
  252. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/integration/test_stress/test_python_simple.py +0 -0
  253. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/integration/test_stress/test_python_threads.py +0 -0
  254. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/manual_tests/__init__.py +0 -0
  255. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/manual_tests/htex_local.py +0 -0
  256. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/manual_tests/test_basic.py +0 -0
  257. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/manual_tests/test_log_filter.py +0 -0
  258. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/manual_tests/test_memory_limits.py +0 -0
  259. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/manual_tests/test_regression_220.py +0 -0
  260. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/manual_tests/test_worker_count.py +0 -0
  261. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/site_tests/__init__.py +0 -0
  262. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/site_tests/site_config_selector.py +0 -0
  263. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/sites/__init__.py +0 -0
  264. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/sites/test_affinity.py +0 -0
  265. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/sites/test_concurrent.py +0 -0
  266. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/sites/test_dynamic_executor.py +0 -0
  267. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/sites/test_ec2.py +0 -0
  268. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/sites/test_launchers.py +0 -0
  269. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/sites/test_mpi/__init__.py +0 -0
  270. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/sites/test_worker_info.py +0 -0
  271. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_bash_apps/__init__.py +0 -0
  272. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_bash_apps/test_apptimeout.py +0 -0
  273. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_bash_apps/test_basic.py +0 -0
  274. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_bash_apps/test_error_codes.py +0 -0
  275. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_bash_apps/test_inputs_default.py +0 -0
  276. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_bash_apps/test_keyword_overlaps.py +0 -0
  277. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_bash_apps/test_kwarg_storage.py +0 -0
  278. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_bash_apps/test_memoize.py +0 -0
  279. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_bash_apps/test_memoize_ignore_args.py +0 -0
  280. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_bash_apps/test_memoize_ignore_args_regr.py +0 -0
  281. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_bash_apps/test_multiline.py +0 -0
  282. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_bash_apps/test_pipeline.py +0 -0
  283. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_bash_apps/test_std_uri.py +0 -0
  284. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_bash_apps/test_stdout.py +0 -0
  285. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_callables.py +0 -0
  286. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_checkpointing/__init__.py +0 -0
  287. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_checkpointing/test_python_checkpoint_1.py +0 -0
  288. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_checkpointing/test_python_checkpoint_2.py +0 -0
  289. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_checkpointing/test_regression_232.py +0 -0
  290. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_checkpointing/test_regression_233.py +0 -0
  291. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_checkpointing/test_regression_239.py +0 -0
  292. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_checkpointing/test_task_exit.py +0 -0
  293. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_curvezmq.py +0 -0
  294. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_docs/__init__.py +0 -0
  295. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_docs/test_from_slides.py +0 -0
  296. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_docs/test_kwargs.py +0 -0
  297. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_docs/test_tutorial_1.py +0 -0
  298. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_docs/test_workflow1.py +0 -0
  299. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_docs/test_workflow4.py +0 -0
  300. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_error_handling/__init__.py +0 -0
  301. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_error_handling/test_fail.py +0 -0
  302. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_error_handling/test_python_walltime.py +0 -0
  303. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_error_handling/test_resource_spec.py +0 -0
  304. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_error_handling/test_retries.py +0 -0
  305. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_error_handling/test_retry_handler.py +0 -0
  306. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_error_handling/test_retry_handler_failure.py +0 -0
  307. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_error_handling/test_serialization_fail.py +0 -0
  308. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_error_handling/test_wrap_with_logs.py +0 -0
  309. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_execute_task.py +0 -0
  310. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_flowcontrol/__init__.py +0 -0
  311. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_flux.py +0 -0
  312. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_htex/__init__.py +0 -0
  313. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_htex/test_basic.py +0 -0
  314. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_htex/test_block_manager_selector_unit.py +0 -0
  315. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_htex/test_command_client_timeout.py +0 -0
  316. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_htex/test_command_concurrency_regression_1321.py +0 -0
  317. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_htex/test_connected_blocks.py +0 -0
  318. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_htex/test_cpu_affinity_explicit.py +0 -0
  319. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_htex/test_disconnected_blocks.py +0 -0
  320. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_htex/test_disconnected_blocks_failing_provider.py +0 -0
  321. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_htex/test_drain.py +0 -0
  322. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_htex/test_htex.py +0 -0
  323. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_htex/test_manager_failure.py +0 -0
  324. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_htex/test_manager_selector_by_block.py +0 -0
  325. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_htex/test_managers_command.py +0 -0
  326. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_htex/test_missing_worker.py +0 -0
  327. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_htex/test_multiple_disconnected_blocks.py +0 -0
  328. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_htex/test_priority_queue.py +0 -0
  329. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_htex/test_resource_spec_validation.py +0 -0
  330. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_htex/test_worker_failure.py +0 -0
  331. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_htex/test_zmq_binding.py +0 -0
  332. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_monitoring/__init__.py +0 -0
  333. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_monitoring/test_app_names.py +0 -0
  334. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_monitoring/test_basic.py +0 -0
  335. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_monitoring/test_db_locks.py +0 -0
  336. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_monitoring/test_exit_helper.py +0 -0
  337. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_monitoring/test_htex_fuzz_zmq.py +0 -0
  338. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_monitoring/test_htex_init_blocks_vs_monitoring.py +0 -0
  339. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_monitoring/test_incomplete_futures.py +0 -0
  340. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_monitoring/test_memoization_representation.py +0 -0
  341. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_monitoring/test_radio_filesystem.py +0 -0
  342. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_monitoring/test_radio_multiprocessing.py +0 -0
  343. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_monitoring/test_radio_udp.py +0 -0
  344. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_monitoring/test_radio_zmq.py +0 -0
  345. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_monitoring/test_stdouterr.py +0 -0
  346. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_monitoring/test_viz_colouring.py +0 -0
  347. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_mpi_apps/__init__.py +0 -0
  348. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_mpi_apps/test_bad_mpi_config.py +0 -0
  349. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py +0 -0
  350. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_mpi_apps/test_mpi_prefix.py +0 -0
  351. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_mpi_apps/test_mpiex.py +0 -0
  352. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_mpi_apps/test_resource_spec.py +0 -0
  353. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_providers/__init__.py +0 -0
  354. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_providers/test_kubernetes_provider.py +0 -0
  355. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_providers/test_local_provider.py +0 -0
  356. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_providers/test_pbspro_template.py +0 -0
  357. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_providers/test_slurm_instantiate.py +0 -0
  358. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_providers/test_slurm_template.py +0 -0
  359. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_providers/test_submiterror_deprecation.py +0 -0
  360. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/__init__.py +0 -0
  361. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_arg_input_types.py +0 -0
  362. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_basic.py +0 -0
  363. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_context_manager.py +0 -0
  364. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_dep_standard_futures.py +0 -0
  365. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_dependencies.py +0 -0
  366. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_dependencies_deep.py +0 -0
  367. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_depfail_propagation.py +0 -0
  368. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_fail.py +0 -0
  369. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_fibonacci_iterative.py +0 -0
  370. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_fibonacci_recursive.py +0 -0
  371. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_futures.py +0 -0
  372. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_garbage_collect.py +0 -0
  373. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_import_fail.py +0 -0
  374. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_inputs_default.py +0 -0
  375. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_join.py +0 -0
  376. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_lifted.py +0 -0
  377. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_mapred.py +0 -0
  378. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_memoize_1.py +0 -0
  379. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_memoize_2.py +0 -0
  380. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_memoize_4.py +0 -0
  381. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_memoize_bad_id_for_memo.py +0 -0
  382. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_memoize_exception.py +0 -0
  383. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_memoize_ignore_args.py +0 -0
  384. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_memoize_joinapp.py +0 -0
  385. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_outputs.py +0 -0
  386. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_overview.py +0 -0
  387. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_pipeline.py +0 -0
  388. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_pluggable_future_resolution.py +0 -0
  389. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_simple.py +0 -0
  390. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_timeout.py +0 -0
  391. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_python_apps/test_type5.py +0 -0
  392. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_radical/__init__.py +0 -0
  393. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_radical/test_mpi_funcs.py +0 -0
  394. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_regression/__init__.py +0 -0
  395. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_regression/test_1480.py +0 -0
  396. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_regression/test_1606_wait_for_current_tasks.py +0 -0
  397. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_regression/test_1653.py +0 -0
  398. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_regression/test_221.py +0 -0
  399. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_regression/test_226.py +0 -0
  400. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_regression/test_2652.py +0 -0
  401. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_regression/test_69a.py +0 -0
  402. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_regression/test_97_parallelism_0.py +0 -0
  403. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_regression/test_98.py +0 -0
  404. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_scaling/__init__.py +0 -0
  405. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_scaling/test_block_error_handler.py +0 -0
  406. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_scaling/test_regression_1621.py +0 -0
  407. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_scaling/test_regression_3568_scaledown_vs_MISSING.py +0 -0
  408. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_scaling/test_regression_3696_oscillation.py +0 -0
  409. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_scaling/test_scale_down.py +0 -0
  410. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_scaling/test_scale_down_htex_auto_scale.py +0 -0
  411. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_scaling/test_scale_down_htex_unregistered.py +0 -0
  412. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_scaling/test_shutdown_scalein.py +0 -0
  413. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_scaling/test_worker_interchange_bad_messages_3262.py +0 -0
  414. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_serialization/__init__.py +0 -0
  415. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_serialization/test_2555_caching_deserializer.py +0 -0
  416. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_serialization/test_3495_deserialize_managerlost.py +0 -0
  417. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_serialization/test_basic.py +0 -0
  418. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_serialization/test_htex_code_cache.py +0 -0
  419. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_serialization/test_proxystore_configured.py +0 -0
  420. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_serialization/test_proxystore_impl.py +0 -0
  421. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_shutdown/__init__.py +0 -0
  422. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_shutdown/test_kill_monitoring.py +0 -0
  423. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_staging/__init__.py +0 -0
  424. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_staging/staging_provider.py +0 -0
  425. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_staging/test_1316.py +0 -0
  426. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_staging/test_docs_1.py +0 -0
  427. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_staging/test_docs_2.py +0 -0
  428. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_staging/test_elaborate_noop_file.py +0 -0
  429. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_staging/test_file.py +0 -0
  430. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_staging/test_file_apps.py +0 -0
  431. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_staging/test_file_staging.py +0 -0
  432. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_staging/test_output_chain_filenames.py +0 -0
  433. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_staging/test_staging_ftp.py +0 -0
  434. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_staging/test_staging_ftp_in_task.py +0 -0
  435. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_staging/test_staging_globus.py +0 -0
  436. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_staging/test_staging_https.py +0 -0
  437. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_staging/test_staging_stdout.py +0 -0
  438. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_staging/test_zip_in.py +0 -0
  439. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_staging/test_zip_out.py +0 -0
  440. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_staging/test_zip_to_zip.py +0 -0
  441. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_summary.py +0 -0
  442. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_thread_parallelism.py +0 -0
  443. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_threads/__init__.py +0 -0
  444. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_threads/test_configs.py +0 -0
  445. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_threads/test_lazy_errors.py +0 -0
  446. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_utils/__init__.py +0 -0
  447. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_utils/test_execute_wait.py +0 -0
  448. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_utils/test_logutils.py +0 -0
  449. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_utils/test_representation_mixin.py +0 -0
  450. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/test_utils/test_sanitize_dns.py +0 -0
  451. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/unit/__init__.py +0 -0
  452. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/unit/test_address.py +0 -0
  453. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/unit/test_file.py +0 -0
  454. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/unit/test_globus_compute_executor.py +0 -0
  455. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/unit/test_usage_tracking.py +0 -0
  456. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/tests/utils.py +0 -0
  457. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/usage_tracking/__init__.py +0 -0
  458. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/usage_tracking/api.py +0 -0
  459. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/usage_tracking/levels.py +0 -0
  460. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/usage_tracking/usage.py +0 -0
  461. {parsl-2025.9.22 → parsl-2025.9.29}/parsl/utils.py +0 -0
  462. {parsl-2025.9.22 → parsl-2025.9.29}/parsl.egg-info/dependency_links.txt +0 -0
  463. {parsl-2025.9.22 → parsl-2025.9.29}/parsl.egg-info/entry_points.txt +0 -0
  464. {parsl-2025.9.22 → parsl-2025.9.29}/parsl.egg-info/requires.txt +0 -0
  465. {parsl-2025.9.22 → parsl-2025.9.29}/parsl.egg-info/top_level.txt +0 -0
  466. {parsl-2025.9.22 → parsl-2025.9.29}/requirements.txt +0 -0
  467. {parsl-2025.9.22 → parsl-2025.9.29}/setup.cfg +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: parsl
3
- Version: 2025.9.22
3
+ Version: 2025.9.29
4
4
  Summary: Simple data dependent workflows in Python
5
5
  Home-page: https://github.com/Parsl/parsl
6
- Download-URL: https://github.com/Parsl/parsl/archive/2025.09.22.tar.gz
6
+ Download-URL: https://github.com/Parsl/parsl/archive/2025.09.29.tar.gz
7
7
  Author: The Parsl Team
8
8
  Author-email: parsl@googlegroups.com
9
9
  License: Apache 2.0
@@ -11,11 +11,10 @@ Keywords: Workflows,Scientific computing
11
11
  Classifier: Development Status :: 5 - Production/Stable
12
12
  Classifier: Intended Audience :: Developers
13
13
  Classifier: License :: OSI Approved :: Apache Software License
14
- Classifier: Programming Language :: Python :: 3.9
15
14
  Classifier: Programming Language :: Python :: 3.10
16
15
  Classifier: Programming Language :: Python :: 3.11
17
16
  Classifier: Programming Language :: Python :: 3.12
18
- Requires-Python: >=3.9.0
17
+ Requires-Python: >=3.10.0
19
18
  Provides-Extra: monitoring
20
19
  Provides-Extra: visualization
21
20
  Provides-Extra: aws
@@ -1,6 +1,6 @@
1
1
  Parsl - Parallel Scripting Library
2
2
  ==================================
3
- |licence| |docs| |NSF-1550588| |NSF-1550476| |NSF-1550562| |NSF-1550528| |NumFOCUS| |CZI-EOSS|
3
+ |licence| |docs| |NSF-1550588| |NSF-1550476| |NSF-1550562| |NSF-1550528| |NumFOCUS| |CZI-EOSS| |paper|
4
4
 
5
5
  Parsl extends parallelism in Python beyond a single computer.
6
6
 
@@ -67,6 +67,9 @@ then explore the `parallel computing patterns <https://parsl.readthedocs.io/en/s
67
67
  .. |NumFOCUS| image:: https://img.shields.io/badge/powered%20by-NumFOCUS-orange.svg?style=flat&colorA=E1523D&colorB=007D8A
68
68
  :target: https://numfocus.org
69
69
  :alt: Powered by NumFOCUS
70
+ .. |paper| image:: https://img.shields.io/badge/Software_DOI-10.1145/3307681.3325400-blue
71
+ :target: https://doi.org/10.1145/3307681.3325400
72
+ :alt: Conference proceedings paper
70
73
 
71
74
 
72
75
  Quickstart
@@ -120,7 +123,7 @@ For Developers
120
123
  Requirements
121
124
  ============
122
125
 
123
- Parsl is supported in Python 3.9+. Requirements can be found `here <requirements.txt>`_. Requirements for running tests can be found `here <test-requirements.txt>`_.
126
+ Parsl is supported in Python 3.10+. Requirements can be found `here <requirements.txt>`_. Requirements for running tests can be found `here <test-requirements.txt>`_.
124
127
 
125
128
  Code of Conduct
126
129
  ===============
@@ -2,32 +2,45 @@ import argparse
2
2
  import concurrent.futures
3
3
  import importlib
4
4
  import time
5
+ from typing import Any, Dict
5
6
 
6
7
  import parsl
8
+ from parsl.dataflow.dflow import DataFlowKernel
7
9
 
8
10
  min_iterations = 2
9
11
 
10
12
 
11
13
  # TODO: factor with conftest.py where this is copy/pasted from?
12
- def load_dfk_from_config(filename):
14
+ def load_dfk_from_config(filename: str) -> DataFlowKernel:
13
15
  spec = importlib.util.spec_from_file_location('', filename)
16
+
17
+ if spec is None:
18
+ raise RuntimeError("Could not import configuration")
19
+
20
+ module = importlib.util.module_from_spec(spec)
21
+
22
+ if spec.loader is None:
23
+ raise RuntimeError("Could not load configuration")
24
+
25
+ spec.loader.exec_module(module)
26
+
14
27
  module = importlib.util.module_from_spec(spec)
15
28
  spec.loader.exec_module(module)
16
29
 
17
30
  if hasattr(module, 'config'):
18
- parsl.load(module.config)
31
+ return parsl.load(module.config)
19
32
  elif hasattr(module, 'fresh_config'):
20
- parsl.load(module.fresh_config())
33
+ return parsl.load(module.fresh_config())
21
34
  else:
22
35
  raise RuntimeError("Config module does not define config or fresh_config")
23
36
 
24
37
 
25
38
  @parsl.python_app
26
- def app(extra_payload, parsl_resource_specification={}):
39
+ def app(extra_payload: Any, parsl_resource_specification: Dict = {}) -> int:
27
40
  return 7
28
41
 
29
42
 
30
- def performance(*, resources: dict, target_t: float, args_extra_size: int):
43
+ def performance(*, resources: dict, target_t: float, args_extra_size: int) -> None:
31
44
  n = 10
32
45
 
33
46
  delta_t: float
@@ -82,6 +95,7 @@ Example usage: python -m parsl.benchmark.perf --config parsl/tests/configs/workq
82
95
  parser.add_argument("--resources", metavar="EXPR", help="parsl_resource_specification dictionary")
83
96
  parser.add_argument("--time", metavar="SECONDS", help="target number of seconds for an iteration", default=120, type=float)
84
97
  parser.add_argument("--argsize", metavar="BYTES", help="extra bytes to add into app invocation arguments", default=0, type=int)
98
+ parser.add_argument("--version", action="version", version=f"parsl-perf from Parsl {parsl.__version__}")
85
99
 
86
100
  args = parser.parse_args()
87
101
 
@@ -90,10 +104,9 @@ Example usage: python -m parsl.benchmark.perf --config parsl/tests/configs/workq
90
104
  else:
91
105
  resources = {}
92
106
 
93
- load_dfk_from_config(args.config)
94
- performance(resources=resources, target_t=args.time, args_extra_size=args.argsize)
95
- print("Cleaning up DFK")
96
- parsl.dfk().cleanup()
107
+ with load_dfk_from_config(args.config):
108
+ performance(resources=resources, target_t=args.time, args_extra_size=args.argsize)
109
+ print("Tests complete - leaving DFK block")
97
110
  print("The end")
98
111
 
99
112
 
@@ -175,7 +175,7 @@ class DataFlowKernel:
175
175
  else:
176
176
  checkpoint_files = []
177
177
 
178
- self.memoizer = Memoizer(self, memoize=config.app_cache, checkpoint_files=checkpoint_files)
178
+ self.memoizer = Memoizer(memoize=config.app_cache, checkpoint_files=checkpoint_files)
179
179
  self.checkpointed_tasks = 0
180
180
  self._checkpoint_timer = None
181
181
  self.checkpoint_mode = config.checkpoint_mode
@@ -561,7 +561,7 @@ class DataFlowKernel:
561
561
  if not task_record['app_fu'] == future:
562
562
  logger.error("Internal consistency error: callback future is not the app_fu in task structure, for task {}".format(task_id))
563
563
 
564
- self.memoizer.update_memo(task_record, future)
564
+ self.memoizer.update_memo(task_record)
565
565
 
566
566
  # Cover all checkpointing cases here:
567
567
  # Do we need to checkpoint now, or queue for later,
@@ -1202,7 +1202,6 @@ class DataFlowKernel:
1202
1202
 
1203
1203
  self.log_task_states()
1204
1204
 
1205
- # Checkpointing takes priority over the rest of the tasks
1206
1205
  # checkpoint if any valid checkpoint method is specified
1207
1206
  if self.checkpoint_mode is not None:
1208
1207
  self.checkpoint()
@@ -4,20 +4,16 @@ import hashlib
4
4
  import logging
5
5
  import os
6
6
  import pickle
7
+ import types
8
+ from concurrent.futures import Future
7
9
  from functools import lru_cache, singledispatch
8
- from typing import TYPE_CHECKING, Any, Dict, List, Optional, Sequence
10
+ from typing import Any, Dict, List, Optional, Sequence
9
11
 
10
12
  import typeguard
11
13
 
12
14
  from parsl.dataflow.errors import BadCheckpoint
13
15
  from parsl.dataflow.taskrecord import TaskRecord
14
16
 
15
- if TYPE_CHECKING:
16
- from parsl import DataFlowKernel # import loop at runtime - needed for typechecking - TODO turn into "if typing:"
17
-
18
- import types
19
- from concurrent.futures import Future
20
-
21
17
  logger = logging.getLogger(__name__)
22
18
 
23
19
 
@@ -150,17 +146,13 @@ class Memoizer:
150
146
 
151
147
  """
152
148
 
153
- def __init__(self, dfk: DataFlowKernel, *, memoize: bool = True, checkpoint_files: Sequence[str]):
149
+ def __init__(self, *, memoize: bool = True, checkpoint_files: Sequence[str]):
154
150
  """Initialize the memoizer.
155
151
 
156
- Args:
157
- - dfk (DFK obj): The DFK object
158
-
159
152
  KWargs:
160
153
  - memoize (Bool): enable memoization or not.
161
154
  - checkpoint (Dict): A checkpoint loaded as a dict.
162
155
  """
163
- self.dfk = dfk
164
156
  self.memoize = memoize
165
157
 
166
158
  checkpoint = self.load_checkpoints(checkpoint_files)
@@ -242,16 +234,14 @@ class Memoizer:
242
234
  assert isinstance(result, Future) or result is None
243
235
  return result
244
236
 
245
- def update_memo(self, task: TaskRecord, r: Future[Any]) -> None:
237
+ def update_memo(self, task: TaskRecord) -> None:
246
238
  """Updates the memoization lookup table with the result from a task.
239
+ This doesn't move any values around but associates the memoization
240
+ hashsum with the completed (by success or failure) AppFuture.
247
241
 
248
242
  Args:
249
- - task (dict) : A task dict from dfk.tasks
250
- - r (Result future): Result future
243
+ - task (TaskRecord) : A task record from dfk.tasks
251
244
  """
252
- # TODO: could use typeguard
253
- assert isinstance(r, Future)
254
-
255
245
  task_id = task['id']
256
246
 
257
247
  if not self.memoize or not task['memoize'] or 'hashsum' not in task:
@@ -265,7 +255,7 @@ class Memoizer:
265
255
  logger.info(f"Replacing app cache entry {task['hashsum']} with result from task {task_id}")
266
256
  else:
267
257
  logger.debug(f"Storing app cache entry {task['hashsum']} with result from task {task_id}")
268
- self.memo_lookup_table[task['hashsum']] = r
258
+ self.memo_lookup_table[task['hashsum']] = task['app_fu']
269
259
 
270
260
  def _load_checkpoints(self, checkpointDirs: Sequence[str]) -> Dict[str, Future[Any]]:
271
261
  """Load a checkpoint file into a lookup table.
@@ -237,7 +237,7 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageIn
237
237
  @typeguard.typechecked
238
238
  def __init__(self,
239
239
  label: str = 'HighThroughputExecutor',
240
- provider: ExecutionProvider = LocalProvider(),
240
+ provider: Optional[ExecutionProvider] = None,
241
241
  launch_cmd: Optional[str] = None,
242
242
  interchange_launch_cmd: Optional[Sequence[str]] = None,
243
243
  address: Optional[str] = None,
@@ -267,7 +267,9 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageIn
267
267
 
268
268
  logger.debug("Initializing HighThroughputExecutor")
269
269
 
270
- BlockProviderExecutor.__init__(self, provider=provider, block_error_handler=block_error_handler)
270
+ BlockProviderExecutor.__init__(self,
271
+ provider=provider if provider else LocalProvider(),
272
+ block_error_handler=block_error_handler)
271
273
  self.label = label
272
274
  self.worker_debug = worker_debug
273
275
  self.storage_access = storage_access
@@ -501,10 +503,7 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageIn
501
503
  else:
502
504
 
503
505
  for serialized_msg in msgs:
504
- try:
505
- msg = pickle.loads(serialized_msg)
506
- except pickle.UnpicklingError:
507
- raise BadMessage("Message received could not be unpickled")
506
+ msg = pickle.loads(serialized_msg)
508
507
 
509
508
  if msg['type'] == 'result':
510
509
  try:
@@ -712,7 +711,11 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageIn
712
711
  except TypeError:
713
712
  raise SerializationError(func.__name__)
714
713
 
715
- msg = {"task_id": task_id, "resource_spec": resource_specification, "buffer": fn_buf}
714
+ context = {}
715
+ if resource_specification:
716
+ context["resource_spec"] = resource_specification
717
+
718
+ msg = {"task_id": task_id, "context": context, "buffer": fn_buf}
716
719
 
717
720
  # Post task to the outgoing queue
718
721
  self.outgoing_q.put(msg)
@@ -332,7 +332,7 @@ class Interchange:
332
332
  msg = self.task_incoming.recv_pyobj()
333
333
 
334
334
  # Process priority, higher number = lower priority
335
- resource_spec = msg.get('resource_spec', {})
335
+ resource_spec = msg['context'].get('resource_spec', {})
336
336
  priority = resource_spec.get('priority', float('inf'))
337
337
  queue_entry = (-priority, -self.task_counter, msg)
338
338
 
@@ -360,9 +360,10 @@ class Interchange:
360
360
  mtype = meta['type']
361
361
  except Exception as e:
362
362
  logger.warning(
363
- f'Failed to read manager message ([{type(e).__name__}] {e})'
363
+ 'Failed to read manager message; ignoring message'
364
+ f' (Exception: [{type(e).__name__}] {e})'
364
365
  )
365
- logger.debug('Message:\n %r\n', msg_parts, exc_info=e)
366
+ logger.debug('Raw message bytes:\n %r\n', msg_parts, exc_info=e)
366
367
  return
367
368
 
368
369
  logger.debug(
@@ -16,7 +16,6 @@ from parsl.executors.status_handling import BlockProviderExecutor
16
16
  from parsl.jobs.states import JobStatus
17
17
  from parsl.launchers import SimpleLauncher
18
18
  from parsl.monitoring.radios.base import RadioConfig
19
- from parsl.providers import LocalProvider
20
19
  from parsl.providers.base import ExecutionProvider
21
20
 
22
21
 
@@ -47,7 +46,7 @@ class MPIExecutor(HighThroughputExecutor):
47
46
  @typeguard.typechecked
48
47
  def __init__(self,
49
48
  label: str = 'MPIExecutor',
50
- provider: ExecutionProvider = LocalProvider(),
49
+ provider: Optional[ExecutionProvider] = None,
51
50
  launch_cmd: Optional[str] = None,
52
51
  interchange_launch_cmd: Optional[str] = None,
53
52
  address: Optional[str] = None,
@@ -166,11 +166,10 @@ class MPITaskScheduler(TaskScheduler):
166
166
 
167
167
  def put_task(self, task_package: dict):
168
168
  """Schedule task if resources are available otherwise backlog the task"""
169
- resource_spec = task_package.get("resource_spec", {})
169
+ resource_spec = task_package.get("context", {}).get("resource_spec", {})
170
170
 
171
- nodes_needed = resource_spec.get("num_nodes")
172
- tid = task_package["task_id"]
173
- if nodes_needed:
171
+ if nodes_needed := resource_spec.get("num_nodes"):
172
+ tid = task_package["task_id"]
174
173
  try:
175
174
  allocated_nodes = self._get_nodes(nodes_needed)
176
175
  except MPINodesUnavailable:
@@ -373,6 +373,8 @@ class Manager:
373
373
  if socks.get(ix_sock) == zmq.POLLIN:
374
374
  pkl_msg = ix_sock.recv()
375
375
  tasks = pickle.loads(pkl_msg)
376
+ del pkl_msg
377
+
376
378
  last_interchange_contact = time.time()
377
379
 
378
380
  if tasks == HEARTBEAT_CODE:
@@ -454,6 +456,7 @@ class Manager:
454
456
  'exception': serialize(RemoteExceptionWrapper(*sys.exc_info()))}
455
457
  pkl_package = pickle.dumps(result_package)
456
458
  self.pending_result_queue.put(pkl_package)
459
+ del pkl_package
457
460
  except KeyError:
458
461
  logger.info("Worker {} was not busy when it died".format(worker_id))
459
462
 
@@ -770,7 +773,10 @@ def worker(
770
773
  ready_worker_count.value -= 1
771
774
  worker_enqueued = False
772
775
 
773
- _init_mpi_env(mpi_launcher=mpi_launcher, resource_spec=req["resource_spec"])
776
+ ctxt = req["context"]
777
+ res_spec = ctxt.get("resource_spec", {})
778
+
779
+ _init_mpi_env(mpi_launcher=mpi_launcher, resource_spec=res_spec)
774
780
 
775
781
  try:
776
782
  result = execute_task(req['buffer'])
@@ -780,7 +786,8 @@ def worker(
780
786
  result_package = {'type': 'result', 'task_id': tid, 'exception': serialize(RemoteExceptionWrapper(*sys.exc_info()))}
781
787
  else:
782
788
  result_package = {'type': 'result', 'task_id': tid, 'result': serialized_result}
783
- # logger.debug("Result: {}".format(result))
789
+ del serialized_result
790
+ del req
784
791
 
785
792
  logger.info("Completed executor task {}".format(tid))
786
793
  try:
@@ -792,6 +799,7 @@ def worker(
792
799
  })
793
800
 
794
801
  result_queue.put(pkl_package)
802
+ del pkl_package, result_package
795
803
  tasks_in_progress.pop(worker_id)
796
804
  logger.info("All processing finished for executor task {}".format(tid))
797
805
 
@@ -136,30 +136,18 @@ class TasksOutgoing:
136
136
  self.port = self.zmq_socket.bind_to_random_port(tcp_url(ip_address),
137
137
  min_port=port_range[0],
138
138
  max_port=port_range[1])
139
- self.poller = zmq.Poller()
140
- self.poller.register(self.zmq_socket, zmq.POLLOUT)
141
139
 
142
140
  def put(self, message):
143
141
  """ This function needs to be fast at the same time aware of the possibility of
144
142
  ZMQ pipes overflowing.
145
143
 
146
- The timeout increases slowly if contention is detected on ZMQ pipes.
147
144
  We could set copy=False and get slightly better latency but this results
148
145
  in ZMQ sockets reaching a broken state once there are ~10k tasks in flight.
149
146
  This issue can be magnified if each the serialized buffer itself is larger.
150
147
  """
151
- timeout_ms = 1
152
- while True:
153
- socks = dict(self.poller.poll(timeout=timeout_ms))
154
- if self.zmq_socket in socks and socks[self.zmq_socket] == zmq.POLLOUT:
155
- # The copy option adds latency but reduces the risk of ZMQ overflow
156
- logger.debug("Sending TasksOutgoing message")
157
- self.zmq_socket.send_pyobj(message, copy=True)
158
- logger.debug("Sent TasksOutgoing message")
159
- return
160
- else:
161
- timeout_ms *= 2
162
- logger.debug("Not sending due to non-ready zmq pipe, timeout: {} ms".format(timeout_ms))
148
+ logger.debug("Sending TasksOutgoing message")
149
+ self.zmq_socket.send_pyobj(message)
150
+ logger.debug("Sent TasksOutgoing message")
163
151
 
164
152
  def close(self):
165
153
  self.zmq_socket.close()
@@ -192,20 +180,15 @@ class ResultsIncoming:
192
180
  self.port = self.results_receiver.bind_to_random_port(tcp_url(ip_address),
193
181
  min_port=port_range[0],
194
182
  max_port=port_range[1])
195
- self.poller = zmq.Poller()
196
- self.poller.register(self.results_receiver, zmq.POLLIN)
197
183
 
198
184
  def get(self, timeout_ms=None):
199
185
  """Get a message from the queue, returning None if timeout expires
200
186
  without a message. timeout is measured in milliseconds.
201
187
  """
202
- socks = dict(self.poller.poll(timeout=timeout_ms))
203
- if self.results_receiver in socks and socks[self.results_receiver] == zmq.POLLIN:
204
- m = self.results_receiver.recv_multipart()
205
- logger.debug("Received ResultsIncoming message")
206
- return m
207
- else:
208
- return None
188
+ if zmq.POLLIN == self.results_receiver.poll(timeout_ms, zmq.POLLIN):
189
+ logger.debug("Receiving ResultsIncoming multipart message")
190
+ return self.results_receiver.recv_multipart()
191
+ return None
209
192
 
210
193
  def close(self):
211
194
  self.results_receiver.close()
@@ -107,13 +107,17 @@ class TaskVineExecutor(BlockProviderExecutor, putils.RepresentationMixin):
107
107
  function_exec_mode: Union[Literal['regular'], Literal['serverless']] = 'regular',
108
108
  manager_config: TaskVineManagerConfig = TaskVineManagerConfig(),
109
109
  factory_config: TaskVineFactoryConfig = TaskVineFactoryConfig(),
110
- provider: Optional[ExecutionProvider] = LocalProvider(init_blocks=1),
110
+ provider: Optional[ExecutionProvider] = None,
111
111
  storage_access: Optional[List[Staging]] = None,
112
112
  remote_monitoring_radio: Optional[RadioConfig] = None):
113
113
 
114
114
  # Set worker launch option for this executor
115
115
  if worker_launch_method == 'factory' or worker_launch_method == 'manual':
116
116
  provider = None
117
+ elif worker_launch_method == 'provider' and provider is None:
118
+ # provider method chosen, but no explicit provider supplied to __init__
119
+ # so default to LocalProvider
120
+ provider = LocalProvider(init_blocks=1)
117
121
 
118
122
  # Initialize the parent class with the execution provider and block error handling enabled.
119
123
  # If provider is None, then no worker is launched via the provider method.
@@ -7,4 +7,4 @@ from parsl.executors.taskvine import TaskVineExecutor, TaskVineManagerConfig
7
7
 
8
8
  def fresh_config():
9
9
  return Config(executors=[TaskVineExecutor(manager_config=TaskVineManagerConfig(port=9000),
10
- worker_launch_method='factory')])
10
+ worker_launch_method='provider')])
@@ -2,11 +2,17 @@ import pytest
2
2
 
3
3
  import parsl
4
4
  from parsl.app.app import python_app
5
- from parsl.tests.configs.local_threads_checkpoint_periodic import fresh_config
5
+ from parsl.config import Config
6
+ from parsl.executors.threads import ThreadPoolExecutor
6
7
 
7
8
 
8
- def local_setup():
9
- parsl.load(fresh_config())
9
+ def fresh_config():
10
+ tpe = ThreadPoolExecutor(label='local_threads_checkpoint_periodic', max_threads=1)
11
+ return Config(
12
+ executors=[tpe],
13
+ checkpoint_mode='periodic',
14
+ checkpoint_period='00:00:02'
15
+ )
10
16
 
11
17
 
12
18
  @python_app(cache=True)
@@ -25,12 +31,12 @@ def tstamp_to_seconds(line):
25
31
  def test_periodic():
26
32
  """Test checkpointing with task_periodic behavior
27
33
  """
28
- h, m, s = map(int, parsl.dfk().config.checkpoint_period.split(":"))
29
- assert h == 0, "Verify test setup"
30
- assert m == 0, "Verify test setup"
31
- assert s > 0, "Verify test setup"
32
- sleep_for = s + 1
33
- with parsl.dfk():
34
+ with parsl.load(fresh_config()):
35
+ h, m, s = map(int, parsl.dfk().config.checkpoint_period.split(":"))
36
+ assert h == 0, "Verify test setup"
37
+ assert m == 0, "Verify test setup"
38
+ assert s > 0, "Verify test setup"
39
+ sleep_for = s + 1
34
40
  futs = [slow_double(sleep_for) for _ in range(4)]
35
41
  [f.result() for f in futs]
36
42
  run_dir = parsl.dfk().run_dir
@@ -1,4 +1,3 @@
1
- import json
2
1
  import logging
3
2
  import os
4
3
  import pickle
@@ -43,8 +43,8 @@ def test_MPISched_put_task():
43
43
  assert len(scheduler.available_nodes) == 8
44
44
  assert scheduler._free_node_counter.value == 8
45
45
 
46
- res_spec = {"num_nodes": 2, "ranks_per_node": 2}
47
- task_package = {"task_id": 1, "buffer": mock_task_buffer, "resource_spec": res_spec}
46
+ ctxt = {"resource_spec": {"num_nodes": 2, "ranks_per_node": 2}}
47
+ task_package = {"task_id": 1, "buffer": mock_task_buffer, "context": ctxt}
48
48
  scheduler.put_task(task_package)
49
49
 
50
50
  assert scheduler._free_node_counter.value == 6
@@ -82,8 +82,8 @@ def test_MPISched_roundtrip():
82
82
  for trip in range(1, 9):
83
83
  assert scheduler._free_node_counter.value == 8
84
84
 
85
- res_spec = {"num_nodes": trip, "ranks_per_node": 2}
86
- task_package = {"task_id": trip, "buffer": mock_task_buffer, "resource_spec": res_spec}
85
+ ctxt = {"resource_spec": {"num_nodes": trip, "ranks_per_node": 2}}
86
+ task_package = {"task_id": trip, "buffer": mock_task_buffer, "context": ctxt}
87
87
  scheduler.put_task(task_package)
88
88
 
89
89
  assert scheduler._free_node_counter.value == 8 - trip
@@ -107,15 +107,15 @@ def test_MPISched_contention():
107
107
 
108
108
  assert scheduler._free_node_counter.value == 8
109
109
 
110
- rspec_1 = {"num_nodes": 8, "ranks_per_node": 2}
111
- task_package = {"task_id": 1, "buffer": mock_task_buffer, "resource_spec": rspec_1}
110
+ ctxt_1 = {"resource_spec": {"num_nodes": 8, "ranks_per_node": 2}}
111
+ task_package = {"task_id": 1, "buffer": mock_task_buffer, "context": ctxt_1}
112
112
  scheduler.put_task(task_package)
113
113
 
114
114
  assert scheduler._free_node_counter.value == 0
115
115
  assert scheduler._backlog_queue.empty()
116
116
 
117
- rspec_2 = {"num_nodes": 8, "ranks_per_node": 2}
118
- task_package = {"task_id": 2, "buffer": mock_task_buffer, "resource_spec": rspec_2}
117
+ ctxt_2 = {"resource_spec": {"num_nodes": 8, "ranks_per_node": 2}}
118
+ task_package = {"task_id": 2, "buffer": mock_task_buffer, "context": ctxt_2}
119
119
  scheduler.put_task(task_package)
120
120
 
121
121
  # Second task should now be in the backlog_queue
@@ -124,7 +124,7 @@ def test_MPISched_contention():
124
124
  # Confirm that the first task is available and has all 8 nodes provisioned
125
125
  task_on_worker_side = task_q.get()
126
126
  assert task_on_worker_side['task_id'] == 1
127
- assert len(rspec_1["MPI_NODELIST"].split(",")) == 8
127
+ assert len(ctxt_1["resource_spec"]["MPI_NODELIST"].split(",")) == 8
128
128
  assert task_q.empty() # Confirm that task 2 is not yet scheduled
129
129
 
130
130
  # Simulate worker returning result and the scheduler picking up result
@@ -139,7 +139,7 @@ def test_MPISched_contention():
139
139
  # Pop in a mock result
140
140
  task_on_worker_side = task_q.get()
141
141
  assert task_on_worker_side['task_id'] == 2
142
- assert len(rspec_2["MPI_NODELIST"].split(",")) == 8
142
+ assert len(ctxt_2["resource_spec"]["MPI_NODELIST"].split(",")) == 8
143
143
 
144
144
 
145
145
  @pytest.mark.local
@@ -157,7 +157,7 @@ def test_hashable_backlog_queue():
157
157
  assert scheduler._free_node_counter.value == 8
158
158
 
159
159
  for i in range(3):
160
- res_spec = {"num_nodes": 8, "ranks_per_node": 2}
161
- task_package = {"task_id": i, "buffer": mock_task_buffer, "resource_spec": res_spec}
160
+ ctxt = {"resource_spec": {"num_nodes": 8, "ranks_per_node": 2}}
161
+ task_package = {"task_id": i, "buffer": mock_task_buffer, "context": ctxt}
162
162
  scheduler.put_task(task_package)
163
163
  assert scheduler._backlog_queue.qsize() == 2, "Expected 2 backlogged tasks"
@@ -0,0 +1,47 @@
1
+ import shutil
2
+
3
+ import pytest
4
+
5
+ import parsl
6
+ from parsl.app.app import python_app
7
+ from parsl.config import Config
8
+ from parsl.executors import HighThroughputExecutor
9
+
10
+
11
+ @python_app
12
+ def noop():
13
+ pass
14
+
15
+
16
+ @pytest.mark.local
17
+ def test_regression_3874(tmpd_cwd_session):
18
+ # HTEX run 1
19
+
20
+ rundir_1 = str(tmpd_cwd_session / "1")
21
+
22
+ config = Config(executors=[HighThroughputExecutor()], strategy_period=0.5)
23
+ config.run_dir = rundir_1
24
+
25
+ with parsl.load(config):
26
+ noop().result()
27
+
28
+ # It is necessary to delete this rundir to exercise the bug. Otherwise,
29
+ # the next run will be able to continue looking at this directory - the
30
+ # bug manifests when it cannot.
31
+
32
+ shutil.rmtree(rundir_1)
33
+
34
+ # HTEX run 2
35
+ # In the case of issue 3874, this run hangs (rather than failing) as the
36
+ # JobStatusPoller fails to collect status of all of its managed tasks
37
+ # every iteration, without converging towards failure.
38
+
39
+ rundir_2 = str(tmpd_cwd_session / "2")
40
+
41
+ config = Config(executors=[HighThroughputExecutor()], strategy_period=0.5)
42
+ config.run_dir = rundir_2
43
+
44
+ with parsl.load(config):
45
+ noop().result()
46
+
47
+ shutil.rmtree(rundir_2)
@@ -3,4 +3,4 @@
3
3
  Year.Month.Day[alpha/beta/..]
4
4
  Alphas will be numbered like this -> 2024.12.10a0
5
5
  """
6
- VERSION = '2025.09.22'
6
+ VERSION = '2025.09.29'
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: parsl
3
- Version: 2025.9.22
3
+ Version: 2025.9.29
4
4
  Summary: Simple data dependent workflows in Python
5
5
  Home-page: https://github.com/Parsl/parsl
6
- Download-URL: https://github.com/Parsl/parsl/archive/2025.09.22.tar.gz
6
+ Download-URL: https://github.com/Parsl/parsl/archive/2025.09.29.tar.gz
7
7
  Author: The Parsl Team
8
8
  Author-email: parsl@googlegroups.com
9
9
  License: Apache 2.0
@@ -11,11 +11,10 @@ Keywords: Workflows,Scientific computing
11
11
  Classifier: Development Status :: 5 - Production/Stable
12
12
  Classifier: Intended Audience :: Developers
13
13
  Classifier: License :: OSI Approved :: Apache Software License
14
- Classifier: Programming Language :: Python :: 3.9
15
14
  Classifier: Programming Language :: Python :: 3.10
16
15
  Classifier: Programming Language :: Python :: 3.11
17
16
  Classifier: Programming Language :: Python :: 3.12
18
- Requires-Python: >=3.9.0
17
+ Requires-Python: >=3.10.0
19
18
  Provides-Extra: monitoring
20
19
  Provides-Extra: visualization
21
20
  Provides-Extra: aws