parsl 2025.1.13__tar.gz → 2025.1.20__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 (472) hide show
  1. {parsl-2025.1.13/parsl.egg-info → parsl-2025.1.20}/PKG-INFO +3 -2
  2. parsl-2025.1.20/parsl/configs/gc_multisite.py +27 -0
  3. parsl-2025.1.20/parsl/configs/gc_tutorial.py +18 -0
  4. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/dataflow/dflow.py +17 -22
  5. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/dataflow/taskrecord.py +1 -3
  6. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/__init__.py +3 -1
  7. parsl-2025.1.20/parsl/executors/globus_compute.py +125 -0
  8. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/high_throughput/errors.py +1 -1
  9. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/high_throughput/executor.py +2 -4
  10. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/high_throughput/zmq_pipes.py +0 -1
  11. parsl-2025.1.20/parsl/tests/configs/globus_compute.py +20 -0
  12. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/conftest.py +4 -0
  13. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_error_handling/test_resource_spec.py +3 -0
  14. parsl-2025.1.20/parsl/tests/test_htex/test_interchange_exit_bad_registration.py +120 -0
  15. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_htex/test_resource_spec_validation.py +0 -7
  16. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_dep_standard_futures.py +3 -0
  17. parsl-2025.1.20/parsl/tests/test_python_apps/test_fail.py +52 -0
  18. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_join.py +6 -0
  19. parsl-2025.1.20/parsl/tests/unit/test_globus_compute_executor.py +104 -0
  20. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/usage_tracking/usage.py +13 -8
  21. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/version.py +1 -1
  22. {parsl-2025.1.13 → parsl-2025.1.20/parsl.egg-info}/PKG-INFO +3 -2
  23. {parsl-2025.1.13 → parsl-2025.1.20}/parsl.egg-info/SOURCES.txt +6 -0
  24. {parsl-2025.1.13 → parsl-2025.1.20}/parsl.egg-info/requires.txt +4 -0
  25. {parsl-2025.1.13 → parsl-2025.1.20}/setup.py +1 -0
  26. parsl-2025.1.13/parsl/tests/test_python_apps/test_fail.py +0 -43
  27. {parsl-2025.1.13 → parsl-2025.1.20}/LICENSE +0 -0
  28. {parsl-2025.1.13 → parsl-2025.1.20}/MANIFEST.in +0 -0
  29. {parsl-2025.1.13 → parsl-2025.1.20}/README.rst +0 -0
  30. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/__init__.py +0 -0
  31. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/addresses.py +0 -0
  32. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/app/__init__.py +0 -0
  33. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/app/app.py +0 -0
  34. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/app/bash.py +0 -0
  35. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/app/errors.py +0 -0
  36. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/app/futures.py +0 -0
  37. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/app/python.py +0 -0
  38. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/benchmark/__init__.py +0 -0
  39. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/benchmark/perf.py +0 -0
  40. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/concurrent/__init__.py +0 -0
  41. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/config.py +0 -0
  42. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/configs/ASPIRE1.py +0 -0
  43. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/configs/Azure.py +0 -0
  44. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/configs/__init__.py +0 -0
  45. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/configs/bridges.py +0 -0
  46. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/configs/cc_in2p3.py +0 -0
  47. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/configs/ec2.py +0 -0
  48. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/configs/expanse.py +0 -0
  49. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/configs/frontera.py +0 -0
  50. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/configs/htex_local.py +0 -0
  51. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/configs/illinoiscluster.py +0 -0
  52. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/configs/improv.py +0 -0
  53. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/configs/kubernetes.py +0 -0
  54. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/configs/local_threads.py +0 -0
  55. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/configs/midway.py +0 -0
  56. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/configs/osg.py +0 -0
  57. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/configs/polaris.py +0 -0
  58. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/configs/stampede2.py +0 -0
  59. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/configs/summit.py +0 -0
  60. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/configs/toss3_llnl.py +0 -0
  61. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/configs/vineex_local.py +0 -0
  62. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/configs/wqex_local.py +0 -0
  63. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/curvezmq.py +0 -0
  64. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/data_provider/__init__.py +0 -0
  65. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/data_provider/data_manager.py +0 -0
  66. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/data_provider/file_noop.py +0 -0
  67. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/data_provider/files.py +0 -0
  68. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/data_provider/ftp.py +0 -0
  69. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/data_provider/globus.py +0 -0
  70. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/data_provider/http.py +0 -0
  71. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/data_provider/rsync.py +0 -0
  72. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/data_provider/staging.py +0 -0
  73. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/data_provider/zip.py +0 -0
  74. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/dataflow/__init__.py +0 -0
  75. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/dataflow/dependency_resolvers.py +0 -0
  76. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/dataflow/errors.py +0 -0
  77. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/dataflow/futures.py +0 -0
  78. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/dataflow/memoization.py +0 -0
  79. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/dataflow/rundirs.py +0 -0
  80. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/dataflow/states.py +0 -0
  81. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/errors.py +0 -0
  82. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/base.py +0 -0
  83. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/errors.py +0 -0
  84. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/execute_task.py +0 -0
  85. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/flux/__init__.py +0 -0
  86. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/flux/execute_parsl_task.py +0 -0
  87. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/flux/executor.py +0 -0
  88. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/flux/flux_instance_manager.py +0 -0
  89. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/high_throughput/__init__.py +0 -0
  90. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/high_throughput/interchange.py +0 -0
  91. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/high_throughput/manager_record.py +0 -0
  92. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/high_throughput/manager_selector.py +0 -0
  93. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/high_throughput/monitoring_info.py +0 -0
  94. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/high_throughput/mpi_executor.py +0 -0
  95. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/high_throughput/mpi_prefix_composer.py +0 -0
  96. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/high_throughput/mpi_resource_management.py +0 -0
  97. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/high_throughput/probe.py +0 -0
  98. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/high_throughput/process_worker_pool.py +0 -0
  99. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/radical/__init__.py +0 -0
  100. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/radical/executor.py +0 -0
  101. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/radical/rpex_resources.py +0 -0
  102. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/radical/rpex_worker.py +0 -0
  103. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/status_handling.py +0 -0
  104. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/taskvine/__init__.py +0 -0
  105. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/taskvine/errors.py +0 -0
  106. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/taskvine/exec_parsl_function.py +0 -0
  107. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/taskvine/executor.py +0 -0
  108. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/taskvine/factory.py +0 -0
  109. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/taskvine/factory_config.py +0 -0
  110. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/taskvine/manager.py +0 -0
  111. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/taskvine/manager_config.py +0 -0
  112. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/taskvine/utils.py +0 -0
  113. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/threads.py +0 -0
  114. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/workqueue/__init__.py +0 -0
  115. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/workqueue/errors.py +0 -0
  116. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/workqueue/exec_parsl_function.py +0 -0
  117. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/workqueue/executor.py +0 -0
  118. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/workqueue/parsl_coprocess.py +0 -0
  119. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/executors/workqueue/parsl_coprocess_stub.py +0 -0
  120. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/jobs/__init__.py +0 -0
  121. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/jobs/error_handlers.py +0 -0
  122. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/jobs/errors.py +0 -0
  123. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/jobs/job_status_poller.py +0 -0
  124. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/jobs/states.py +0 -0
  125. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/jobs/strategy.py +0 -0
  126. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/launchers/__init__.py +0 -0
  127. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/launchers/base.py +0 -0
  128. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/launchers/errors.py +0 -0
  129. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/launchers/launchers.py +0 -0
  130. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/log_utils.py +0 -0
  131. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/__init__.py +0 -0
  132. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/db_manager.py +0 -0
  133. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/errors.py +0 -0
  134. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/message_type.py +0 -0
  135. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/monitoring.py +0 -0
  136. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/queries/__init__.py +0 -0
  137. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/queries/pandas.py +0 -0
  138. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/radios/__init__.py +0 -0
  139. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/radios/base.py +0 -0
  140. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/radios/filesystem.py +0 -0
  141. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/radios/htex.py +0 -0
  142. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/radios/multiprocessing.py +0 -0
  143. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/radios/udp.py +0 -0
  144. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/radios/zmq.py +0 -0
  145. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/remote.py +0 -0
  146. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/router.py +0 -0
  147. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/types.py +0 -0
  148. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/visualization/__init__.py +0 -0
  149. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/visualization/app.py +0 -0
  150. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/visualization/models.py +0 -0
  151. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/visualization/plots/__init__.py +0 -0
  152. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/visualization/plots/default/__init__.py +0 -0
  153. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/visualization/plots/default/task_plots.py +0 -0
  154. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/visualization/plots/default/workflow_plots.py +0 -0
  155. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/visualization/plots/default/workflow_resource_plots.py +0 -0
  156. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/visualization/static/parsl-logo-white.png +0 -0
  157. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/visualization/static/parsl-monitor.css +0 -0
  158. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/visualization/templates/app.html +0 -0
  159. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/visualization/templates/dag.html +0 -0
  160. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/visualization/templates/error.html +0 -0
  161. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/visualization/templates/layout.html +0 -0
  162. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/visualization/templates/resource_usage.html +0 -0
  163. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/visualization/templates/task.html +0 -0
  164. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/visualization/templates/workflow.html +0 -0
  165. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/visualization/templates/workflows_summary.html +0 -0
  166. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/visualization/utils.py +0 -0
  167. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/visualization/version.py +0 -0
  168. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/monitoring/visualization/views.py +0 -0
  169. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/multiprocessing.py +0 -0
  170. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/process_loggers.py +0 -0
  171. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/__init__.py +0 -0
  172. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/aws/__init__.py +0 -0
  173. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/aws/aws.py +0 -0
  174. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/aws/template.py +0 -0
  175. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/azure/__init__.py +0 -0
  176. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/azure/azure.py +0 -0
  177. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/azure/template.py +0 -0
  178. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/base.py +0 -0
  179. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/cluster_provider.py +0 -0
  180. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/condor/__init__.py +0 -0
  181. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/condor/condor.py +0 -0
  182. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/condor/template.py +0 -0
  183. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/errors.py +0 -0
  184. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/googlecloud/__init__.py +0 -0
  185. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/googlecloud/googlecloud.py +0 -0
  186. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/grid_engine/__init__.py +0 -0
  187. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/grid_engine/grid_engine.py +0 -0
  188. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/grid_engine/template.py +0 -0
  189. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/kubernetes/__init__.py +0 -0
  190. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/kubernetes/kube.py +0 -0
  191. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/kubernetes/template.py +0 -0
  192. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/local/__init__.py +0 -0
  193. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/local/local.py +0 -0
  194. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/lsf/__init__.py +0 -0
  195. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/lsf/lsf.py +0 -0
  196. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/lsf/template.py +0 -0
  197. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/pbspro/__init__.py +0 -0
  198. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/pbspro/pbspro.py +0 -0
  199. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/pbspro/template.py +0 -0
  200. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/slurm/__init__.py +0 -0
  201. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/slurm/slurm.py +0 -0
  202. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/slurm/template.py +0 -0
  203. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/torque/__init__.py +0 -0
  204. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/torque/template.py +0 -0
  205. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/providers/torque/torque.py +0 -0
  206. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/py.typed +0 -0
  207. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/serialize/__init__.py +0 -0
  208. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/serialize/base.py +0 -0
  209. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/serialize/concretes.py +0 -0
  210. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/serialize/errors.py +0 -0
  211. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/serialize/facade.py +0 -0
  212. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/serialize/proxystore.py +0 -0
  213. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/__init__.py +0 -0
  214. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/callables_helper.py +0 -0
  215. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/__init__.py +0 -0
  216. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/azure_single_node.py +0 -0
  217. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/bluewaters.py +0 -0
  218. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/bridges.py +0 -0
  219. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/cc_in2p3.py +0 -0
  220. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/comet.py +0 -0
  221. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/ec2_single_node.py +0 -0
  222. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/ec2_spot.py +0 -0
  223. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/flux_local.py +0 -0
  224. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/frontera.py +0 -0
  225. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/htex_local.py +0 -0
  226. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/htex_local_alternate.py +0 -0
  227. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/htex_local_intask_staging.py +0 -0
  228. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/htex_local_rsync_staging.py +0 -0
  229. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/local_radical.py +0 -0
  230. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/local_radical_mpi.py +0 -0
  231. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/local_threads.py +0 -0
  232. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/local_threads_checkpoint.py +0 -0
  233. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/local_threads_checkpoint_dfk_exit.py +0 -0
  234. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/local_threads_checkpoint_periodic.py +0 -0
  235. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/local_threads_checkpoint_task_exit.py +0 -0
  236. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/local_threads_ftp_in_task.py +0 -0
  237. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/local_threads_globus.py +0 -0
  238. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/local_threads_http_in_task.py +0 -0
  239. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/local_threads_monitoring.py +0 -0
  240. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/local_threads_no_cache.py +0 -0
  241. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/midway.py +0 -0
  242. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/nscc_singapore.py +0 -0
  243. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/osg_htex.py +0 -0
  244. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/petrelkube.py +0 -0
  245. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/slurm_local.py +0 -0
  246. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/summit.py +0 -0
  247. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/taskvine_ex.py +0 -0
  248. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/user_opts.py +0 -0
  249. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/configs/workqueue_ex.py +0 -0
  250. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/integration/__init__.py +0 -0
  251. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/integration/latency.py +0 -0
  252. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/integration/test_apps/__init__.py +0 -0
  253. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/integration/test_parsl_load_default_config.py +0 -0
  254. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/integration/test_stress/__init__.py +0 -0
  255. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/integration/test_stress/test_python_simple.py +0 -0
  256. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/integration/test_stress/test_python_threads.py +0 -0
  257. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/manual_tests/__init__.py +0 -0
  258. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/manual_tests/htex_local.py +0 -0
  259. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/manual_tests/test_basic.py +0 -0
  260. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/manual_tests/test_log_filter.py +0 -0
  261. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/manual_tests/test_memory_limits.py +0 -0
  262. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/manual_tests/test_regression_220.py +0 -0
  263. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/manual_tests/test_udp_simple.py +0 -0
  264. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/manual_tests/test_worker_count.py +0 -0
  265. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/scaling_tests/__init__.py +0 -0
  266. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/scaling_tests/htex_local.py +0 -0
  267. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/scaling_tests/local_threads.py +0 -0
  268. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/scaling_tests/test_scale.py +0 -0
  269. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/scaling_tests/vineex_condor.py +0 -0
  270. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/scaling_tests/vineex_local.py +0 -0
  271. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/scaling_tests/wqex_condor.py +0 -0
  272. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/scaling_tests/wqex_local.py +0 -0
  273. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/site_tests/__init__.py +0 -0
  274. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/site_tests/site_config_selector.py +0 -0
  275. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/site_tests/test_provider.py +0 -0
  276. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/site_tests/test_site.py +0 -0
  277. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/sites/__init__.py +0 -0
  278. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/sites/test_affinity.py +0 -0
  279. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/sites/test_concurrent.py +0 -0
  280. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/sites/test_dynamic_executor.py +0 -0
  281. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/sites/test_ec2.py +0 -0
  282. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/sites/test_launchers.py +0 -0
  283. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/sites/test_mpi/__init__.py +0 -0
  284. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/sites/test_worker_info.py +0 -0
  285. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_aalst_patterns.py +0 -0
  286. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_bash_apps/__init__.py +0 -0
  287. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_bash_apps/test_apptimeout.py +0 -0
  288. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_bash_apps/test_basic.py +0 -0
  289. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_bash_apps/test_error_codes.py +0 -0
  290. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_bash_apps/test_inputs_default.py +0 -0
  291. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_bash_apps/test_keyword_overlaps.py +0 -0
  292. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_bash_apps/test_kwarg_storage.py +0 -0
  293. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_bash_apps/test_memoize.py +0 -0
  294. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_bash_apps/test_memoize_ignore_args.py +0 -0
  295. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_bash_apps/test_memoize_ignore_args_regr.py +0 -0
  296. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_bash_apps/test_multiline.py +0 -0
  297. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_bash_apps/test_pipeline.py +0 -0
  298. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_bash_apps/test_std_uri.py +0 -0
  299. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_bash_apps/test_stdout.py +0 -0
  300. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_callables.py +0 -0
  301. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_checkpointing/__init__.py +0 -0
  302. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_checkpointing/test_periodic.py +0 -0
  303. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_checkpointing/test_python_checkpoint_1.py +0 -0
  304. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_checkpointing/test_python_checkpoint_2.py +0 -0
  305. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_checkpointing/test_python_checkpoint_3.py +0 -0
  306. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_checkpointing/test_regression_232.py +0 -0
  307. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_checkpointing/test_regression_233.py +0 -0
  308. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_checkpointing/test_regression_239.py +0 -0
  309. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_checkpointing/test_task_exit.py +0 -0
  310. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_curvezmq.py +0 -0
  311. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_docs/__init__.py +0 -0
  312. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_docs/test_from_slides.py +0 -0
  313. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_docs/test_kwargs.py +0 -0
  314. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_docs/test_tutorial_1.py +0 -0
  315. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_docs/test_workflow1.py +0 -0
  316. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_docs/test_workflow2.py +0 -0
  317. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_docs/test_workflow4.py +0 -0
  318. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_error_handling/__init__.py +0 -0
  319. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_error_handling/test_fail.py +0 -0
  320. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_error_handling/test_python_walltime.py +0 -0
  321. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_error_handling/test_rand_fail.py +0 -0
  322. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_error_handling/test_retries.py +0 -0
  323. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_error_handling/test_retry_handler.py +0 -0
  324. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_error_handling/test_retry_handler_failure.py +0 -0
  325. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_error_handling/test_serialization_fail.py +0 -0
  326. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_error_handling/test_wrap_with_logs.py +0 -0
  327. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_execute_task.py +0 -0
  328. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_flowcontrol/__init__.py +0 -0
  329. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_flux.py +0 -0
  330. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_htex/__init__.py +0 -0
  331. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_htex/test_basic.py +0 -0
  332. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_htex/test_block_manager_selector_unit.py +0 -0
  333. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_htex/test_command_client_timeout.py +0 -0
  334. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_htex/test_connected_blocks.py +0 -0
  335. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_htex/test_cpu_affinity_explicit.py +0 -0
  336. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_htex/test_disconnected_blocks.py +0 -0
  337. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_htex/test_disconnected_blocks_failing_provider.py +0 -0
  338. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_htex/test_drain.py +0 -0
  339. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_htex/test_htex.py +0 -0
  340. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_htex/test_manager_failure.py +0 -0
  341. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_htex/test_manager_selector_by_block.py +0 -0
  342. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_htex/test_managers_command.py +0 -0
  343. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_htex/test_missing_worker.py +0 -0
  344. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_htex/test_multiple_disconnected_blocks.py +0 -0
  345. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_htex/test_worker_failure.py +0 -0
  346. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_htex/test_zmq_binding.py +0 -0
  347. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_monitoring/__init__.py +0 -0
  348. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_monitoring/test_app_names.py +0 -0
  349. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_monitoring/test_basic.py +0 -0
  350. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_monitoring/test_db_locks.py +0 -0
  351. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_monitoring/test_fuzz_zmq.py +0 -0
  352. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_monitoring/test_htex_init_blocks_vs_monitoring.py +0 -0
  353. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_monitoring/test_incomplete_futures.py +0 -0
  354. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_monitoring/test_memoization_representation.py +0 -0
  355. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_monitoring/test_stdouterr.py +0 -0
  356. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_monitoring/test_viz_colouring.py +0 -0
  357. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_mpi_apps/__init__.py +0 -0
  358. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_mpi_apps/test_bad_mpi_config.py +0 -0
  359. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py +0 -0
  360. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_mpi_apps/test_mpi_prefix.py +0 -0
  361. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_mpi_apps/test_mpi_scheduler.py +0 -0
  362. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_mpi_apps/test_mpiex.py +0 -0
  363. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_mpi_apps/test_resource_spec.py +0 -0
  364. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_providers/__init__.py +0 -0
  365. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_providers/test_kubernetes_provider.py +0 -0
  366. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_providers/test_local_provider.py +0 -0
  367. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_providers/test_pbspro_template.py +0 -0
  368. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_providers/test_slurm_instantiate.py +0 -0
  369. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_providers/test_slurm_template.py +0 -0
  370. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_providers/test_submiterror_deprecation.py +0 -0
  371. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/__init__.py +0 -0
  372. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_arg_input_types.py +0 -0
  373. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_basic.py +0 -0
  374. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_context_manager.py +0 -0
  375. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_dependencies.py +0 -0
  376. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_dependencies_deep.py +0 -0
  377. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_depfail_propagation.py +0 -0
  378. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_fibonacci_iterative.py +0 -0
  379. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_fibonacci_recursive.py +0 -0
  380. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_futures.py +0 -0
  381. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_garbage_collect.py +0 -0
  382. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_import_fail.py +0 -0
  383. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_inputs_default.py +0 -0
  384. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_lifted.py +0 -0
  385. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_mapred.py +0 -0
  386. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_memoize_1.py +0 -0
  387. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_memoize_2.py +0 -0
  388. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_memoize_4.py +0 -0
  389. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_memoize_bad_id_for_memo.py +0 -0
  390. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_memoize_ignore_args.py +0 -0
  391. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_memoize_joinapp.py +0 -0
  392. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_outputs.py +0 -0
  393. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_overview.py +0 -0
  394. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_pipeline.py +0 -0
  395. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_pluggable_future_resolution.py +0 -0
  396. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_simple.py +0 -0
  397. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_timeout.py +0 -0
  398. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_python_apps/test_type5.py +0 -0
  399. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_radical/__init__.py +0 -0
  400. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_radical/test_mpi_funcs.py +0 -0
  401. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_regression/__init__.py +0 -0
  402. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_regression/test_1480.py +0 -0
  403. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_regression/test_1606_wait_for_current_tasks.py +0 -0
  404. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_regression/test_1653.py +0 -0
  405. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_regression/test_221.py +0 -0
  406. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_regression/test_226.py +0 -0
  407. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_regression/test_2652.py +0 -0
  408. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_regression/test_69a.py +0 -0
  409. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_regression/test_854.py +0 -0
  410. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_regression/test_97_parallelism_0.py +0 -0
  411. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_regression/test_98.py +0 -0
  412. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_scaling/__init__.py +0 -0
  413. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_scaling/test_block_error_handler.py +0 -0
  414. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_scaling/test_regression_1621.py +0 -0
  415. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_scaling/test_regression_3568_scaledown_vs_MISSING.py +0 -0
  416. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_scaling/test_regression_3696_oscillation.py +0 -0
  417. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_scaling/test_scale_down.py +0 -0
  418. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_scaling/test_scale_down_htex_auto_scale.py +0 -0
  419. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_scaling/test_scale_down_htex_unregistered.py +0 -0
  420. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_scaling/test_shutdown_scalein.py +0 -0
  421. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_scaling/test_worker_interchange_bad_messages_3262.py +0 -0
  422. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_serialization/__init__.py +0 -0
  423. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_serialization/test_2555_caching_deserializer.py +0 -0
  424. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_serialization/test_3495_deserialize_managerlost.py +0 -0
  425. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_serialization/test_basic.py +0 -0
  426. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_serialization/test_htex_code_cache.py +0 -0
  427. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_serialization/test_pack_resource_spec.py +0 -0
  428. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_serialization/test_proxystore_configured.py +0 -0
  429. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_serialization/test_proxystore_impl.py +0 -0
  430. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_shutdown/__init__.py +0 -0
  431. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_shutdown/test_kill_monitoring.py +0 -0
  432. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_staging/__init__.py +0 -0
  433. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_staging/staging_provider.py +0 -0
  434. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_staging/test_1316.py +0 -0
  435. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_staging/test_docs_1.py +0 -0
  436. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_staging/test_docs_2.py +0 -0
  437. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_staging/test_elaborate_noop_file.py +0 -0
  438. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_staging/test_file.py +0 -0
  439. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_staging/test_file_apps.py +0 -0
  440. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_staging/test_file_staging.py +0 -0
  441. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_staging/test_output_chain_filenames.py +0 -0
  442. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_staging/test_staging_ftp.py +0 -0
  443. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_staging/test_staging_ftp_in_task.py +0 -0
  444. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_staging/test_staging_globus.py +0 -0
  445. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_staging/test_staging_https.py +0 -0
  446. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_staging/test_staging_stdout.py +0 -0
  447. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_staging/test_zip_in.py +0 -0
  448. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_staging/test_zip_out.py +0 -0
  449. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_staging/test_zip_to_zip.py +0 -0
  450. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_summary.py +0 -0
  451. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_thread_parallelism.py +0 -0
  452. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_threads/__init__.py +0 -0
  453. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_threads/test_configs.py +0 -0
  454. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_threads/test_lazy_errors.py +0 -0
  455. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_utils/__init__.py +0 -0
  456. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_utils/test_execute_wait.py +0 -0
  457. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_utils/test_representation_mixin.py +0 -0
  458. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/test_utils/test_sanitize_dns.py +0 -0
  459. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/unit/__init__.py +0 -0
  460. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/unit/test_address.py +0 -0
  461. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/unit/test_file.py +0 -0
  462. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/unit/test_usage_tracking.py +0 -0
  463. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/tests/utils.py +0 -0
  464. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/usage_tracking/__init__.py +0 -0
  465. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/usage_tracking/api.py +0 -0
  466. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/usage_tracking/levels.py +0 -0
  467. {parsl-2025.1.13 → parsl-2025.1.20}/parsl/utils.py +0 -0
  468. {parsl-2025.1.13 → parsl-2025.1.20}/parsl.egg-info/dependency_links.txt +0 -0
  469. {parsl-2025.1.13 → parsl-2025.1.20}/parsl.egg-info/entry_points.txt +0 -0
  470. {parsl-2025.1.13 → parsl-2025.1.20}/parsl.egg-info/top_level.txt +0 -0
  471. {parsl-2025.1.13 → parsl-2025.1.20}/requirements.txt +0 -0
  472. {parsl-2025.1.13 → parsl-2025.1.20}/setup.cfg +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: parsl
3
- Version: 2025.1.13
3
+ Version: 2025.1.20
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.01.13.tar.gz
6
+ Download-URL: https://github.com/Parsl/parsl/archive/2025.01.20.tar.gz
7
7
  Author: The Parsl Team
8
8
  Author-email: parsl@googlegroups.com
9
9
  License: Apache 2.0
@@ -28,6 +28,7 @@ Provides-Extra: workqueue
28
28
  Provides-Extra: flux
29
29
  Provides-Extra: proxystore
30
30
  Provides-Extra: radical-pilot
31
+ Provides-Extra: globus_compute
31
32
  Provides-Extra: all
32
33
  License-File: LICENSE
33
34
 
@@ -0,0 +1,27 @@
1
+ from globus_compute_sdk import Executor
2
+
3
+ from parsl.config import Config
4
+ from parsl.executors import GlobusComputeExecutor
5
+ from parsl.usage_tracking.levels import LEVEL_1
6
+
7
+ # Please start your own endpoint on perlmutter following instructions below to use this config:
8
+ # https://globus-compute.readthedocs.io/en/stable/endpoints/endpoint_examples.html#perlmutter-nersc
9
+ perlmutter_endpoint = 'YOUR_PERLMUTTER_ENDPOINT_UUID'
10
+
11
+ # Please start your own endpoint on expanse following instructions below to use this config:
12
+ # https://globus-compute.readthedocs.io/en/stable/endpoints/endpoint_examples.html#expanse-sdsc
13
+ expanse_endpoint = 'YOUR_EXPANSE_ENDPOINT_UUID'
14
+
15
+ config = Config(
16
+ executors=[
17
+ GlobusComputeExecutor(
18
+ executor=Executor(endpoint_id=perlmutter_endpoint),
19
+ label="Perlmutter",
20
+ ),
21
+ GlobusComputeExecutor(
22
+ executor=Executor(endpoint_id=expanse_endpoint),
23
+ label="Expanse",
24
+ ),
25
+ ],
26
+ usage_tracking=LEVEL_1,
27
+ )
@@ -0,0 +1,18 @@
1
+ from globus_compute_sdk import Executor
2
+
3
+ from parsl.config import Config
4
+ from parsl.executors import GlobusComputeExecutor
5
+ from parsl.usage_tracking.levels import LEVEL_1
6
+
7
+ # Public tutorial endpoint
8
+ tutorial_endpoint = '4b116d3c-1703-4f8f-9f6f-39921e5864df'
9
+
10
+ config = Config(
11
+ executors=[
12
+ GlobusComputeExecutor(
13
+ executor=Executor(endpoint_id=tutorial_endpoint),
14
+ label="Tutorial_Endpoint_py3.11",
15
+ )
16
+ ],
17
+ usage_tracking=LEVEL_1,
18
+ )
@@ -484,24 +484,18 @@ class DataFlowKernel:
484
484
 
485
485
  # now we know each joinable Future is done
486
486
  # so now look for any exceptions
487
- exceptions_tids: List[Tuple[BaseException, Optional[str]]]
487
+ exceptions_tids: List[Tuple[BaseException, str]]
488
488
  exceptions_tids = []
489
489
  if isinstance(joinable, Future):
490
490
  je = joinable.exception()
491
491
  if je is not None:
492
- if hasattr(joinable, 'task_record'):
493
- tid = joinable.task_record['id']
494
- else:
495
- tid = None
492
+ tid = self.render_future_description(joinable)
496
493
  exceptions_tids = [(je, tid)]
497
494
  elif isinstance(joinable, list):
498
495
  for future in joinable:
499
496
  je = future.exception()
500
497
  if je is not None:
501
- if hasattr(joinable, 'task_record'):
502
- tid = joinable.task_record['id']
503
- else:
504
- tid = None
498
+ tid = self.render_future_description(future)
505
499
  exceptions_tids.append((je, tid))
506
500
  else:
507
501
  raise TypeError(f"Unknown joinable type {type(joinable)}")
@@ -918,13 +912,7 @@ class DataFlowKernel:
918
912
  dep_failures = []
919
913
 
920
914
  def append_failure(e: Exception, dep: Future) -> None:
921
- # If this Future is associated with a task inside this DFK,
922
- # then refer to the task ID.
923
- # Otherwise make a repr of the Future object.
924
- if hasattr(dep, 'task_record') and dep.task_record['dfk'] == self:
925
- tid = "task " + repr(dep.task_record['id'])
926
- else:
927
- tid = repr(dep)
915
+ tid = self.render_future_description(dep)
928
916
  dep_failures.extend([(e, tid)])
929
917
 
930
918
  # Replace item in args
@@ -1076,10 +1064,7 @@ class DataFlowKernel:
1076
1064
 
1077
1065
  depend_descs = []
1078
1066
  for d in depends:
1079
- if isinstance(d, AppFuture) or isinstance(d, DataFuture):
1080
- depend_descs.append("task {}".format(d.tid))
1081
- else:
1082
- depend_descs.append(repr(d))
1067
+ depend_descs.append(self.render_future_description(d))
1083
1068
 
1084
1069
  if depend_descs != []:
1085
1070
  waiting_message = "waiting on {}".format(", ".join(depend_descs))
@@ -1215,10 +1200,8 @@ class DataFlowKernel:
1215
1200
  self._checkpoint_timer.close()
1216
1201
 
1217
1202
  # Send final stats
1218
- logger.info("Sending end message for usage tracking")
1219
1203
  self.usage_tracker.send_end_message()
1220
1204
  self.usage_tracker.close()
1221
- logger.info("Closed usage tracking")
1222
1205
 
1223
1206
  logger.info("Closing job status poller")
1224
1207
  self.job_status_poller.close()
@@ -1438,6 +1421,18 @@ class DataFlowKernel:
1438
1421
  '' if label is None else '_{}'.format(label),
1439
1422
  kw))
1440
1423
 
1424
+ def render_future_description(self, dep: Future) -> str:
1425
+ """Renders a description of the future in the context of the
1426
+ current DFK.
1427
+ """
1428
+ if isinstance(dep, AppFuture) and dep.task_record['dfk'] == self:
1429
+ tid = "task " + repr(dep.task_record['id'])
1430
+ elif isinstance(dep, DataFuture):
1431
+ tid = "DataFuture from task " + repr(dep.tid)
1432
+ else:
1433
+ tid = repr(dep)
1434
+ return tid
1435
+
1441
1436
 
1442
1437
  class DataFlowKernelLoader:
1443
1438
  """Manage which DataFlowKernel is active.
@@ -43,12 +43,11 @@ class TaskRecord(TypedDict, total=False):
43
43
  executed on.
44
44
  """
45
45
 
46
- retries_left: int
47
46
  fail_count: int
48
47
  fail_cost: float
49
48
  fail_history: List[str]
50
49
 
51
- checkpoint: bool # this change is also in #1516
50
+ checkpoint: bool
52
51
  """Should this task be checkpointed?
53
52
  """
54
53
 
@@ -68,7 +67,6 @@ class TaskRecord(TypedDict, total=False):
68
67
 
69
68
  # these three could be more strongly typed perhaps but I'm not thinking about that now
70
69
  func: Callable
71
- fn_hash: str
72
70
  args: Sequence[Any]
73
71
  # in some places we uses a Tuple[Any, ...] and in some places a List[Any].
74
72
  # This is an attempt to correctly type both of those.
@@ -1,4 +1,5 @@
1
1
  from parsl.executors.flux.executor import FluxExecutor
2
+ from parsl.executors.globus_compute import GlobusComputeExecutor
2
3
  from parsl.executors.high_throughput.executor import HighThroughputExecutor
3
4
  from parsl.executors.high_throughput.mpi_executor import MPIExecutor
4
5
  from parsl.executors.threads import ThreadPoolExecutor
@@ -8,4 +9,5 @@ __all__ = ['ThreadPoolExecutor',
8
9
  'HighThroughputExecutor',
9
10
  'MPIExecutor',
10
11
  'WorkQueueExecutor',
11
- 'FluxExecutor']
12
+ 'FluxExecutor',
13
+ 'GlobusComputeExecutor']
@@ -0,0 +1,125 @@
1
+ from __future__ import annotations
2
+
3
+ import copy
4
+ from concurrent.futures import Future
5
+ from typing import Any, Callable, Dict
6
+
7
+ import typeguard
8
+
9
+ from parsl.errors import OptionalModuleMissing
10
+ from parsl.executors.base import ParslExecutor
11
+ from parsl.utils import RepresentationMixin
12
+
13
+ try:
14
+ from globus_compute_sdk import Executor
15
+ _globus_compute_enabled = True
16
+ except ImportError:
17
+ _globus_compute_enabled = False
18
+
19
+
20
+ class GlobusComputeExecutor(ParslExecutor, RepresentationMixin):
21
+ """ GlobusComputeExecutor enables remote execution on Globus Compute endpoints
22
+
23
+ GlobusComputeExecutor is a thin wrapper over globus_compute_sdk.Executor
24
+ Refer to `globus-compute user documentation <https://globus-compute.readthedocs.io/en/latest/executor.html>`_
25
+ and `reference documentation <https://globus-compute.readthedocs.io/en/latest/reference/executor.html>`_
26
+ for more details.
27
+
28
+ .. note::
29
+ As a remote execution system, Globus Compute relies on serialization to ship
30
+ tasks and results between the Parsl client side and the remote Globus Compute
31
+ Endpoint side. Serialization is unreliable across python versions, and
32
+ wrappers used by Parsl assume identical Parsl versions across on both sides.
33
+ We recommend using matching Python, Parsl and Globus Compute version on both
34
+ the client side and the endpoint side for stable behavior.
35
+
36
+ """
37
+
38
+ @typeguard.typechecked
39
+ def __init__(
40
+ self,
41
+ executor: Executor,
42
+ label: str = 'GlobusComputeExecutor',
43
+ ):
44
+ """
45
+ Parameters
46
+ ----------
47
+
48
+ executor: globus_compute_sdk.Executor
49
+ Pass a globus_compute_sdk Executor that will be used to execute
50
+ tasks on a globus_compute endpoint. Refer to `globus-compute docs
51
+ <https://globus-compute.readthedocs.io/en/latest/reference/executor.html#globus-compute-executor>`_
52
+
53
+ label:
54
+ a label to name the executor
55
+ """
56
+ if not _globus_compute_enabled:
57
+ raise OptionalModuleMissing(
58
+ ['globus-compute-sdk'],
59
+ "GlobusComputeExecutor requires globus-compute-sdk installed"
60
+ )
61
+
62
+ super().__init__()
63
+ self.executor: Executor = executor
64
+ self.resource_specification = self.executor.resource_specification
65
+ self.user_endpoint_config = self.executor.user_endpoint_config
66
+ self.label = label
67
+
68
+ def start(self) -> None:
69
+ """ Start the Globus Compute Executor """
70
+ pass
71
+
72
+ def submit(self, func: Callable, resource_specification: Dict[str, Any], *args: Any, **kwargs: Any) -> Future:
73
+ """ Submit func to globus-compute
74
+
75
+
76
+ Parameters
77
+ ----------
78
+
79
+ func: Callable
80
+ Python function to execute remotely
81
+
82
+ resource_specification: Dict[str, Any]
83
+ Resource specification can be used specify MPI resources required by MPI applications on
84
+ Endpoints configured to use globus compute's MPIEngine. GCE also accepts *user_endpoint_config*
85
+ to configure endpoints when the endpoint is a `Multi-User Endpoint
86
+ <https://globus-compute.readthedocs.io/en/latest/endpoints/endpoints.html#templating-endpoint-configuration>`_
87
+
88
+ args:
89
+ Args to pass to the function
90
+
91
+ kwargs:
92
+ kwargs to pass to the function
93
+
94
+ Returns
95
+ -------
96
+
97
+ Future
98
+ """
99
+ res_spec = copy.deepcopy(resource_specification or self.resource_specification)
100
+ # Pop user_endpoint_config since it is illegal in resource_spec for globus_compute
101
+ if res_spec:
102
+ user_endpoint_config = res_spec.pop('user_endpoint_config', self.user_endpoint_config)
103
+ else:
104
+ user_endpoint_config = self.user_endpoint_config
105
+
106
+ try:
107
+ self.executor.resource_specification = res_spec
108
+ self.executor.user_endpoint_config = user_endpoint_config
109
+ return self.executor.submit(func, *args, **kwargs)
110
+ finally:
111
+ # Reset executor state to defaults set at configuration time
112
+ self.executor.resource_specification = self.resource_specification
113
+ self.executor.user_endpoint_config = self.user_endpoint_config
114
+
115
+ def shutdown(self):
116
+ """Clean-up the resources associated with the Executor.
117
+
118
+ GCE.shutdown will cancel all futures that have not yet registered with
119
+ Globus Compute and will not wait for the launched futures to complete.
120
+ This method explicitly shutsdown the result_watcher thread to avoid
121
+ it waiting for outstanding futures at thread exit.
122
+ """
123
+ self.executor.shutdown(wait=False, cancel_futures=True)
124
+ result_watcher = self.executor._get_result_watcher()
125
+ result_watcher.shutdown(wait=False, cancel_futures=True)
@@ -27,7 +27,7 @@ class VersionMismatch(Exception):
27
27
  def __str__(self) -> str:
28
28
  return (
29
29
  f"Manager version info {self.manager_version} does not match interchange"
30
- f" version info {self.interchange_version}, causing a critical failure"
30
+ f" version info {self.interchange_version}"
31
31
  )
32
32
 
33
33
 
@@ -8,7 +8,7 @@ import warnings
8
8
  from collections import defaultdict
9
9
  from concurrent.futures import Future
10
10
  from dataclasses import dataclass
11
- from typing import Callable, Dict, List, Optional, Sequence, Tuple, Union
11
+ from typing import Callable, Dict, List, Optional, Sequence, Set, Tuple, Union
12
12
 
13
13
  import typeguard
14
14
 
@@ -357,10 +357,8 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageIn
357
357
  return self.logdir
358
358
 
359
359
  def validate_resource_spec(self, resource_specification: dict):
360
- """HTEX supports the following *Optional* resource specifications:
361
- priority: lower value is higher priority"""
362
360
  if resource_specification:
363
- acceptable_fields = {'priority'}
361
+ acceptable_fields: Set[str] = set() # add new resource spec field names here to make htex accept them
364
362
  keys = set(resource_specification.keys())
365
363
  invalid_keys = keys - acceptable_fields
366
364
  if invalid_keys:
@@ -213,7 +213,6 @@ class ResultsIncoming:
213
213
  """Get a message from the queue, returning None if timeout expires
214
214
  without a message. timeout is measured in milliseconds.
215
215
  """
216
- logger.debug("Waiting for ResultsIncoming message")
217
216
  socks = dict(self.poller.poll(timeout=timeout_ms))
218
217
  if self.results_receiver in socks and socks[self.results_receiver] == zmq.POLLIN:
219
218
  m = self.results_receiver.recv_multipart()
@@ -0,0 +1,20 @@
1
+ import os
2
+
3
+ from globus_compute_sdk import Executor
4
+
5
+ from parsl.config import Config
6
+ from parsl.executors import GlobusComputeExecutor
7
+
8
+
9
+ def fresh_config():
10
+
11
+ endpoint_id = os.environ["GLOBUS_COMPUTE_ENDPOINT"]
12
+
13
+ return Config(
14
+ executors=[
15
+ GlobusComputeExecutor(
16
+ executor=Executor(endpoint_id=endpoint_id),
17
+ label="globus_compute",
18
+ )
19
+ ]
20
+ )
@@ -163,6 +163,10 @@ def pytest_configure(config):
163
163
  'markers',
164
164
  'shared_fs: Marks tests that require a shared_fs between the workers are the test client'
165
165
  )
166
+ config.addinivalue_line(
167
+ 'markers',
168
+ 'issue_3620: Marks tests that do not work correctly on GlobusComputeExecutor (ref: issue 3620)'
169
+ )
166
170
 
167
171
 
168
172
  @pytest.fixture(autouse=True, scope='session')
@@ -1,3 +1,5 @@
1
+ import pytest
2
+
1
3
  import parsl
2
4
  from parsl.app.app import python_app
3
5
  from parsl.executors import WorkQueueExecutor
@@ -11,6 +13,7 @@ def double(x, parsl_resource_specification={}):
11
13
  return x * 2
12
14
 
13
15
 
16
+ @pytest.mark.issue_3620
14
17
  def test_resource(n=2):
15
18
  executors = parsl.dfk().executors
16
19
  executor = None
@@ -0,0 +1,120 @@
1
+ import json
2
+ import logging
3
+ import os
4
+ import pickle
5
+ import platform
6
+ import subprocess
7
+ import time
8
+
9
+ import psutil
10
+ import pytest
11
+ import zmq
12
+
13
+ import parsl.executors.high_throughput.zmq_pipes as zmq_pipes
14
+ from parsl.executors.high_throughput.executor import DEFAULT_INTERCHANGE_LAUNCH_CMD
15
+ from parsl.executors.high_throughput.manager_selector import RandomManagerSelector
16
+ from parsl.version import VERSION as PARSL_VERSION
17
+
18
+ P_ms = 10
19
+
20
+
21
+ @pytest.mark.local
22
+ def test_exit_with_bad_registration(tmpd_cwd, try_assert):
23
+ """Test that the interchange exits when it receives a bad registration message.
24
+ This complements parsl/tests/test_scaling/test_worker_interchange_bad_messages_3262.py
25
+ which tests that the interchange is resistent to other forms of bad message.
26
+ """
27
+
28
+ outgoing_q = zmq_pipes.TasksOutgoing(
29
+ "127.0.0.1", (49152, 65535), None
30
+ )
31
+ incoming_q = zmq_pipes.ResultsIncoming(
32
+ "127.0.0.1", (49152, 65535), None
33
+ )
34
+ command_client = zmq_pipes.CommandClient(
35
+ "127.0.0.1", (49152, 65535), None
36
+ )
37
+
38
+ interchange_config = {"client_address": "127.0.0.1",
39
+ "client_ports": (outgoing_q.port,
40
+ incoming_q.port,
41
+ command_client.port),
42
+ "interchange_address": "127.0.0.1",
43
+ "worker_ports": None,
44
+ "worker_port_range": (50000, 60000),
45
+ "hub_address": None,
46
+ "hub_zmq_port": None,
47
+ "logdir": tmpd_cwd,
48
+ "heartbeat_threshold": 120,
49
+ "poll_period": P_ms,
50
+ "logging_level": logging.DEBUG,
51
+ "cert_dir": None,
52
+ "manager_selector": RandomManagerSelector(),
53
+ "run_id": "test"
54
+ }
55
+
56
+ config_pickle = pickle.dumps(interchange_config)
57
+
58
+ interchange_proc = subprocess.Popen(DEFAULT_INTERCHANGE_LAUNCH_CMD, stdin=subprocess.PIPE)
59
+ stdin = interchange_proc.stdin
60
+ assert stdin is not None, "Popen should have created an IO object (vs default None) because of PIPE mode"
61
+
62
+ stdin.write(config_pickle)
63
+ stdin.flush()
64
+ stdin.close()
65
+
66
+ # wait for interchange to be alive, by waiting for the command thread to become
67
+ # responsive. if the interchange process didn't start enough to get the command
68
+ # thread running, this will time out.
69
+
70
+ (task_port, result_port) = command_client.run("WORKER_PORTS", timeout_s=120)
71
+
72
+ # now we'll assume that if the interchange command thread is responding,
73
+ # then the worker polling code is also running and that the interchange has
74
+ # started successfully.
75
+
76
+ # send bad registration message as if from a new worker pool. The badness here
77
+ # is that the Python version does not match the real Python version - which
78
+ # unlike some other bad interchange messages, should cause the interchange
79
+ # to shut down.
80
+
81
+ msg = {'type': 'registration',
82
+ 'parsl_v': PARSL_VERSION,
83
+ 'python_v': "{}.{}.{}".format(1, 1, 1), # this is the bad bit
84
+ 'worker_count': 1,
85
+ 'uid': 'testuid',
86
+ 'block_id': 0,
87
+ 'start_time': time.time(),
88
+ 'prefetch_capacity': 0,
89
+ 'max_capacity': 1,
90
+ 'os': platform.system(),
91
+ 'hostname': platform.node(),
92
+ 'dir': os.getcwd(),
93
+ 'cpu_count': psutil.cpu_count(logical=False),
94
+ 'total_memory': psutil.virtual_memory().total,
95
+ }
96
+
97
+ # connect to worker port and send this message.
98
+
99
+ context = zmq.Context()
100
+ channel_timeout = 10000 # in milliseconds
101
+ task_channel = context.socket(zmq.DEALER)
102
+ task_channel.setsockopt(zmq.LINGER, 0)
103
+ task_channel.setsockopt(zmq.IDENTITY, b'testid')
104
+
105
+ task_channel.set_hwm(0)
106
+ task_channel.setsockopt(zmq.SNDTIMEO, channel_timeout)
107
+ task_channel.connect(f"tcp://127.0.0.1:{task_port}")
108
+
109
+ b_msg = json.dumps(msg).encode('utf-8')
110
+
111
+ task_channel.send(b_msg)
112
+
113
+ # check that the interchange exits within some reasonable time
114
+ try_assert(lambda: interchange_proc.poll() is not None, "Interchange did not exit after killing watched client process", timeout_ms=5000)
115
+
116
+ # See issue #3697 - ideally the interchange would exit cleanly, but it does not.
117
+ # assert interchange_proc.poll() == 0, "Interchange exited with an error code, not 0"
118
+
119
+ task_channel.close()
120
+ context.term()
@@ -30,13 +30,6 @@ def test_resource_spec_validation():
30
30
  assert ret_val is None
31
31
 
32
32
 
33
- @pytest.mark.local
34
- def test_resource_spec_validation_one_key():
35
- htex = HighThroughputExecutor()
36
- ret_val = htex.validate_resource_spec({"priority": 2})
37
- assert ret_val is None
38
-
39
-
40
33
  @pytest.mark.local
41
34
  def test_resource_spec_validation_bad_keys():
42
35
  htex = HighThroughputExecutor()
@@ -43,3 +43,6 @@ def test_future_fail_dependency():
43
43
  # Future, plain_fut, somewhere in its str
44
44
 
45
45
  assert repr(plain_fut) in str(ex)
46
+ assert len(ex.dependent_exceptions_tids) == 1
47
+ assert isinstance(ex.dependent_exceptions_tids[0][0], ValueError)
48
+ assert ex.dependent_exceptions_tids[0][1].startswith("<Future ")
@@ -0,0 +1,52 @@
1
+ import pytest
2
+
3
+ from parsl.app.app import python_app
4
+ from parsl.dataflow.errors import DependencyError
5
+
6
+
7
+ class ManufacturedTestFailure(Exception):
8
+ pass
9
+
10
+
11
+ @python_app
12
+ def random_fail(fail_prob: float, inputs=()):
13
+ import random
14
+ if random.random() < fail_prob:
15
+ raise ManufacturedTestFailure("App failure")
16
+
17
+
18
+ def test_no_deps():
19
+ """Test basic error handling, with no dependent failures
20
+ """
21
+ futs = [random_fail(1), random_fail(0), random_fail(0)]
22
+
23
+ for f in futs:
24
+ try:
25
+ f.result()
26
+ except ManufacturedTestFailure:
27
+ pass
28
+
29
+
30
+ def test_fail_sequence_first():
31
+ t1 = random_fail(fail_prob=1)
32
+ t2 = random_fail(fail_prob=0, inputs=[t1])
33
+ t_final = random_fail(fail_prob=0, inputs=[t2])
34
+
35
+ with pytest.raises(DependencyError):
36
+ t_final.result()
37
+
38
+ assert len(t_final.exception().dependent_exceptions_tids) == 1
39
+ assert isinstance(t_final.exception().dependent_exceptions_tids[0][0], DependencyError)
40
+ assert t_final.exception().dependent_exceptions_tids[0][1].startswith("task ")
41
+
42
+
43
+ def test_fail_sequence_middle():
44
+ t1 = random_fail(fail_prob=0)
45
+ t2 = random_fail(fail_prob=1, inputs=[t1])
46
+ t_final = random_fail(fail_prob=0, inputs=[t2])
47
+
48
+ with pytest.raises(DependencyError):
49
+ t_final.result()
50
+
51
+ assert len(t_final.exception().dependent_exceptions_tids) == 1
52
+ assert isinstance(t_final.exception().dependent_exceptions_tids[0][0], ManufacturedTestFailure)
@@ -97,7 +97,10 @@ def test_error():
97
97
  f = outer_error()
98
98
  e = f.exception()
99
99
  assert isinstance(e, JoinError)
100
+
101
+ assert len(e.dependent_exceptions_tids) == 1
100
102
  assert isinstance(e.dependent_exceptions_tids[0][0], InnerError)
103
+ assert e.dependent_exceptions_tids[0][1].startswith("task ")
101
104
 
102
105
 
103
106
  def test_two_errors():
@@ -109,10 +112,12 @@ def test_two_errors():
109
112
  de0 = e.dependent_exceptions_tids[0][0]
110
113
  assert isinstance(de0, InnerError)
111
114
  assert de0.args[0] == "Error A"
115
+ assert e.dependent_exceptions_tids[0][1].startswith("task ")
112
116
 
113
117
  de1 = e.dependent_exceptions_tids[1][0]
114
118
  assert isinstance(de1, InnerError)
115
119
  assert de1.args[0] == "Error B"
120
+ assert e.dependent_exceptions_tids[1][1].startswith("task ")
116
121
 
117
122
 
118
123
  def test_one_error_one_result():
@@ -125,6 +130,7 @@ def test_one_error_one_result():
125
130
  de0 = e.dependent_exceptions_tids[0][0]
126
131
  assert isinstance(de0, InnerError)
127
132
  assert de0.args[0] == "Error A"
133
+ assert e.dependent_exceptions_tids[0][1].startswith("task ")
128
134
 
129
135
 
130
136
  @join_app