parsl 2024.3.11__py3-none-any.whl → 2025.1.13__py3-none-any.whl

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 (369) hide show
  1. parsl/__init__.py +9 -10
  2. parsl/addresses.py +29 -7
  3. parsl/app/app.py +7 -8
  4. parsl/app/bash.py +15 -8
  5. parsl/app/errors.py +10 -13
  6. parsl/app/futures.py +8 -10
  7. parsl/app/python.py +2 -1
  8. parsl/benchmark/perf.py +2 -1
  9. parsl/concurrent/__init__.py +2 -2
  10. parsl/config.py +57 -10
  11. parsl/configs/ASPIRE1.py +6 -5
  12. parsl/configs/Azure.py +9 -8
  13. parsl/configs/bridges.py +6 -4
  14. parsl/configs/cc_in2p3.py +3 -3
  15. parsl/configs/ec2.py +3 -1
  16. parsl/configs/expanse.py +4 -3
  17. parsl/configs/frontera.py +3 -4
  18. parsl/configs/htex_local.py +3 -4
  19. parsl/configs/illinoiscluster.py +3 -1
  20. parsl/configs/improv.py +34 -0
  21. parsl/configs/kubernetes.py +4 -3
  22. parsl/configs/local_threads.py +5 -1
  23. parsl/configs/midway.py +5 -3
  24. parsl/configs/osg.py +4 -2
  25. parsl/configs/polaris.py +4 -2
  26. parsl/configs/stampede2.py +6 -5
  27. parsl/configs/summit.py +3 -3
  28. parsl/configs/toss3_llnl.py +4 -3
  29. parsl/configs/vineex_local.py +6 -4
  30. parsl/configs/wqex_local.py +5 -3
  31. parsl/curvezmq.py +4 -0
  32. parsl/data_provider/data_manager.py +4 -3
  33. parsl/data_provider/file_noop.py +1 -2
  34. parsl/data_provider/files.py +3 -3
  35. parsl/data_provider/ftp.py +1 -3
  36. parsl/data_provider/globus.py +7 -6
  37. parsl/data_provider/http.py +2 -2
  38. parsl/data_provider/rsync.py +1 -1
  39. parsl/data_provider/staging.py +2 -2
  40. parsl/data_provider/zip.py +135 -0
  41. parsl/dataflow/dependency_resolvers.py +115 -0
  42. parsl/dataflow/dflow.py +262 -224
  43. parsl/dataflow/errors.py +3 -5
  44. parsl/dataflow/futures.py +27 -14
  45. parsl/dataflow/memoization.py +5 -5
  46. parsl/dataflow/rundirs.py +5 -6
  47. parsl/dataflow/taskrecord.py +4 -5
  48. parsl/executors/__init__.py +4 -2
  49. parsl/executors/base.py +45 -15
  50. parsl/executors/errors.py +13 -0
  51. parsl/executors/execute_task.py +37 -0
  52. parsl/executors/flux/execute_parsl_task.py +3 -3
  53. parsl/executors/flux/executor.py +18 -19
  54. parsl/executors/flux/flux_instance_manager.py +26 -27
  55. parsl/executors/high_throughput/errors.py +43 -3
  56. parsl/executors/high_throughput/executor.py +316 -282
  57. parsl/executors/high_throughput/interchange.py +158 -167
  58. parsl/executors/high_throughput/manager_record.py +5 -0
  59. parsl/executors/high_throughput/manager_selector.py +55 -0
  60. parsl/executors/high_throughput/monitoring_info.py +2 -1
  61. parsl/executors/high_throughput/mpi_executor.py +113 -0
  62. parsl/executors/high_throughput/mpi_prefix_composer.py +10 -11
  63. parsl/executors/high_throughput/mpi_resource_management.py +6 -17
  64. parsl/executors/high_throughput/probe.py +9 -7
  65. parsl/executors/high_throughput/process_worker_pool.py +115 -77
  66. parsl/executors/high_throughput/zmq_pipes.py +81 -23
  67. parsl/executors/radical/executor.py +130 -79
  68. parsl/executors/radical/rpex_resources.py +17 -15
  69. parsl/executors/radical/rpex_worker.py +4 -3
  70. parsl/executors/status_handling.py +157 -51
  71. parsl/executors/taskvine/__init__.py +1 -1
  72. parsl/executors/taskvine/errors.py +1 -1
  73. parsl/executors/taskvine/exec_parsl_function.py +2 -2
  74. parsl/executors/taskvine/executor.py +41 -57
  75. parsl/executors/taskvine/factory.py +1 -1
  76. parsl/executors/taskvine/factory_config.py +1 -1
  77. parsl/executors/taskvine/manager.py +18 -13
  78. parsl/executors/taskvine/manager_config.py +9 -5
  79. parsl/executors/threads.py +6 -6
  80. parsl/executors/workqueue/errors.py +1 -1
  81. parsl/executors/workqueue/exec_parsl_function.py +6 -5
  82. parsl/executors/workqueue/executor.py +64 -63
  83. parsl/executors/workqueue/parsl_coprocess.py +1 -1
  84. parsl/jobs/error_handlers.py +2 -2
  85. parsl/jobs/job_status_poller.py +30 -113
  86. parsl/jobs/states.py +7 -2
  87. parsl/jobs/strategy.py +43 -31
  88. parsl/launchers/__init__.py +12 -3
  89. parsl/launchers/errors.py +1 -1
  90. parsl/launchers/launchers.py +6 -12
  91. parsl/log_utils.py +9 -6
  92. parsl/monitoring/db_manager.py +59 -95
  93. parsl/monitoring/errors.py +6 -0
  94. parsl/monitoring/monitoring.py +87 -356
  95. parsl/monitoring/queries/pandas.py +1 -2
  96. parsl/monitoring/radios/base.py +13 -0
  97. parsl/monitoring/radios/filesystem.py +52 -0
  98. parsl/monitoring/radios/htex.py +57 -0
  99. parsl/monitoring/radios/multiprocessing.py +17 -0
  100. parsl/monitoring/radios/udp.py +56 -0
  101. parsl/monitoring/radios/zmq.py +17 -0
  102. parsl/monitoring/remote.py +33 -37
  103. parsl/monitoring/router.py +212 -0
  104. parsl/monitoring/types.py +5 -6
  105. parsl/monitoring/visualization/app.py +4 -2
  106. parsl/monitoring/visualization/models.py +0 -1
  107. parsl/monitoring/visualization/plots/default/workflow_plots.py +11 -4
  108. parsl/monitoring/visualization/plots/default/workflow_resource_plots.py +1 -0
  109. parsl/monitoring/visualization/utils.py +0 -1
  110. parsl/monitoring/visualization/views.py +16 -8
  111. parsl/multiprocessing.py +0 -1
  112. parsl/process_loggers.py +1 -2
  113. parsl/providers/__init__.py +8 -17
  114. parsl/providers/aws/aws.py +2 -3
  115. parsl/providers/azure/azure.py +4 -5
  116. parsl/providers/base.py +2 -18
  117. parsl/providers/cluster_provider.py +4 -12
  118. parsl/providers/condor/condor.py +7 -17
  119. parsl/providers/errors.py +2 -2
  120. parsl/providers/googlecloud/googlecloud.py +2 -1
  121. parsl/providers/grid_engine/grid_engine.py +5 -14
  122. parsl/providers/kubernetes/kube.py +80 -40
  123. parsl/providers/local/local.py +13 -26
  124. parsl/providers/lsf/lsf.py +5 -23
  125. parsl/providers/pbspro/pbspro.py +5 -17
  126. parsl/providers/slurm/slurm.py +81 -39
  127. parsl/providers/torque/torque.py +3 -14
  128. parsl/serialize/__init__.py +8 -3
  129. parsl/serialize/base.py +1 -2
  130. parsl/serialize/concretes.py +5 -4
  131. parsl/serialize/facade.py +3 -3
  132. parsl/serialize/proxystore.py +3 -2
  133. parsl/tests/__init__.py +1 -1
  134. parsl/tests/configs/azure_single_node.py +4 -5
  135. parsl/tests/configs/bridges.py +3 -2
  136. parsl/tests/configs/cc_in2p3.py +1 -3
  137. parsl/tests/configs/comet.py +2 -1
  138. parsl/tests/configs/ec2_single_node.py +1 -2
  139. parsl/tests/configs/ec2_spot.py +1 -2
  140. parsl/tests/configs/flux_local.py +11 -0
  141. parsl/tests/configs/frontera.py +2 -3
  142. parsl/tests/configs/htex_local.py +3 -5
  143. parsl/tests/configs/htex_local_alternate.py +11 -15
  144. parsl/tests/configs/htex_local_intask_staging.py +5 -9
  145. parsl/tests/configs/htex_local_rsync_staging.py +4 -8
  146. parsl/tests/configs/local_radical.py +1 -3
  147. parsl/tests/configs/local_radical_mpi.py +2 -2
  148. parsl/tests/configs/local_threads_checkpoint_periodic.py +8 -10
  149. parsl/tests/configs/local_threads_monitoring.py +0 -1
  150. parsl/tests/configs/midway.py +2 -2
  151. parsl/tests/configs/nscc_singapore.py +3 -3
  152. parsl/tests/configs/osg_htex.py +1 -1
  153. parsl/tests/configs/petrelkube.py +3 -2
  154. parsl/tests/configs/slurm_local.py +24 -0
  155. parsl/tests/configs/summit.py +1 -0
  156. parsl/tests/configs/taskvine_ex.py +4 -7
  157. parsl/tests/configs/user_opts.py +2 -8
  158. parsl/tests/configs/workqueue_ex.py +4 -6
  159. parsl/tests/conftest.py +27 -13
  160. parsl/tests/integration/test_stress/test_python_simple.py +3 -4
  161. parsl/tests/integration/test_stress/test_python_threads.py +3 -5
  162. parsl/tests/manual_tests/htex_local.py +4 -6
  163. parsl/tests/manual_tests/test_basic.py +1 -0
  164. parsl/tests/manual_tests/test_log_filter.py +3 -1
  165. parsl/tests/manual_tests/test_memory_limits.py +6 -8
  166. parsl/tests/manual_tests/test_regression_220.py +2 -1
  167. parsl/tests/manual_tests/test_udp_simple.py +4 -4
  168. parsl/tests/manual_tests/test_worker_count.py +3 -2
  169. parsl/tests/scaling_tests/htex_local.py +2 -4
  170. parsl/tests/scaling_tests/test_scale.py +0 -9
  171. parsl/tests/scaling_tests/vineex_condor.py +1 -2
  172. parsl/tests/scaling_tests/vineex_local.py +1 -2
  173. parsl/tests/site_tests/site_config_selector.py +1 -6
  174. parsl/tests/site_tests/test_provider.py +4 -2
  175. parsl/tests/site_tests/test_site.py +2 -0
  176. parsl/tests/sites/test_affinity.py +7 -7
  177. parsl/tests/sites/test_dynamic_executor.py +3 -4
  178. parsl/tests/sites/test_ec2.py +3 -2
  179. parsl/tests/sites/test_worker_info.py +4 -5
  180. parsl/tests/test_aalst_patterns.py +0 -1
  181. parsl/tests/test_bash_apps/test_apptimeout.py +2 -2
  182. parsl/tests/test_bash_apps/test_basic.py +10 -4
  183. parsl/tests/test_bash_apps/test_error_codes.py +5 -7
  184. parsl/tests/test_bash_apps/test_inputs_default.py +25 -0
  185. parsl/tests/test_bash_apps/test_kwarg_storage.py +1 -1
  186. parsl/tests/test_bash_apps/test_memoize.py +2 -8
  187. parsl/tests/test_bash_apps/test_memoize_ignore_args.py +9 -14
  188. parsl/tests/test_bash_apps/test_memoize_ignore_args_regr.py +9 -14
  189. parsl/tests/test_bash_apps/test_multiline.py +1 -1
  190. parsl/tests/test_bash_apps/test_pipeline.py +1 -1
  191. parsl/tests/test_bash_apps/test_std_uri.py +123 -0
  192. parsl/tests/test_bash_apps/test_stdout.py +33 -8
  193. parsl/tests/test_callables.py +2 -2
  194. parsl/tests/test_checkpointing/test_periodic.py +21 -39
  195. parsl/tests/test_checkpointing/test_python_checkpoint_1.py +1 -0
  196. parsl/tests/test_checkpointing/test_python_checkpoint_2.py +2 -2
  197. parsl/tests/test_checkpointing/test_python_checkpoint_3.py +0 -1
  198. parsl/tests/test_checkpointing/test_regression_239.py +1 -1
  199. parsl/tests/test_checkpointing/test_task_exit.py +2 -3
  200. parsl/tests/test_docs/test_from_slides.py +5 -2
  201. parsl/tests/test_docs/test_kwargs.py +4 -1
  202. parsl/tests/test_docs/test_tutorial_1.py +1 -2
  203. parsl/tests/test_docs/test_workflow1.py +2 -2
  204. parsl/tests/test_docs/test_workflow2.py +0 -1
  205. parsl/tests/test_error_handling/test_rand_fail.py +2 -2
  206. parsl/tests/test_error_handling/test_resource_spec.py +10 -12
  207. parsl/tests/test_error_handling/test_retries.py +6 -16
  208. parsl/tests/test_error_handling/test_retry_handler.py +1 -0
  209. parsl/tests/test_error_handling/test_retry_handler_failure.py +2 -1
  210. parsl/tests/test_error_handling/test_serialization_fail.py +1 -1
  211. parsl/tests/test_error_handling/test_wrap_with_logs.py +1 -0
  212. parsl/tests/test_execute_task.py +29 -0
  213. parsl/tests/test_flux.py +1 -1
  214. parsl/tests/test_htex/test_basic.py +2 -3
  215. parsl/tests/test_htex/test_block_manager_selector_unit.py +20 -0
  216. parsl/tests/test_htex/test_command_client_timeout.py +66 -0
  217. parsl/tests/test_htex/test_connected_blocks.py +3 -2
  218. parsl/tests/test_htex/test_cpu_affinity_explicit.py +6 -10
  219. parsl/tests/test_htex/test_disconnected_blocks.py +6 -5
  220. parsl/tests/test_htex/test_disconnected_blocks_failing_provider.py +71 -0
  221. parsl/tests/test_htex/test_drain.py +79 -0
  222. parsl/tests/test_htex/test_htex.py +51 -25
  223. parsl/tests/test_htex/test_manager_failure.py +0 -1
  224. parsl/tests/test_htex/test_manager_selector_by_block.py +51 -0
  225. parsl/tests/test_htex/test_managers_command.py +36 -0
  226. parsl/tests/test_htex/test_missing_worker.py +2 -12
  227. parsl/tests/test_htex/test_multiple_disconnected_blocks.py +9 -9
  228. parsl/tests/test_htex/test_resource_spec_validation.py +45 -0
  229. parsl/tests/test_htex/test_zmq_binding.py +29 -8
  230. parsl/tests/test_monitoring/test_app_names.py +86 -0
  231. parsl/tests/test_monitoring/test_basic.py +73 -25
  232. parsl/tests/test_monitoring/test_db_locks.py +6 -4
  233. parsl/tests/test_monitoring/test_fuzz_zmq.py +19 -8
  234. parsl/tests/test_monitoring/test_htex_init_blocks_vs_monitoring.py +80 -0
  235. parsl/tests/test_monitoring/test_incomplete_futures.py +5 -4
  236. parsl/tests/test_monitoring/test_memoization_representation.py +4 -2
  237. parsl/tests/test_monitoring/test_stdouterr.py +134 -0
  238. parsl/tests/test_monitoring/test_viz_colouring.py +1 -0
  239. parsl/tests/test_mpi_apps/test_bad_mpi_config.py +33 -26
  240. parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py +28 -11
  241. parsl/tests/test_mpi_apps/test_mpi_prefix.py +4 -4
  242. parsl/tests/test_mpi_apps/test_mpi_scheduler.py +7 -2
  243. parsl/tests/test_mpi_apps/test_mpiex.py +64 -0
  244. parsl/tests/test_mpi_apps/test_resource_spec.py +42 -49
  245. parsl/tests/test_providers/test_kubernetes_provider.py +102 -0
  246. parsl/tests/test_providers/test_local_provider.py +3 -132
  247. parsl/tests/test_providers/test_pbspro_template.py +2 -3
  248. parsl/tests/test_providers/test_slurm_template.py +2 -3
  249. parsl/tests/test_providers/test_submiterror_deprecation.py +2 -1
  250. parsl/tests/test_python_apps/test_context_manager.py +128 -0
  251. parsl/tests/test_python_apps/test_dep_standard_futures.py +2 -1
  252. parsl/tests/test_python_apps/test_dependencies_deep.py +59 -0
  253. parsl/tests/test_python_apps/test_fail.py +0 -25
  254. parsl/tests/test_python_apps/test_futures.py +2 -1
  255. parsl/tests/test_python_apps/test_inputs_default.py +22 -0
  256. parsl/tests/test_python_apps/test_join.py +0 -1
  257. parsl/tests/test_python_apps/test_lifted.py +11 -7
  258. parsl/tests/test_python_apps/test_memoize_bad_id_for_memo.py +1 -0
  259. parsl/tests/test_python_apps/test_outputs.py +1 -1
  260. parsl/tests/test_python_apps/test_pluggable_future_resolution.py +161 -0
  261. parsl/tests/test_radical/test_mpi_funcs.py +1 -2
  262. parsl/tests/test_regression/test_1480.py +2 -1
  263. parsl/tests/test_regression/test_1653.py +2 -1
  264. parsl/tests/test_regression/test_226.py +1 -0
  265. parsl/tests/test_regression/test_2652.py +1 -0
  266. parsl/tests/test_regression/test_69a.py +0 -1
  267. parsl/tests/test_regression/test_854.py +4 -2
  268. parsl/tests/test_regression/test_97_parallelism_0.py +1 -2
  269. parsl/tests/test_regression/test_98.py +0 -1
  270. parsl/tests/test_scaling/test_block_error_handler.py +9 -4
  271. parsl/tests/test_scaling/test_regression_1621.py +11 -15
  272. parsl/tests/test_scaling/test_regression_3568_scaledown_vs_MISSING.py +84 -0
  273. parsl/tests/test_scaling/test_regression_3696_oscillation.py +103 -0
  274. parsl/tests/test_scaling/test_scale_down.py +2 -5
  275. parsl/tests/test_scaling/test_scale_down_htex_auto_scale.py +6 -18
  276. parsl/tests/test_scaling/test_scale_down_htex_unregistered.py +71 -0
  277. parsl/tests/test_scaling/test_shutdown_scalein.py +73 -0
  278. parsl/tests/test_scaling/test_worker_interchange_bad_messages_3262.py +90 -0
  279. parsl/tests/test_serialization/test_2555_caching_deserializer.py +1 -1
  280. parsl/tests/test_serialization/test_3495_deserialize_managerlost.py +47 -0
  281. parsl/tests/test_serialization/test_basic.py +2 -1
  282. parsl/tests/test_serialization/test_htex_code_cache.py +3 -4
  283. parsl/tests/test_serialization/test_pack_resource_spec.py +2 -1
  284. parsl/tests/test_serialization/test_proxystore_configured.py +10 -6
  285. parsl/tests/test_serialization/test_proxystore_impl.py +5 -3
  286. parsl/tests/test_shutdown/test_kill_monitoring.py +64 -0
  287. parsl/tests/test_staging/staging_provider.py +2 -2
  288. parsl/tests/test_staging/test_1316.py +3 -4
  289. parsl/tests/test_staging/test_docs_1.py +2 -1
  290. parsl/tests/test_staging/test_docs_2.py +2 -1
  291. parsl/tests/test_staging/test_elaborate_noop_file.py +2 -3
  292. parsl/tests/{test_data → test_staging}/test_file.py +6 -6
  293. parsl/tests/{test_data → test_staging}/test_output_chain_filenames.py +3 -0
  294. parsl/tests/test_staging/test_staging_ftp.py +1 -0
  295. parsl/tests/test_staging/test_staging_https.py +5 -2
  296. parsl/tests/test_staging/test_staging_stdout.py +64 -0
  297. parsl/tests/test_staging/test_zip_in.py +39 -0
  298. parsl/tests/test_staging/test_zip_out.py +110 -0
  299. parsl/tests/test_staging/test_zip_to_zip.py +41 -0
  300. parsl/tests/test_summary.py +2 -2
  301. parsl/tests/test_thread_parallelism.py +0 -1
  302. parsl/tests/test_threads/test_configs.py +1 -2
  303. parsl/tests/test_threads/test_lazy_errors.py +2 -2
  304. parsl/tests/test_utils/test_execute_wait.py +35 -0
  305. parsl/tests/test_utils/test_sanitize_dns.py +76 -0
  306. parsl/tests/unit/test_address.py +20 -0
  307. parsl/tests/unit/test_file.py +99 -0
  308. parsl/tests/unit/test_usage_tracking.py +66 -0
  309. parsl/usage_tracking/api.py +65 -0
  310. parsl/usage_tracking/levels.py +6 -0
  311. parsl/usage_tracking/usage.py +104 -62
  312. parsl/utils.py +139 -6
  313. parsl/version.py +1 -1
  314. {parsl-2024.3.11.data → parsl-2025.1.13.data}/scripts/exec_parsl_function.py +6 -5
  315. parsl-2025.1.13.data/scripts/interchange.py +649 -0
  316. {parsl-2024.3.11.data → parsl-2025.1.13.data}/scripts/process_worker_pool.py +115 -77
  317. parsl-2025.1.13.dist-info/METADATA +96 -0
  318. parsl-2025.1.13.dist-info/RECORD +462 -0
  319. {parsl-2024.3.11.dist-info → parsl-2025.1.13.dist-info}/WHEEL +1 -1
  320. parsl/channels/__init__.py +0 -7
  321. parsl/channels/base.py +0 -141
  322. parsl/channels/errors.py +0 -113
  323. parsl/channels/local/local.py +0 -164
  324. parsl/channels/oauth_ssh/oauth_ssh.py +0 -110
  325. parsl/channels/ssh/ssh.py +0 -276
  326. parsl/channels/ssh_il/__init__.py +0 -0
  327. parsl/channels/ssh_il/ssh_il.py +0 -74
  328. parsl/configs/ad_hoc.py +0 -35
  329. parsl/executors/radical/rpex_master.py +0 -42
  330. parsl/monitoring/radios.py +0 -175
  331. parsl/providers/ad_hoc/__init__.py +0 -0
  332. parsl/providers/ad_hoc/ad_hoc.py +0 -248
  333. parsl/providers/cobalt/__init__.py +0 -0
  334. parsl/providers/cobalt/cobalt.py +0 -236
  335. parsl/providers/cobalt/template.py +0 -17
  336. parsl/tests/configs/ad_hoc_cluster_htex.py +0 -35
  337. parsl/tests/configs/cooley_htex.py +0 -37
  338. parsl/tests/configs/htex_ad_hoc_cluster.py +0 -28
  339. parsl/tests/configs/local_adhoc.py +0 -18
  340. parsl/tests/configs/swan_htex.py +0 -43
  341. parsl/tests/configs/theta.py +0 -37
  342. parsl/tests/integration/test_channels/__init__.py +0 -0
  343. parsl/tests/integration/test_channels/test_channels.py +0 -17
  344. parsl/tests/integration/test_channels/test_local_channel.py +0 -42
  345. parsl/tests/integration/test_channels/test_scp_1.py +0 -45
  346. parsl/tests/integration/test_channels/test_ssh_1.py +0 -40
  347. parsl/tests/integration/test_channels/test_ssh_errors.py +0 -46
  348. parsl/tests/integration/test_channels/test_ssh_file_transport.py +0 -41
  349. parsl/tests/integration/test_channels/test_ssh_interactive.py +0 -24
  350. parsl/tests/manual_tests/test_ad_hoc_htex.py +0 -48
  351. parsl/tests/manual_tests/test_fan_in_out_htex_remote.py +0 -88
  352. parsl/tests/manual_tests/test_oauth_ssh.py +0 -13
  353. parsl/tests/sites/test_local_adhoc.py +0 -61
  354. parsl/tests/test_channels/__init__.py +0 -0
  355. parsl/tests/test_channels/test_large_output.py +0 -22
  356. parsl/tests/test_data/__init__.py +0 -0
  357. parsl/tests/test_mpi_apps/test_mpi_mode_disabled.py +0 -51
  358. parsl/tests/test_providers/test_cobalt_deprecation_warning.py +0 -16
  359. parsl-2024.3.11.dist-info/METADATA +0 -98
  360. parsl-2024.3.11.dist-info/RECORD +0 -447
  361. parsl/{channels/local → monitoring/radios}/__init__.py +0 -0
  362. parsl/{channels/oauth_ssh → tests/test_shutdown}/__init__.py +0 -0
  363. parsl/tests/{test_data → test_staging}/test_file_apps.py +0 -0
  364. parsl/tests/{test_data → test_staging}/test_file_staging.py +0 -0
  365. parsl/{channels/ssh → tests/unit}/__init__.py +0 -0
  366. {parsl-2024.3.11.data → parsl-2025.1.13.data}/scripts/parsl_coprocess.py +1 -1
  367. {parsl-2024.3.11.dist-info → parsl-2025.1.13.dist-info}/LICENSE +0 -0
  368. {parsl-2024.3.11.dist-info → parsl-2025.1.13.dist-info}/entry_points.txt +0 -0
  369. {parsl-2024.3.11.dist-info → parsl-2025.1.13.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,103 @@
1
+ import math
2
+ from unittest.mock import MagicMock
3
+
4
+ import pytest
5
+
6
+ from parsl.executors.high_throughput.executor import HighThroughputExecutor
7
+ from parsl.jobs.states import JobState, JobStatus
8
+ from parsl.jobs.strategy import Strategy
9
+
10
+
11
+ # the parameterize tuple consists of:
12
+ # Input:
13
+ # * number of tasks to mock the load as
14
+ # * number of workers per node
15
+ # Expected output:
16
+ # * the number of blocks we should expect to be launched
17
+ # in this situation
18
+ #
19
+ # This test will configure an executor, then run strategize
20
+ # a few times, asserting that it converges to the correct
21
+ # number of blocks without oscillating.
22
+ @pytest.mark.local
23
+ @pytest.mark.parametrize("ns", [(14, 48, 1), # values from issue #3696
24
+
25
+ (1, 1, 1), # one task needs one block
26
+
27
+ (100, 1, 20), # many one-task blocks, hitting hard-coded max blocks
28
+
29
+ (47, 48, 1), # some edge cases around #3696 values
30
+ (48, 48, 1), # "
31
+ (49, 48, 2), # "
32
+ (149, 50, 3)]) # "
33
+ def test_htex_strategy_does_not_oscillate(ns):
34
+ """Check for oscillations in htex scaling.
35
+ In issue 3696, with a large number of workers per block
36
+ and a smaller number of active tasks, the htex scaling
37
+ strategy oscillates between 0 and 1 active block, rather
38
+ than converging to 1 active block.
39
+ """
40
+
41
+ n_tasks, n_workers, n_blocks = ns
42
+
43
+ s = Strategy(strategy='htex_auto_scale', max_idletime=0)
44
+
45
+ provider = MagicMock()
46
+ executor = MagicMock(spec=HighThroughputExecutor)
47
+
48
+ statuses = {}
49
+
50
+ executor.provider = provider
51
+ executor.outstanding = n_tasks
52
+ executor.status_facade = statuses
53
+ executor.workers_per_node = n_workers
54
+
55
+ provider.parallelism = 1
56
+ provider.init_blocks = 0
57
+ provider.min_blocks = 0
58
+ provider.max_blocks = 20
59
+ provider.nodes_per_block = 1
60
+
61
+ def scale_out(n):
62
+ for _ in range(n):
63
+ statuses[len(statuses)] = JobStatus(state=JobState.PENDING)
64
+
65
+ executor.scale_out_facade.side_effect = scale_out
66
+
67
+ def scale_in(n, max_idletime=None):
68
+ # find n PENDING jobs and set them to CANCELLED
69
+ for k in statuses:
70
+ if n == 0:
71
+ return
72
+ if statuses[k].state == JobState.PENDING:
73
+ statuses[k].state = JobState.CANCELLED
74
+ n -= 1
75
+
76
+ executor.scale_in_facade.side_effect = scale_in
77
+
78
+ s.add_executors([executor])
79
+
80
+ # In issue #3696, this first strategise does initial and load based
81
+ # scale outs, because n_tasks > n_workers*0
82
+ s.strategize([executor])
83
+
84
+ executor.scale_out_facade.assert_called()
85
+ assert len(statuses) == n_blocks, "Should have launched n_blocks"
86
+ assert len([k for k in statuses if statuses[k].state == JobState.PENDING]) == n_blocks
87
+ # there might be several calls to scale_out_facade inside strategy,
88
+ # but the end effect should be that exactly one block is scaled out.
89
+
90
+ executor.scale_in_facade.assert_not_called()
91
+
92
+ # In issue #3696, this second strategize does a scale in, because n_tasks < n_workers*1
93
+ s.strategize([executor])
94
+
95
+ # assert that there should still be n_blocks pending blocks
96
+ assert len([k for k in statuses if statuses[k].state == JobState.PENDING]) == n_blocks
97
+ # this assert fails due to issue #3696
98
+
99
+ # Now check scale in happens with 0 load
100
+ executor.outstanding = 0
101
+ s.strategize([executor])
102
+ executor.scale_in_facade.assert_called()
103
+ assert len([k for k in statuses if statuses[k].state == JobState.PENDING]) == 0
@@ -4,13 +4,11 @@ import time
4
4
  import pytest
5
5
 
6
6
  import parsl
7
-
8
7
  from parsl import File, python_app
9
- from parsl.providers import LocalProvider
10
- from parsl.channels import LocalChannel
11
- from parsl.launchers import SingleNodeLauncher
12
8
  from parsl.config import Config
13
9
  from parsl.executors import HighThroughputExecutor
10
+ from parsl.launchers import SingleNodeLauncher
11
+ from parsl.providers import LocalProvider
14
12
 
15
13
  logger = logging.getLogger(__name__)
16
14
 
@@ -30,7 +28,6 @@ def local_config():
30
28
  max_workers_per_node=1,
31
29
  encrypted=True,
32
30
  provider=LocalProvider(
33
- channel=LocalChannel(),
34
31
  init_blocks=0,
35
32
  max_blocks=_max_blocks,
36
33
  min_blocks=_min_blocks,
@@ -1,15 +1,13 @@
1
+ from threading import Event
2
+
1
3
  import pytest
2
4
 
3
5
  import parsl
4
-
5
6
  from parsl import File, python_app
6
- from parsl.providers import LocalProvider
7
- from parsl.channels import LocalChannel
8
- from parsl.launchers import SingleNodeLauncher
9
7
  from parsl.config import Config
10
8
  from parsl.executors import HighThroughputExecutor
11
-
12
- from threading import Event
9
+ from parsl.launchers import SingleNodeLauncher
10
+ from parsl.providers import LocalProvider
13
11
 
14
12
  _max_blocks = 5
15
13
  _min_blocks = 0
@@ -24,10 +22,9 @@ def local_config():
24
22
  poll_period=100,
25
23
  label="htex_local",
26
24
  address="127.0.0.1",
27
- max_workers=1,
25
+ max_workers_per_node=1,
28
26
  encrypted=True,
29
27
  provider=LocalProvider(
30
- channel=LocalChannel(),
31
28
  init_blocks=0,
32
29
  max_blocks=_max_blocks,
33
30
  min_blocks=_min_blocks,
@@ -37,6 +34,7 @@ def local_config():
37
34
  ],
38
35
  max_idletime=0.5,
39
36
  strategy='htex_auto_scale',
37
+ strategy_period=0.1
40
38
  )
41
39
 
42
40
 
@@ -62,16 +60,6 @@ def waiting_app(ident: int, outputs=(), inputs=()):
62
60
  def test_scale_out(tmpd_cwd, try_assert):
63
61
  dfk = parsl.dfk()
64
62
 
65
- # reconfigure scaling strategy to run faster than usual. This allows
66
- # this test to complete faster - at time of writing 27s with default
67
- # 5s strategy, vs XXXX with 0.5s strategy.
68
-
69
- # check this attribute still exists, in the presence of ongoing
70
- # development, so we have some belief that setting it will not be
71
- # setting a now-ignored parameter.
72
- assert hasattr(dfk.job_status_poller, 'interval')
73
- dfk.job_status_poller.interval = 0.1
74
-
75
63
  num_managers = len(dfk.executors['htex_local'].connected_managers())
76
64
 
77
65
  assert num_managers == 0, "Expected 0 managers at start"
@@ -0,0 +1,71 @@
1
+ import logging
2
+ import time
3
+
4
+ import pytest
5
+
6
+ import parsl
7
+ from parsl import File, python_app
8
+ from parsl.config import Config
9
+ from parsl.executors import HighThroughputExecutor
10
+ from parsl.jobs.states import TERMINAL_STATES, JobState
11
+ from parsl.launchers import SingleNodeLauncher
12
+ from parsl.providers import LocalProvider
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+ _max_blocks = 1
17
+ _min_blocks = 0
18
+
19
+
20
+ def local_config():
21
+ return Config(
22
+ executors=[
23
+ HighThroughputExecutor(
24
+ heartbeat_period=1,
25
+ heartbeat_threshold=2,
26
+ poll_period=100,
27
+ label="htex_local",
28
+ address="127.0.0.1",
29
+ max_workers_per_node=1,
30
+ encrypted=True,
31
+ launch_cmd="sleep inf",
32
+ provider=LocalProvider(
33
+ init_blocks=1,
34
+ max_blocks=_max_blocks,
35
+ min_blocks=_min_blocks,
36
+ launcher=SingleNodeLauncher(),
37
+ ),
38
+ )
39
+ ],
40
+ max_idletime=0.5,
41
+ strategy='htex_auto_scale',
42
+ strategy_period=0.1
43
+ )
44
+
45
+
46
+ # see issue #1885 for details of failures of this test.
47
+ # at the time of issue #1885 this test was failing frequently
48
+ # in CI.
49
+ @pytest.mark.local
50
+ def test_scaledown_with_register(try_assert):
51
+ dfk = parsl.dfk()
52
+ htex = dfk.executors['htex_local']
53
+
54
+ num_managers = len(htex.connected_managers())
55
+ assert num_managers == 0, "Expected 0 managers at start"
56
+
57
+ try_assert(lambda: len(htex.status()),
58
+ fail_msg="Expected 1 block at start")
59
+
60
+ s = htex.status()
61
+ assert s['0'].state == JobState.RUNNING, "Expected block to be in RUNNING"
62
+
63
+ def check_zero_blocks():
64
+ s = htex.status()
65
+ return len(s) == 1 and s['0'].state in TERMINAL_STATES
66
+
67
+ try_assert(
68
+ check_zero_blocks,
69
+ fail_msg="Expected 0 blocks after idle scaledown",
70
+ timeout_ms=15000,
71
+ )
@@ -0,0 +1,73 @@
1
+ import random
2
+ import threading
3
+
4
+ import pytest
5
+
6
+ import parsl
7
+ from parsl.config import Config
8
+ from parsl.executors import HighThroughputExecutor
9
+ from parsl.launchers import SimpleLauncher
10
+ from parsl.providers import LocalProvider
11
+
12
+ # we need some blocks, but it doesn't matter too much how many, as long
13
+ # as they can all start up and get registered within the try_assert
14
+ # timeout later on.
15
+ BLOCK_COUNT = 3
16
+
17
+
18
+ class AccumulatingLocalProvider(LocalProvider):
19
+ def __init__(self, *args, **kwargs):
20
+ # Use a list for submitted job IDs because if there are multiple
21
+ # submissions returning the same job ID, this test should count
22
+ # those...
23
+ self.submit_job_ids = []
24
+
25
+ # ... but there's no requirement, I think, that cancel must be called
26
+ # only once per job id. What matters here is that each job ID is
27
+ # cancelled at least once.
28
+ self.cancel_job_ids = set()
29
+
30
+ super().__init__(*args, **kwargs)
31
+
32
+ def submit(self, *args, **kwargs):
33
+ job_id = super().submit(*args, **kwargs)
34
+ self.submit_job_ids.append(job_id)
35
+ return job_id
36
+
37
+ def cancel(self, job_ids):
38
+ self.cancel_job_ids.update(job_ids)
39
+ return super().cancel(job_ids)
40
+
41
+
42
+ @pytest.mark.local
43
+ def test_shutdown_scalein_blocks(tmpd_cwd, try_assert):
44
+ """
45
+ This test scales up several blocks, and then checks that they are all
46
+ scaled in at DFK shutdown.
47
+ """
48
+ accumulating_provider = AccumulatingLocalProvider(
49
+ init_blocks=BLOCK_COUNT,
50
+ min_blocks=0,
51
+ max_blocks=0,
52
+ launcher=SimpleLauncher(),
53
+ )
54
+
55
+ htex = HighThroughputExecutor(
56
+ label="htex_local",
57
+ cores_per_worker=1,
58
+ provider=accumulating_provider
59
+ )
60
+
61
+ config = Config(
62
+ executors=[htex],
63
+ strategy='none',
64
+ strategy_period=0.1,
65
+ run_dir=str(tmpd_cwd)
66
+ )
67
+
68
+ with parsl.load(config):
69
+ # this will wait for everything to be scaled out fully
70
+ try_assert(lambda: len(htex.connected_managers()) == BLOCK_COUNT)
71
+
72
+ assert len(accumulating_provider.submit_job_ids) == BLOCK_COUNT, f"Exactly {BLOCK_COUNT} blocks should have been launched"
73
+ assert len(accumulating_provider.cancel_job_ids) == BLOCK_COUNT, f"Exactly {BLOCK_COUNT} blocks should have been scaled in"
@@ -0,0 +1,90 @@
1
+ import os
2
+ import signal
3
+ import time
4
+
5
+ import pytest
6
+ import zmq
7
+
8
+ import parsl
9
+ from parsl.config import Config
10
+ from parsl.executors import HighThroughputExecutor
11
+ from parsl.launchers import SimpleLauncher
12
+ from parsl.providers import LocalProvider
13
+
14
+ T_s = 1
15
+
16
+
17
+ def fresh_config():
18
+ htex = HighThroughputExecutor(
19
+ heartbeat_period=1 * T_s,
20
+ heartbeat_threshold=3 * T_s,
21
+ label="htex_local",
22
+ worker_debug=True,
23
+ cores_per_worker=1,
24
+ encrypted=False,
25
+ provider=LocalProvider(
26
+ init_blocks=0,
27
+ min_blocks=0,
28
+ max_blocks=0,
29
+ launcher=SimpleLauncher(),
30
+ ),
31
+ )
32
+ c = Config(
33
+ executors=[htex],
34
+ strategy='none',
35
+ strategy_period=0.5,
36
+ )
37
+ return c, htex
38
+
39
+
40
+ @parsl.python_app
41
+ def app():
42
+ return 7
43
+
44
+
45
+ @pytest.mark.local
46
+ @pytest.mark.parametrize("msg",
47
+ (b'FuzzyByte\rSTREAM', # not JSON
48
+ b'{}', # missing fields
49
+ b'{"type":"heartbeat"}', # regression test #3262
50
+ )
51
+ )
52
+ def test_bad_messages(try_assert, msg):
53
+ """This tests that the interchange is resilient to a few different bad
54
+ messages: malformed messages caused by implementation errors, and
55
+ heartbeat messages from managers that are not registered.
56
+
57
+ The heartbeat test is a regression test for issues #3262, #3632
58
+ """
59
+
60
+ c, htex = fresh_config()
61
+
62
+ with parsl.load(c):
63
+
64
+ # send a bad message into the interchange on the task_outgoing worker
65
+ # channel, and then check that the interchange is still alive enough
66
+ # that we can scale out a block and run a task.
67
+
68
+ (task_port, result_port) = htex.command_client.run("WORKER_PORTS")
69
+
70
+ context = zmq.Context()
71
+ channel_timeout = 10000 # in milliseconds
72
+ task_channel = context.socket(zmq.DEALER)
73
+ task_channel.setsockopt(zmq.LINGER, 0)
74
+ task_channel.setsockopt(zmq.IDENTITY, b'testid')
75
+
76
+ task_channel.set_hwm(0)
77
+ task_channel.setsockopt(zmq.SNDTIMEO, channel_timeout)
78
+ task_channel.connect(f"tcp://localhost:{task_port}")
79
+
80
+ task_channel.send(msg)
81
+
82
+ # If the interchange exits, it's likely that this test will hang rather
83
+ # than raise an error, because the interchange interaction code
84
+ # assumes the interchange is always there.
85
+ # In the case of issue #3262, an exception message goes to stderr, and
86
+ # no error goes to the interchange log file.
87
+ htex.scale_out_facade(1)
88
+ try_assert(lambda: len(htex.connected_managers()) == 1, timeout_ms=10000)
89
+
90
+ assert app().result() == 7
@@ -1,6 +1,6 @@
1
- import parsl
2
1
  import pytest
3
2
 
3
+ import parsl
4
4
  from parsl.tests.configs.htex_local import fresh_config as local_config
5
5
 
6
6
 
@@ -0,0 +1,47 @@
1
+ import os
2
+ import signal
3
+
4
+ import pytest
5
+
6
+ import parsl
7
+ from parsl import Config, HighThroughputExecutor
8
+ from parsl.executors.high_throughput.errors import ManagerLost
9
+
10
+
11
+ @parsl.python_app
12
+ def get_manager_pgid():
13
+ import os
14
+ return os.getpgid(os.getpid())
15
+
16
+
17
+ @parsl.python_app
18
+ def lose_manager():
19
+ import os
20
+ import signal
21
+
22
+ manager_pid = os.getppid()
23
+ os.kill(manager_pid, signal.SIGSTOP)
24
+
25
+
26
+ @pytest.mark.local
27
+ def test_manager_lost_system_failure(tmpd_cwd):
28
+ hte = HighThroughputExecutor(
29
+ label="htex_local",
30
+ address="127.0.0.1",
31
+ max_workers_per_node=2,
32
+ cores_per_worker=1,
33
+ worker_logdir_root=str(tmpd_cwd),
34
+ heartbeat_period=1,
35
+ heartbeat_threshold=3,
36
+ )
37
+ c = Config(executors=[hte], strategy='simple', strategy_period=0.1)
38
+
39
+ with parsl.load(c):
40
+ manager_pgid = get_manager_pgid().result()
41
+ try:
42
+ with pytest.raises(ManagerLost):
43
+ lose_manager().result()
44
+ finally:
45
+ # Allow process to clean itself up
46
+ os.killpg(manager_pgid, signal.SIGCONT)
47
+ os.killpg(manager_pgid, signal.SIGTERM)
@@ -1,5 +1,6 @@
1
1
  import pytest
2
- from parsl.serialize import serialize, deserialize
2
+
3
+ from parsl.serialize import deserialize, serialize
3
4
  from parsl.serialize.concretes import DillSerializer, PickleSerializer
4
5
 
5
6
 
@@ -1,10 +1,9 @@
1
- import parsl
2
- import pytest
3
-
4
1
  from typing import Any
5
2
 
6
- from parsl.serialize.facade import methods_for_code
3
+ import pytest
7
4
 
5
+ import parsl
6
+ from parsl.serialize.facade import methods_for_code
8
7
  from parsl.tests.configs.htex_local import fresh_config as local_config
9
8
 
10
9
 
@@ -1,5 +1,6 @@
1
1
  import pytest
2
- from parsl.serialize import unpack_res_spec_apply_message, pack_res_spec_apply_message
2
+
3
+ from parsl.serialize import pack_res_spec_apply_message, unpack_res_spec_apply_message
3
4
 
4
5
 
5
6
  def double(x: int, y: int = 2) -> int:
@@ -1,19 +1,24 @@
1
1
  import logging
2
- import pytest
3
2
  import uuid
4
3
 
4
+ import pytest
5
+
5
6
  import parsl
6
- from parsl.serialize.facade import additional_methods_for_deserialization, methods_for_data, register_method_for_data
7
+ from parsl.serialize.facade import (
8
+ additional_methods_for_deserialization,
9
+ methods_for_data,
10
+ register_method_for_data,
11
+ )
7
12
  from parsl.tests.configs.htex_local import fresh_config
8
13
 
9
-
10
14
  logger = logging.getLogger(__name__)
11
15
 
12
16
 
13
17
  def local_setup():
14
- from parsl.serialize.proxystore import ProxyStoreSerializer
15
- from proxystore.store import Store, register_store
16
18
  from proxystore.connectors.file import FileConnector
19
+ from proxystore.store import Store, register_store
20
+
21
+ from parsl.serialize.proxystore import ProxyStoreSerializer
17
22
 
18
23
  parsl.load(fresh_config())
19
24
 
@@ -38,7 +43,6 @@ def local_setup():
38
43
 
39
44
  def local_teardown():
40
45
  parsl.dfk().cleanup()
41
- parsl.clear()
42
46
 
43
47
  methods_for_data.clear()
44
48
  methods_for_data.update(previous_methods)
@@ -1,6 +1,7 @@
1
- import pytest
2
1
  import uuid
3
2
 
3
+ import pytest
4
+
4
5
 
5
6
  def policy_example(o):
6
7
  """Example policy will proxy only lists."""
@@ -13,10 +14,11 @@ def test_proxystore_nonglobal():
13
14
  """
14
15
  # import in function, because proxystore is not importable in base parsl
15
16
  # installation.
16
- from parsl.serialize.proxystore import ProxyStoreSerializer
17
+ from proxystore.connectors.file import FileConnector
17
18
  from proxystore.proxy import Proxy
18
19
  from proxystore.store import Store, register_store
19
- from proxystore.connectors.file import FileConnector
20
+
21
+ from parsl.serialize.proxystore import ProxyStoreSerializer
20
22
 
21
23
  store = Store(name='parsl_store_' + str(uuid.uuid4()), connector=FileConnector(store_dir="/tmp"))
22
24
  register_store(store)
@@ -0,0 +1,64 @@
1
+ import os
2
+ import signal
3
+ import time
4
+
5
+ import pytest
6
+
7
+ import parsl
8
+ from parsl.tests.configs.htex_local_alternate import fresh_config
9
+
10
+ # This is a very generous upper bound on expected shutdown time of target
11
+ # process after receiving a signal, measured in seconds.
12
+ PERMITTED_SHUTDOWN_TIME_S = 60
13
+
14
+
15
+ @parsl.python_app
16
+ def simple_app():
17
+ return True
18
+
19
+
20
+ @pytest.mark.local
21
+ def test_no_kills():
22
+ """This tests that we can create a monitoring-enabled DFK and shut it down."""
23
+
24
+ parsl.load(fresh_config())
25
+
26
+ assert parsl.dfk().monitoring is not None, "This test requires monitoring"
27
+
28
+ parsl.dfk().cleanup()
29
+
30
+
31
+ @pytest.mark.local
32
+ @pytest.mark.parametrize("sig", [signal.SIGINT, signal.SIGTERM, signal.SIGKILL, signal.SIGQUIT])
33
+ @pytest.mark.parametrize("process_attr", ["router_proc", "dbm_proc"])
34
+ def test_kill_monitoring_helper_process(sig, process_attr, try_assert):
35
+ """This tests that we can kill a monitoring process and still have successful shutdown.
36
+ SIGINT emulates some racy behaviour when ctrl-C is pressed: that
37
+ monitoring processes receive a ctrl-C too, and so the other processes
38
+ need to be tolerant to monitoring processes arbitrarily exiting.
39
+ """
40
+
41
+ parsl.load(fresh_config())
42
+
43
+ dfk = parsl.dfk()
44
+
45
+ assert dfk.monitoring is not None, "Monitoring required"
46
+
47
+ target_proc = getattr(dfk.monitoring, process_attr)
48
+
49
+ assert target_proc is not None, "prereq: target process must exist"
50
+ assert target_proc.is_alive(), "prereq: target process must be alive"
51
+
52
+ target_pid = target_proc.pid
53
+ assert target_pid is not None, "prereq: target process must have a pid"
54
+
55
+ os.kill(target_pid, sig)
56
+
57
+ try_assert(lambda: not target_proc.is_alive(), timeout_ms=PERMITTED_SHUTDOWN_TIME_S * 1000)
58
+
59
+ # now we have broken one piece of the monitoring system, do some app
60
+ # execution and then shut down.
61
+
62
+ simple_app().result()
63
+
64
+ parsl.dfk().cleanup()
@@ -62,8 +62,8 @@ def make_stage_out_app(executor, dfk):
62
62
 
63
63
 
64
64
  def stage_out_noop(app_fu, inputs=[], _parsl_staging_inhibit=True):
65
- import time
66
65
  import logging
66
+ import time
67
67
  logger = logging.getLogger(__name__)
68
68
  logger.info("stage_out_noop")
69
69
  time.sleep(1)
@@ -75,8 +75,8 @@ def make_stage_in_app(executor, dfk):
75
75
 
76
76
 
77
77
  def stage_in_noop(parent_fut=None, outputs=[], _parsl_staging_inhibit=True):
78
- import time
79
78
  import logging
79
+ import time
80
80
  logger = logging.getLogger(__name__)
81
81
  logger.info("stage_in_noop")
82
82
  time.sleep(1)
@@ -1,8 +1,9 @@
1
+ import time
2
+
1
3
  import pytest
2
4
 
3
5
  import parsl
4
- import time
5
- from parsl import python_app, ThreadPoolExecutor
6
+ from parsl import ThreadPoolExecutor, python_app
6
7
  from parsl.config import Config
7
8
  from parsl.data_provider.files import File
8
9
  from parsl.data_provider.staging import Staging
@@ -60,7 +61,6 @@ def test_1316_local_path_on_execution_side_sp2():
60
61
  assert not file.local_path, "The local_path on the submit side should not be set"
61
62
 
62
63
  parsl.dfk().cleanup()
63
- parsl.clear()
64
64
 
65
65
 
66
66
  @pytest.mark.local
@@ -83,4 +83,3 @@ def test_1316_local_path_setting_preserves_dependency_sp2():
83
83
  assert not file.local_path, "The local_path on the submit side should not be set"
84
84
 
85
85
  parsl.dfk().cleanup()
86
- parsl.clear()