parsl 2025.1.13__py3-none-any.whl → 2025.1.27__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 (36) hide show
  1. parsl/configs/gc_multisite.py +27 -0
  2. parsl/configs/gc_tutorial.py +18 -0
  3. parsl/dataflow/dflow.py +23 -103
  4. parsl/dataflow/errors.py +60 -18
  5. parsl/dataflow/memoization.py +76 -2
  6. parsl/dataflow/taskrecord.py +1 -3
  7. parsl/executors/__init__.py +3 -1
  8. parsl/executors/globus_compute.py +125 -0
  9. parsl/executors/high_throughput/errors.py +1 -1
  10. parsl/executors/high_throughput/executor.py +16 -15
  11. parsl/executors/high_throughput/interchange.py +74 -96
  12. parsl/executors/high_throughput/zmq_pipes.py +0 -1
  13. parsl/tests/configs/globus_compute.py +20 -0
  14. parsl/tests/conftest.py +4 -0
  15. parsl/tests/test_checkpointing/test_python_checkpoint_1.py +0 -3
  16. parsl/tests/test_error_handling/test_resource_spec.py +3 -0
  17. parsl/tests/test_htex/test_interchange_exit_bad_registration.py +120 -0
  18. parsl/tests/test_htex/test_resource_spec_validation.py +0 -7
  19. parsl/tests/test_python_apps/test_dep_standard_futures.py +3 -0
  20. parsl/tests/test_python_apps/test_fail.py +23 -8
  21. parsl/tests/test_python_apps/test_join.py +6 -0
  22. parsl/tests/test_python_apps/test_memoize_1.py +0 -1
  23. parsl/tests/unit/test_globus_compute_executor.py +104 -0
  24. parsl/usage_tracking/usage.py +13 -8
  25. parsl/version.py +1 -1
  26. {parsl-2025.1.13.data → parsl-2025.1.27.data}/scripts/interchange.py +74 -96
  27. {parsl-2025.1.13.dist-info → parsl-2025.1.27.dist-info}/METADATA +5 -2
  28. {parsl-2025.1.13.dist-info → parsl-2025.1.27.dist-info}/RECORD +35 -30
  29. parsl/tests/test_checkpointing/test_python_checkpoint_3.py +0 -42
  30. {parsl-2025.1.13.data → parsl-2025.1.27.data}/scripts/exec_parsl_function.py +0 -0
  31. {parsl-2025.1.13.data → parsl-2025.1.27.data}/scripts/parsl_coprocess.py +0 -0
  32. {parsl-2025.1.13.data → parsl-2025.1.27.data}/scripts/process_worker_pool.py +0 -0
  33. {parsl-2025.1.13.dist-info → parsl-2025.1.27.dist-info}/LICENSE +0 -0
  34. {parsl-2025.1.13.dist-info → parsl-2025.1.27.dist-info}/WHEEL +0 -0
  35. {parsl-2025.1.13.dist-info → parsl-2025.1.27.dist-info}/entry_points.txt +0 -0
  36. {parsl-2025.1.13.dist-info → parsl-2025.1.27.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,104 @@
1
+ import random
2
+ from unittest import mock
3
+
4
+ import pytest
5
+ from globus_compute_sdk import Executor
6
+
7
+ from parsl.executors import GlobusComputeExecutor
8
+
9
+
10
+ @pytest.fixture
11
+ def mock_ex():
12
+ # Not Parsl's job to test GC's Executor
13
+ yield mock.Mock(spec=Executor)
14
+
15
+
16
+ @pytest.mark.local
17
+ def test_gc_executor_mock_spec(mock_ex):
18
+ # a test of tests -- make sure we're using spec= in the mock
19
+ with pytest.raises(AttributeError):
20
+ mock_ex.aasdf()
21
+
22
+
23
+ @pytest.mark.local
24
+ def test_gc_executor_label_default(mock_ex):
25
+ gce = GlobusComputeExecutor(mock_ex)
26
+ assert gce.label == type(gce).__name__, "Expect reasonable default label"
27
+
28
+
29
+ @pytest.mark.local
30
+ def test_gc_executor_label(mock_ex, randomstring):
31
+ exp_label = randomstring()
32
+ gce = GlobusComputeExecutor(mock_ex, label=exp_label)
33
+ assert gce.label == exp_label
34
+
35
+
36
+ @pytest.mark.local
37
+ def test_gc_executor_resets_spec_after_submit(mock_ex, randomstring):
38
+ submit_res = {randomstring(): "some submit res"}
39
+ res = {"some": randomstring(), "spec": randomstring()}
40
+ mock_ex.resource_specification = res
41
+ mock_ex.user_endpoint_config = None
42
+ gce = GlobusComputeExecutor(mock_ex)
43
+
44
+ fn = mock.Mock()
45
+ orig_res = mock_ex.resource_specification
46
+ orig_uep = mock_ex.user_endpoint_config
47
+
48
+ def mock_submit(*a, **k):
49
+ assert mock_ex.resource_specification == submit_res, "Expect set for submission"
50
+ assert mock_ex.user_endpoint_config is None
51
+ mock_ex.submit.side_effect = mock_submit
52
+
53
+ gce.submit(fn, resource_specification=submit_res)
54
+
55
+ assert mock_ex.resource_specification == orig_res
56
+ assert mock_ex.user_endpoint_config is orig_uep
57
+
58
+
59
+ @pytest.mark.local
60
+ def test_gc_executor_resets_uep_after_submit(mock_ex, randomstring):
61
+ uep_conf = randomstring()
62
+ res = {"some": randomstring()}
63
+ gce = GlobusComputeExecutor(mock_ex)
64
+
65
+ fn = mock.Mock()
66
+ orig_res = mock_ex.resource_specification
67
+ orig_uep = mock_ex.user_endpoint_config
68
+
69
+ def mock_submit(*a, **k):
70
+
71
+ assert mock_ex.resource_specification == res, "Expect set for submission"
72
+ assert mock_ex.user_endpoint_config == uep_conf, "Expect set for submission"
73
+ mock_ex.submit.side_effect = mock_submit
74
+
75
+ gce.submit(fn, resource_specification={"user_endpoint_config": uep_conf, **res})
76
+
77
+ assert mock_ex.resource_specification == orig_res
78
+ assert mock_ex.user_endpoint_config is orig_uep
79
+
80
+
81
+ @pytest.mark.local
82
+ def test_gc_executor_happy_path(mock_ex, randomstring):
83
+ mock_fn = mock.Mock()
84
+ args = tuple(randomstring() for _ in range(random.randint(0, 3)))
85
+ kwargs = {randomstring(): randomstring() for _ in range(random.randint(0, 3))}
86
+
87
+ gce = GlobusComputeExecutor(mock_ex)
88
+ gce.submit(mock_fn, {}, *args, **kwargs)
89
+
90
+ assert mock_ex.submit.called, "Expect proxying of args to underlying executor"
91
+ found_a, found_k = mock_ex.submit.call_args
92
+ assert found_a[0] is mock_fn
93
+ assert found_a[1:] == args
94
+ assert found_k == kwargs
95
+
96
+
97
+ @pytest.mark.local
98
+ def test_gc_executor_shuts_down_asynchronously(mock_ex):
99
+ gce = GlobusComputeExecutor(mock_ex)
100
+ gce.shutdown()
101
+ assert mock_ex.shutdown.called
102
+ a, k = mock_ex.shutdown.call_args
103
+ assert k["wait"] is False
104
+ assert k["cancel_futures"] is True
@@ -213,12 +213,14 @@ class UsageTracker:
213
213
 
214
214
  def send_start_message(self) -> None:
215
215
  if self.tracking_level:
216
+ logger.info("Sending start message for usage tracking")
216
217
  self.start_time = time.time()
217
218
  message = self.construct_start_message()
218
219
  self.send_UDP_message(message)
219
220
 
220
221
  def send_end_message(self) -> None:
221
222
  if self.tracking_level == 3:
223
+ logger.info("Sending end message for usage tracking")
222
224
  message = self.construct_end_message()
223
225
  self.send_UDP_message(message)
224
226
 
@@ -229,11 +231,14 @@ class UsageTracker:
229
231
  definitely either: going to behave broadly the same as to SIGKILL,
230
232
  or won't respond to SIGTERM.
231
233
  """
232
- for proc in self.procs:
233
- logger.debug("Joining usage tracking process %s", proc)
234
- proc.join(timeout=timeout)
235
- if proc.is_alive():
236
- logger.warning("Usage tracking process did not end itself; sending SIGKILL")
237
- proc.kill()
238
-
239
- proc.close()
234
+ if self.tracking_level:
235
+ logger.info("Closing usage tracking")
236
+
237
+ for proc in self.procs:
238
+ logger.debug("Joining usage tracking process %s", proc)
239
+ proc.join(timeout=timeout)
240
+ if proc.is_alive():
241
+ logger.warning("Usage tracking process did not end itself; sending SIGKILL")
242
+ proc.kill()
243
+
244
+ proc.close()
parsl/version.py CHANGED
@@ -3,4 +3,4 @@
3
3
  Year.Month.Day[alpha/beta/..]
4
4
  Alphas will be numbered like this -> 2024.12.10a0
5
5
  """
6
- VERSION = '2025.01.13'
6
+ VERSION = '2025.01.27'
@@ -9,7 +9,7 @@ import queue
9
9
  import sys
10
10
  import threading
11
11
  import time
12
- from typing import Any, Dict, List, NoReturn, Optional, Sequence, Set, Tuple, cast
12
+ from typing import Any, Dict, List, Optional, Sequence, Set, Tuple, cast
13
13
 
14
14
  import zmq
15
15
 
@@ -132,6 +132,11 @@ class Interchange:
132
132
  self.hub_zmq_port = hub_zmq_port
133
133
 
134
134
  self.pending_task_queue: queue.Queue[Any] = queue.Queue(maxsize=10 ** 6)
135
+
136
+ # count of tasks that have been received from the submit side
137
+ self.task_counter = 0
138
+
139
+ # count of tasks that have been sent out to worker pools
135
140
  self.count = 0
136
141
 
137
142
  self.worker_ports = worker_ports
@@ -201,28 +206,6 @@ class Interchange:
201
206
 
202
207
  return tasks
203
208
 
204
- @wrap_with_logs(target="interchange")
205
- def task_puller(self) -> NoReturn:
206
- """Pull tasks from the incoming tasks zmq pipe onto the internal
207
- pending task queue
208
- """
209
- logger.info("Starting")
210
- task_counter = 0
211
-
212
- while True:
213
- logger.debug("launching recv_pyobj")
214
- try:
215
- msg = self.task_incoming.recv_pyobj()
216
- except zmq.Again:
217
- # We just timed out while attempting to receive
218
- logger.debug("zmq.Again with {} tasks in internal queue".format(self.pending_task_queue.qsize()))
219
- continue
220
-
221
- logger.debug("putting message onto pending_task_queue")
222
- self.pending_task_queue.put(msg)
223
- task_counter += 1
224
- logger.debug(f"Fetched {task_counter} tasks so far")
225
-
226
209
  def _send_monitoring_info(self, monitoring_radio: Optional[MonitoringRadioSender], manager: ManagerRecord) -> None:
227
210
  if monitoring_radio:
228
211
  logger.info("Sending message {} to MonitoringHub".format(manager))
@@ -234,79 +217,68 @@ class Interchange:
234
217
 
235
218
  monitoring_radio.send((MessageType.NODE_INFO, d))
236
219
 
237
- @wrap_with_logs(target="interchange")
238
- def _command_server(self) -> NoReturn:
220
+ def process_command(self, monitoring_radio: Optional[MonitoringRadioSender]) -> None:
239
221
  """ Command server to run async command to the interchange
240
222
  """
241
- logger.debug("Command Server Starting")
242
-
243
- if self.hub_address is not None and self.hub_zmq_port is not None:
244
- logger.debug("Creating monitoring radio to %s:%s", self.hub_address, self.hub_zmq_port)
245
- monitoring_radio = ZMQRadioSender(self.hub_address, self.hub_zmq_port)
246
- else:
247
- monitoring_radio = None
223
+ logger.debug("entering command_server section")
248
224
 
249
225
  reply: Any # the type of reply depends on the command_req received (aka this needs dependent types...)
250
226
 
251
- while True:
252
- try:
253
- command_req = self.command_channel.recv_pyobj()
254
- logger.debug("Received command request: {}".format(command_req))
255
- if command_req == "CONNECTED_BLOCKS":
256
- reply = self.connected_block_history
257
-
258
- elif command_req == "WORKERS":
259
- num_workers = 0
260
- for manager in self._ready_managers.values():
261
- num_workers += manager['worker_count']
262
- reply = num_workers
263
-
264
- elif command_req == "MANAGERS":
265
- reply = []
266
- for manager_id in self._ready_managers:
267
- m = self._ready_managers[manager_id]
268
- idle_since = m['idle_since']
269
- if idle_since is not None:
270
- idle_duration = time.time() - idle_since
271
- else:
272
- idle_duration = 0.0
273
- resp = {'manager': manager_id.decode('utf-8'),
274
- 'block_id': m['block_id'],
275
- 'worker_count': m['worker_count'],
276
- 'tasks': len(m['tasks']),
277
- 'idle_duration': idle_duration,
278
- 'active': m['active'],
279
- 'parsl_version': m['parsl_version'],
280
- 'python_version': m['python_version'],
281
- 'draining': m['draining']}
282
- reply.append(resp)
283
-
284
- elif command_req.startswith("HOLD_WORKER"):
285
- cmd, s_manager = command_req.split(';')
286
- manager_id = s_manager.encode('utf-8')
287
- logger.info("Received HOLD_WORKER for {!r}".format(manager_id))
288
- if manager_id in self._ready_managers:
289
- m = self._ready_managers[manager_id]
290
- m['active'] = False
291
- self._send_monitoring_info(monitoring_radio, m)
227
+ if self.command_channel in self.socks and self.socks[self.command_channel] == zmq.POLLIN:
228
+
229
+ command_req = self.command_channel.recv_pyobj()
230
+ logger.debug("Received command request: {}".format(command_req))
231
+ if command_req == "CONNECTED_BLOCKS":
232
+ reply = self.connected_block_history
233
+
234
+ elif command_req == "WORKERS":
235
+ num_workers = 0
236
+ for manager in self._ready_managers.values():
237
+ num_workers += manager['worker_count']
238
+ reply = num_workers
239
+
240
+ elif command_req == "MANAGERS":
241
+ reply = []
242
+ for manager_id in self._ready_managers:
243
+ m = self._ready_managers[manager_id]
244
+ idle_since = m['idle_since']
245
+ if idle_since is not None:
246
+ idle_duration = time.time() - idle_since
292
247
  else:
293
- logger.warning("Worker to hold was not in ready managers list")
294
-
295
- reply = None
248
+ idle_duration = 0.0
249
+ resp = {'manager': manager_id.decode('utf-8'),
250
+ 'block_id': m['block_id'],
251
+ 'worker_count': m['worker_count'],
252
+ 'tasks': len(m['tasks']),
253
+ 'idle_duration': idle_duration,
254
+ 'active': m['active'],
255
+ 'parsl_version': m['parsl_version'],
256
+ 'python_version': m['python_version'],
257
+ 'draining': m['draining']}
258
+ reply.append(resp)
259
+
260
+ elif command_req.startswith("HOLD_WORKER"):
261
+ cmd, s_manager = command_req.split(';')
262
+ manager_id = s_manager.encode('utf-8')
263
+ logger.info("Received HOLD_WORKER for {!r}".format(manager_id))
264
+ if manager_id in self._ready_managers:
265
+ m = self._ready_managers[manager_id]
266
+ m['active'] = False
267
+ self._send_monitoring_info(monitoring_radio, m)
268
+ else:
269
+ logger.warning("Worker to hold was not in ready managers list")
296
270
 
297
- elif command_req == "WORKER_PORTS":
298
- reply = (self.worker_task_port, self.worker_result_port)
271
+ reply = None
299
272
 
300
- else:
301
- logger.error(f"Received unknown command: {command_req}")
302
- reply = None
273
+ elif command_req == "WORKER_PORTS":
274
+ reply = (self.worker_task_port, self.worker_result_port)
303
275
 
304
- logger.debug("Reply: {}".format(reply))
305
- self.command_channel.send_pyobj(reply)
276
+ else:
277
+ logger.error(f"Received unknown command: {command_req}")
278
+ reply = None
306
279
 
307
- except zmq.Again:
308
- logger.debug("Command thread is alive")
309
- continue
280
+ logger.debug("Reply: {}".format(reply))
281
+ self.command_channel.send_pyobj(reply)
310
282
 
311
283
  @wrap_with_logs
312
284
  def start(self) -> None:
@@ -326,21 +298,13 @@ class Interchange:
326
298
 
327
299
  start = time.time()
328
300
 
329
- self._task_puller_thread = threading.Thread(target=self.task_puller,
330
- name="Interchange-Task-Puller",
331
- daemon=True)
332
- self._task_puller_thread.start()
333
-
334
- self._command_thread = threading.Thread(target=self._command_server,
335
- name="Interchange-Command",
336
- daemon=True)
337
- self._command_thread.start()
338
-
339
301
  kill_event = threading.Event()
340
302
 
341
303
  poller = zmq.Poller()
342
304
  poller.register(self.task_outgoing, zmq.POLLIN)
343
305
  poller.register(self.results_incoming, zmq.POLLIN)
306
+ poller.register(self.task_incoming, zmq.POLLIN)
307
+ poller.register(self.command_channel, zmq.POLLIN)
344
308
 
345
309
  # These are managers which we should examine in an iteration
346
310
  # for scheduling a job (or maybe any other attention?).
@@ -351,6 +315,8 @@ class Interchange:
351
315
  while not kill_event.is_set():
352
316
  self.socks = dict(poller.poll(timeout=poll_period))
353
317
 
318
+ self.process_command(monitoring_radio)
319
+ self.process_task_incoming()
354
320
  self.process_task_outgoing_incoming(interesting_managers, monitoring_radio, kill_event)
355
321
  self.process_results_incoming(interesting_managers, monitoring_radio)
356
322
  self.expire_bad_managers(interesting_managers, monitoring_radio)
@@ -362,6 +328,18 @@ class Interchange:
362
328
  logger.info(f"Processed {self.count} tasks in {delta} seconds")
363
329
  logger.warning("Exiting")
364
330
 
331
+ def process_task_incoming(self) -> None:
332
+ """Process incoming task message(s).
333
+ """
334
+
335
+ if self.task_incoming in self.socks and self.socks[self.task_incoming] == zmq.POLLIN:
336
+ logger.debug("start task_incoming section")
337
+ msg = self.task_incoming.recv_pyobj()
338
+ logger.debug("putting message onto pending_task_queue")
339
+ self.pending_task_queue.put(msg)
340
+ self.task_counter += 1
341
+ logger.debug(f"Fetched {self.task_counter} tasks so far")
342
+
365
343
  def process_task_outgoing_incoming(
366
344
  self,
367
345
  interesting_managers: Set[bytes],
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: parsl
3
- Version: 2025.1.13
3
+ Version: 2025.1.27
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.27.tar.gz
7
7
  Author: The Parsl Team
8
8
  Author-email: parsl@googlegroups.com
9
9
  License: Apache 2.0
@@ -54,6 +54,7 @@ Requires-Dist: jsonschema; extra == "all"
54
54
  Requires-Dist: proxystore; extra == "all"
55
55
  Requires-Dist: radical.pilot==1.90; extra == "all"
56
56
  Requires-Dist: radical.utils==1.90; extra == "all"
57
+ Requires-Dist: globus-compute-sdk>=2.34.0; extra == "all"
57
58
  Provides-Extra: aws
58
59
  Requires-Dist: boto3; extra == "aws"
59
60
  Provides-Extra: azure
@@ -68,6 +69,8 @@ Provides-Extra: flux
68
69
  Requires-Dist: pyyaml; extra == "flux"
69
70
  Requires-Dist: cffi; extra == "flux"
70
71
  Requires-Dist: jsonschema; extra == "flux"
72
+ Provides-Extra: globus_compute
73
+ Requires-Dist: globus-compute-sdk>=2.34.0; extra == "globus-compute"
71
74
  Provides-Extra: google_cloud
72
75
  Requires-Dist: google-auth; extra == "google-cloud"
73
76
  Requires-Dist: google-api-python-client; extra == "google-cloud"
@@ -8,7 +8,7 @@ parsl/multiprocessing.py,sha256=MyaEcEq-Qf860u7V98u-PZrPNdtzOZL_NW6EhIJnmfQ,1937
8
8
  parsl/process_loggers.py,sha256=uQ7Gd0W72Jz7rrcYlOMfLsAEhkRltxXJL2MgdduJjEw,1136
9
9
  parsl/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  parsl/utils.py,sha256=5FvHIMao3Ik0Rm2p2ieL1KQcQcYXc5K83Jrx5csi-B4,14301
11
- parsl/version.py,sha256=bTc0Ag_aE5DQzLbxb9Ls_EZLzh1tm2AQOpG2Eg0inwg,131
11
+ parsl/version.py,sha256=FCVXhZGb8M-LjO2YDkIquMX7ZJEQ6J5AWGf63T7y0-k,131
12
12
  parsl/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  parsl/app/app.py,sha256=0gbM4AH2OtFOLsv07I5nglpElcwMSOi-FzdZZfrk7So,8532
14
14
  parsl/app/bash.py,sha256=jm2AvePlCT9DZR7H_4ANDWxatp5dN_22FUlT_gWhZ-g,5528
@@ -26,6 +26,8 @@ parsl/configs/cc_in2p3.py,sha256=8KQ18URTKX5o16k66_h-TRCRQeh7Vrsi-s2d_AuOBHs,705
26
26
  parsl/configs/ec2.py,sha256=5xtlZI4Fc558sYXdM4nQQvQDBNPdzhRRCO14F-8H7Y4,944
27
27
  parsl/configs/expanse.py,sha256=ADUY3GZWSfVKmqFWbgdfC85kRxNPChqOGwly0XdcKSw,1033
28
28
  parsl/configs/frontera.py,sha256=HkZ3sFvFqKrk8kdxMonbUiWjGaZxz3vgvhtgg6_0vpY,1415
29
+ parsl/configs/gc_multisite.py,sha256=831wrArZ-cUHB7eucpGDtgqvfgXV4lTjKYy7sN8rtDY,1001
30
+ parsl/configs/gc_tutorial.py,sha256=2BnWVmblSG_dxeO2aBez3IeaBk5Phk-X0ZtJXWxZpLI,478
29
31
  parsl/configs/htex_local.py,sha256=ktc1RlF1ig0QHDJHUl8ZROutSle-5f1yYYod8RFZcaY,462
30
32
  parsl/configs/illinoiscluster.py,sha256=ZR22A8uwFb8tzSzmU1D0kR0qcr5Thr0j-7Nb5hiCgQ8,1170
31
33
  parsl/configs/improv.py,sha256=le9fDip-Mr-HqKObiyHXbdR-Ne7cy15Ao5ONoUzCSaE,1252
@@ -51,17 +53,18 @@ parsl/data_provider/staging.py,sha256=ZDZuuFg38pjUStegKPcvPsfGp3iMeReMzfU6DSwtJj
51
53
  parsl/data_provider/zip.py,sha256=S4kVuH9lxAegRURYbvIUR7EYYBOccyslaqyCrVWUBhw,4497
52
54
  parsl/dataflow/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
55
  parsl/dataflow/dependency_resolvers.py,sha256=Om8Dgh7a0ZwgXAc6TlhxLSzvxXHDlNNV1aBNiD3JTNY,3325
54
- parsl/dataflow/dflow.py,sha256=HClWgi9BpEcFhe3IBEkTNaIV8JtYTBc1oSmjtOkIdh8,65253
55
- parsl/dataflow/errors.py,sha256=vzgEEFqIfIQ3_QGvqDCcsACZZlUKNAKaMchM30TGHyY,2114
56
+ parsl/dataflow/dflow.py,sha256=jNxrAd2xmxesS3fR6eZyDN9f6I0BIBQbhL63zv51lkk,61752
57
+ parsl/dataflow/errors.py,sha256=daVfr2BWs1zRsGD6JtosEMttWHvK1df1Npiu_MUvFKg,3998
56
58
  parsl/dataflow/futures.py,sha256=08LuP-HFiHBIZmeKCjlsazw_WpQ5fwevrU2_WbidkYw,6080
57
- parsl/dataflow/memoization.py,sha256=l9uw1Bu50GucBF70M5relpGKFkE4dIM9T3R1KrxW0v0,9583
59
+ parsl/dataflow/memoization.py,sha256=QUkTduZ_gdr8i08VWNWrqhfEvoMGsPDZegWUE2_7sGQ,12579
58
60
  parsl/dataflow/rundirs.py,sha256=JZdzybVGubY35jL2YiKcDo65ZmRl1WyOApc8ajYxztc,1087
59
61
  parsl/dataflow/states.py,sha256=hV6mfv-y4A6xrujeQglcomnfEs7y3Xm2g6JFwC6dvgQ,2612
60
- parsl/dataflow/taskrecord.py,sha256=-FuujdZQ1y5GSc-PJ91QKGT-Kp0lrg70MFDoxpbWI1Q,3113
61
- parsl/executors/__init__.py,sha256=Cg8e-F2NUaBD8A9crDAXKCSdoBEwQVIdgm4FlXd-wvk,476
62
+ parsl/dataflow/taskrecord.py,sha256=qIW7T6hn9dYTuNPdUura3HQwwUpUJACwPP5REm5COf4,3042
63
+ parsl/executors/__init__.py,sha256=PEuXYrnVqwlaz_nt82s9D_YNaVsX7ET29DeIZRUR8hw,577
62
64
  parsl/executors/base.py,sha256=jYEa5nS1_Vn8k3A92TCSYG0n2zeHnN6KiuVWsILl4sE,5205
63
65
  parsl/executors/errors.py,sha256=ZxL3nK5samPos8Xixo_jpRtPIiRJfZ5D397_qaXj2g0,2515
64
66
  parsl/executors/execute_task.py,sha256=PtqHxk778UQaNah1AN-TJV5emZbOcU5TGtWDxFn3_F4,1079
67
+ parsl/executors/globus_compute.py,sha256=giyCyq5KWK_o4nhQJBX2Xm9FatdpdKrgloZuHhN0Zwg,4840
65
68
  parsl/executors/status_handling.py,sha256=nxbkiGr6f3xDc0nsUeSrMMxlj7UD32K7nOLCLzfthDs,15416
66
69
  parsl/executors/threads.py,sha256=_LA5NA3GSvtjDend-1HVpjoDoNHHW13rAD0CET99fjQ,3463
67
70
  parsl/executors/flux/__init__.py,sha256=P9grTTeRPXfqXurFhlSS7XhmE6tTbnCnyQ1f9b-oYHE,136
@@ -69,9 +72,9 @@ parsl/executors/flux/execute_parsl_task.py,sha256=zHP5M7ILGiwnoalZ8WsfVVdZM7uP4i
69
72
  parsl/executors/flux/executor.py,sha256=8_xakLUu5zNJAHL0LbeTCFEWqWzRK1eE-3ep4GIIIrY,17017
70
73
  parsl/executors/flux/flux_instance_manager.py,sha256=5T3Rp7ZM-mlT0Pf0Gxgs5_YmnaPrSF9ec7zvRfLfYJw,2129
71
74
  parsl/executors/high_throughput/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
72
- parsl/executors/high_throughput/errors.py,sha256=YfGvJQxoF7tnEecHUmJsCyALjXvgAkuPJosH8pNu-aw,1582
73
- parsl/executors/high_throughput/executor.py,sha256=kueKbVVblvXcbXsHEnmQXMkvdfuF6IpwV7-clp2Tkzk,38393
74
- parsl/executors/high_throughput/interchange.py,sha256=i0TYgAQzcnzRnSdKal9M9d6TcWRoIWK77kuxMsiYxXE,30142
75
+ parsl/executors/high_throughput/errors.py,sha256=k2XuvvFdUfNs2foHFnxmS-BToRMfdXpYEa4EF3ELKq4,1554
76
+ parsl/executors/high_throughput/executor.py,sha256=4WKp0ZqAz036WcaXq-4DDwLyu8W6xGPunnvLAVSeaiQ,38493
77
+ parsl/executors/high_throughput/interchange.py,sha256=kVz7LTx6ThcYrQOSq-TsWHOlDwgyQk4w9Qyd3egQTuY,29143
75
78
  parsl/executors/high_throughput/manager_record.py,sha256=yn3L8TUJFkgm2lX1x0SeS9mkvJowC0s2VIMCFiU7ThM,455
76
79
  parsl/executors/high_throughput/manager_selector.py,sha256=UKcUE6v0tO7PDMTThpKSKxVpOpOUilxDL7UbNgpZCxo,2116
77
80
  parsl/executors/high_throughput/monitoring_info.py,sha256=HC0drp6nlXQpAop5PTUKNjdXMgtZVvrBL0JzZJebPP4,298
@@ -80,7 +83,7 @@ parsl/executors/high_throughput/mpi_prefix_composer.py,sha256=DmpKugANNa1bdYlqQB
80
83
  parsl/executors/high_throughput/mpi_resource_management.py,sha256=hqotZLn3Q_iPRfMVmvvpKiGdguw55iYq1L_Gp9x6y4Y,7790
81
84
  parsl/executors/high_throughput/probe.py,sha256=QOEaliO3x5cB6ltMOZMsZQ-ath9AAuFqXcBzRgWOM60,2754
82
85
  parsl/executors/high_throughput/process_worker_pool.py,sha256=3zXe3_X5GvbTOlfeJJD_E0ssfJqkAfkqXHfeU7mymdI,41865
83
- parsl/executors/high_throughput/zmq_pipes.py,sha256=XtNTxbnt9UHfhiduj9f3UkviYRebUy4ierhEGvowB8k,9040
86
+ parsl/executors/high_throughput/zmq_pipes.py,sha256=NUK25IEh0UkxzdqQQyM8tMtuZmjSiTeWu1DzkkAIOhA,8980
84
87
  parsl/executors/radical/__init__.py,sha256=CKbtV2numw5QvgIBq1htMUrt9TqDCIC2zifyf2svTNU,186
85
88
  parsl/executors/radical/executor.py,sha256=en2TKzZnJYU_juojkM_aZUdWhbAgutAYn_EL6HGpfSY,22835
86
89
  parsl/executors/radical/rpex_resources.py,sha256=Q7-0u3K447LBCe2y7mVcdw6jqWI7SdPXxCKhkr6FoRQ,5139
@@ -191,7 +194,7 @@ parsl/serialize/facade.py,sha256=3uOuVp0epfyLn7qDzuWqLfsy971YVGD3sqwqcAiRwh0,668
191
194
  parsl/serialize/proxystore.py,sha256=o-ha9QAvVhbN8y9S1itk3W0O75eyHYZw2AvB2xu5_Lg,1624
192
195
  parsl/tests/__init__.py,sha256=VTtJzOzz_x6fWNh8IOnsgFqVbdiJShi2AZH21mcmID4,204
193
196
  parsl/tests/callables_helper.py,sha256=ceP1YYsNtrZgKT6MAIvpgdccEjQ_CpFEOnZBGHKGOx0,30
194
- parsl/tests/conftest.py,sha256=njhszRuR15nZDufKF2S90lgkL8bSnQY4vH7dckx9q24,14851
197
+ parsl/tests/conftest.py,sha256=i8vJ2OSyhU1g8MoA1g6XPPEJ4VaavGN88dTcBROrhYE,15009
195
198
  parsl/tests/test_aalst_patterns.py,sha256=lNIxb7nIgh1yX7hR2fr_ck_mxYJxx8ASKK9zHUVqPno,9614
196
199
  parsl/tests/test_callables.py,sha256=97vrIF1_hfDGd81FM1bhR6FemZMWFcALrH6pVHMTCt8,1974
197
200
  parsl/tests/test_curvezmq.py,sha256=yyhlS4vmaZdMitiySoy4l_ih9H1bsPiN-tMdwIh3H20,12431
@@ -210,6 +213,7 @@ parsl/tests/configs/ec2_single_node.py,sha256=rK9AfMf4C84CXMhS5nhgHA_dNG2An7Yiq2
210
213
  parsl/tests/configs/ec2_spot.py,sha256=NKDCKgKxYNOHGVLBl2DFfiUwkR6xQnyhNb_E04TBs28,1253
211
214
  parsl/tests/configs/flux_local.py,sha256=xliKQfB5FFpfNHWYEHoA8FKOTVHFCXVhWNuKQ5VJNTk,182
212
215
  parsl/tests/configs/frontera.py,sha256=WEXJjFmHMhFT8X8JLUIUK35Qm2FRDolhOCAaE0zlL0U,1483
216
+ parsl/tests/configs/globus_compute.py,sha256=5lRtOVmXSUJ1vLgCk3eoR96GVX-vitP9IsU8_e3netE,418
213
217
  parsl/tests/configs/htex_local.py,sha256=6TKsAbEyFknFWT1cpMyd34DmPoo0OrsyPTayzSf2OFQ,675
214
218
  parsl/tests/configs/htex_local_alternate.py,sha256=CgIpjBpenLn-xOG0Ix5xrWgqO8wllOFnNXomJEWSkDY,2453
215
219
  parsl/tests/configs/htex_local_intask_staging.py,sha256=JTcrc8qNseF1sdBHxX_BfiGc-ZCPv7HXHlzZ94Jh-YE,806
@@ -286,9 +290,8 @@ parsl/tests/test_bash_apps/test_std_uri.py,sha256=CvAt8BUhNl2pA5chq9YyhkD6eo2IUH
286
290
  parsl/tests/test_bash_apps/test_stdout.py,sha256=lNBzCJGst0IhKaSl8CM8-mTJ5eaK7hTlZ8gY-M2TDBU,3244
287
291
  parsl/tests/test_checkpointing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
288
292
  parsl/tests/test_checkpointing/test_periodic.py,sha256=nfMgrG7sZ8rkMu6iOHS6lp_iTU4IsOyQLQ2Gur_FMmE,1509
289
- parsl/tests/test_checkpointing/test_python_checkpoint_1.py,sha256=k7_Zy4CV9OQt4ORYFCdyX53c4B0YPiwEIi35LhvLB2w,746
293
+ parsl/tests/test_checkpointing/test_python_checkpoint_1.py,sha256=TP6kSK_0qpCqecpp7O50AbTsnLKU6wvTvNG89hh4LQw,637
290
294
  parsl/tests/test_checkpointing/test_python_checkpoint_2.py,sha256=Q_cXeAVz_dJuDDeiemUIGd-wmb7aCY3ggpqYjRRhHRc,1089
291
- parsl/tests/test_checkpointing/test_python_checkpoint_3.py,sha256=y4esbbp1h9FP-_rBfnFhohB6a7o3VOpjqKdTovV8HbA,805
292
295
  parsl/tests/test_checkpointing/test_regression_232.py,sha256=AsI6AJ0DcFaefAbEY9qWa41ER0VX-4yLuIdlgvBw360,2637
293
296
  parsl/tests/test_checkpointing/test_regression_233.py,sha256=jii7BKuygK6KMIGtg4IeBjix7Z28cYhv57rE9ixoXMU,1774
294
297
  parsl/tests/test_checkpointing/test_regression_239.py,sha256=xycW1_IwVC55L25oMES_OzJU58TN5BoMvRUZ_xB69jU,2441
@@ -304,7 +307,7 @@ parsl/tests/test_error_handling/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm
304
307
  parsl/tests/test_error_handling/test_fail.py,sha256=xx4TGWfL7le4cQ9nvnUkrlmKQJkskhD0l_3W1xwZSEI,282
305
308
  parsl/tests/test_error_handling/test_python_walltime.py,sha256=rdmGZHIkuann2Njt3i62odKJ0FaODGr7-L96rOXNVYg,950
306
309
  parsl/tests/test_error_handling/test_rand_fail.py,sha256=crFg4GmwdDpvx49_7w5Xt2P7H2R_V9f6i1Ar-QkASuU,3864
307
- parsl/tests/test_error_handling/test_resource_spec.py,sha256=gUS_lN7CcvOh_GeMY8DtZTh6LhizPfrVrYAJpt9XSYM,1428
310
+ parsl/tests/test_error_handling/test_resource_spec.py,sha256=uOYGHf2EC3cn4-G5ZYWK8WxXl_QONQfn9E0Tk7RJrGA,1467
308
311
  parsl/tests/test_error_handling/test_retries.py,sha256=zJ9D2hrvXQURnK2OIf5LfQFcSDVZ8rhdpp6peGccY7s,2372
309
312
  parsl/tests/test_error_handling/test_retry_handler.py,sha256=8fMHffMBLhRyNreIqkrwamx9TYRZ498uVYNlkcbAoLU,1407
310
313
  parsl/tests/test_error_handling/test_retry_handler_failure.py,sha256=GaGtZZCB9Wb7ieShqTrxUFEUSKy07ZZWytCY4Qixk9Y,552
@@ -321,12 +324,13 @@ parsl/tests/test_htex/test_disconnected_blocks.py,sha256=3V1Ol9gMS6knjLTgIjB5Gru
321
324
  parsl/tests/test_htex/test_disconnected_blocks_failing_provider.py,sha256=eOdipRpKMOkWAXB3UtY1UjqTiwfNs_csNLve8vllG_M,2040
322
325
  parsl/tests/test_htex/test_drain.py,sha256=gYA7qzbv5ozox3clVdW0rlxAzwa_f_P0kqsAez3tIfk,2370
323
326
  parsl/tests/test_htex/test_htex.py,sha256=J1uEGezic8ziPPZsQwfK9iNiTJ53NqXMhIg9CUunjZw,4901
327
+ parsl/tests/test_htex/test_interchange_exit_bad_registration.py,sha256=3yqX_VVQz9fCEiV6Wd1BlcFYcARDDpNaR6ws7LWn-oc,4549
324
328
  parsl/tests/test_htex/test_manager_failure.py,sha256=N-obuSZ8f7XA_XcddoN2LWKSVtpKUZvTHb7BFelS3iQ,1143
325
329
  parsl/tests/test_htex/test_manager_selector_by_block.py,sha256=VQqSE6MDhGpDSjShGUTbj7l9Ahuj2tC9qD--o4puF44,1310
326
330
  parsl/tests/test_htex/test_managers_command.py,sha256=Y-eUjtBzwW9erCYdph9bOesbkUvX8QUPqXt27DCgVS8,951
327
331
  parsl/tests/test_htex/test_missing_worker.py,sha256=gyp5i7_t-JHyJGtz_eXZKKBY5w8oqLOIxO6cJgGJMtQ,745
328
332
  parsl/tests/test_htex/test_multiple_disconnected_blocks.py,sha256=2vXZoIx4NuAWYuiNoL5Gxr85w72qZ7Kdb3JGh0FufTg,1867
329
- parsl/tests/test_htex/test_resource_spec_validation.py,sha256=VzOk4rjMNiDcEVLb-3YdlYZND7HRoGACJkTwq8NUTnc,1102
333
+ parsl/tests/test_htex/test_resource_spec_validation.py,sha256=JqboQRRFV0tEfWrGOdYT9pHazsUjyZLbF7qqnLFS_-A,914
330
334
  parsl/tests/test_htex/test_worker_failure.py,sha256=Uz-RHI-LK78FMjXUvrUFmo4iYfmpDVBUcBxxRb3UG9M,603
331
335
  parsl/tests/test_htex/test_zmq_binding.py,sha256=WNFsCKKfid2uEfem0WLgl1wnBncIabpAv6kmg3imBxk,4001
332
336
  parsl/tests/test_monitoring/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -357,21 +361,21 @@ parsl/tests/test_python_apps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
357
361
  parsl/tests/test_python_apps/test_arg_input_types.py,sha256=JXpfHiu8lr9BN6u1OzqFvGwBhxzsGTPMewHx6Wdo-HI,670
358
362
  parsl/tests/test_python_apps/test_basic.py,sha256=lFqh4ugePbp_FRiHGUXxzV34iS7l8C5UkxTHuLcpnYs,855
359
363
  parsl/tests/test_python_apps/test_context_manager.py,sha256=8kUgcxN-6cz2u-lUoDhMAgu_ObUwEZvE3Eyxra6pFCo,3869
360
- parsl/tests/test_python_apps/test_dep_standard_futures.py,sha256=a3decndowPh8ma641BbxFAyMUZFGMT00TYpa7Y-7dV8,860
364
+ parsl/tests/test_python_apps/test_dep_standard_futures.py,sha256=kMOMZLaxJMmpABCUVniDIOIfkEqflZyhKjS_wkDti7A,1049
361
365
  parsl/tests/test_python_apps/test_dependencies.py,sha256=IRiTI_lPoWBSFSFnaBlE6Bv08PKEaf-qj5dfqO2RjT0,272
362
366
  parsl/tests/test_python_apps/test_dependencies_deep.py,sha256=Cuow2LLGY7zffPFj89AOIwKlXxHtsin3v_UIhfdwV_w,1542
363
367
  parsl/tests/test_python_apps/test_depfail_propagation.py,sha256=3q3HlVWrOixFtXWBvR_ypKtbdAHAJcKndXQ5drwrBQU,1488
364
- parsl/tests/test_python_apps/test_fail.py,sha256=O_TfnGUI4qKh7Q9zSZnfWgrgAhHlBabYsWvRzHQXtMA,1036
368
+ parsl/tests/test_python_apps/test_fail.py,sha256=gMuZwxZNaUCaonlUX-7SOBvXg8kidkBcEeqKLEvqpYM,1692
365
369
  parsl/tests/test_python_apps/test_fibonacci_iterative.py,sha256=ly2s5HuB9R53Z2FM_zy0WWdOk01iVhgcwSpQyK6ErIY,573
366
370
  parsl/tests/test_python_apps/test_fibonacci_recursive.py,sha256=q7LMFcu_pJSNPdz8iY0UiRoIweEWIBGwMjQffHWAuDc,592
367
371
  parsl/tests/test_python_apps/test_futures.py,sha256=EWnzmPn5sVCgeMxc0Uz2ieaaVYr98tFZ7g8YJFqYuC8,2355
368
372
  parsl/tests/test_python_apps/test_garbage_collect.py,sha256=RPntrLuzPkeNbhS7mmqEnHbyOcuV1YVppgZ8BaX-h84,1076
369
373
  parsl/tests/test_python_apps/test_import_fail.py,sha256=Vd8IMa_UsbHYkr3IGnS-rgGb6zKxB1tOTqMZY5lc_xY,691
370
374
  parsl/tests/test_python_apps/test_inputs_default.py,sha256=J2GR1NgdvEucNSJkfO6GC5OoMiuvSzO0tASCowT8HM0,436
371
- parsl/tests/test_python_apps/test_join.py,sha256=qnwdPYC_uIS5hQ2jmU2nIP_3P_TaMY8Av1ut10EZA_M,2678
375
+ parsl/tests/test_python_apps/test_join.py,sha256=OWd6_A0Cf-1Xpjr0OT3HaJ1IMYcJ0LFL1VnmL0cZkL8,2988
372
376
  parsl/tests/test_python_apps/test_lifted.py,sha256=Na6qC_dZSeYJcZdkGn-dCjgYkQV267HmGFfaqFcRVcQ,3408
373
377
  parsl/tests/test_python_apps/test_mapred.py,sha256=C7nTl0NsP_2TCtcmZXWFMpvAG4pwGswrIJKr-5sRUNY,786
374
- parsl/tests/test_python_apps/test_memoize_1.py,sha256=PXazRnekBe_KScUdbh8P3I7Vu_1Tc-nGssWBpfcic7M,514
378
+ parsl/tests/test_python_apps/test_memoize_1.py,sha256=cXQ-t87qKEphQDLpxCoMPQPoh5npGHHomQiHLGfrgeA,461
375
379
  parsl/tests/test_python_apps/test_memoize_2.py,sha256=uG9zG9j3ap1FqeJ8aB0Gj_dX191pN3dxWXeQ-asxPgU,553
376
380
  parsl/tests/test_python_apps/test_memoize_4.py,sha256=CdK_vHW5s-phi5KPqcAQm_BRh8xek91GVGeQRjfJ4Bk,569
377
381
  parsl/tests/test_python_apps/test_memoize_bad_id_for_memo.py,sha256=5v25zdU6koXexRTkccj_3sSSdXqHdsU8ZdNrnZ3ONZU,1436
@@ -445,18 +449,19 @@ parsl/tests/test_utils/test_sanitize_dns.py,sha256=8P_v5a5JLGU76OYf0LtclAwqJxGU0
445
449
  parsl/tests/unit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
446
450
  parsl/tests/unit/test_address.py,sha256=LL9qhp00JFG5lDN7-lY1YtuhTDlKHXHHp3a9TX06c84,682
447
451
  parsl/tests/unit/test_file.py,sha256=vLycnYcv3bvSzL-FV8WdoibqTyb41BrH1LUYBavobsg,2850
452
+ parsl/tests/unit/test_globus_compute_executor.py,sha256=9BWKZ4C03tQ5gZ3jxIsDt5j2yyYHa_VHqULJPeM7YPM,3238
448
453
  parsl/tests/unit/test_usage_tracking.py,sha256=xEfUlbBRpsFdUdOrCsk1Kz5AfmMxJT7f0_esZl8Ft-0,1884
449
454
  parsl/usage_tracking/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
450
455
  parsl/usage_tracking/api.py,sha256=iaCY58Dc5J4UM7_dJzEEs871P1p1HdxBMtNGyVdzc9g,1821
451
456
  parsl/usage_tracking/levels.py,sha256=xbfzYEsd55KiZJ-mzNgPebvOH4rRHum04hROzEf41tU,291
452
- parsl/usage_tracking/usage.py,sha256=tcoZ2OUjsQVakG8Uu9_HFuEdzpSHyt4JarSRcLGnSMw,8918
453
- parsl-2025.1.13.data/scripts/exec_parsl_function.py,sha256=YXKVVIa4zXmOtz-0Ca4E_5nQfN_3S2bh2tB75uZZB4w,7774
454
- parsl-2025.1.13.data/scripts/interchange.py,sha256=rUhF_Bwk5NOqLhh-HgP-ei_gclKnPIJJ7uS32p0j-XI,30129
455
- parsl-2025.1.13.data/scripts/parsl_coprocess.py,sha256=zrVjEqQvFOHxsLufPi00xzMONagjVwLZbavPM7bbjK4,5722
456
- parsl-2025.1.13.data/scripts/process_worker_pool.py,sha256=82FoJTye2SysJzPg-N8BpenuHGU7hOI8-Bedq8HV9C0,41851
457
- parsl-2025.1.13.dist-info/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
458
- parsl-2025.1.13.dist-info/METADATA,sha256=J-S4YBjyOytgwrw8cuWoFMLhmLXTZ6jkR0EBVX5k3e4,3869
459
- parsl-2025.1.13.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
460
- parsl-2025.1.13.dist-info/entry_points.txt,sha256=XqnsWDYoEcLbsMcpnYGKLEnSBmaIe1YoM5YsBdJG2tI,176
461
- parsl-2025.1.13.dist-info/top_level.txt,sha256=PIheYoUFQtF2icLsgOykgU-Cjuwr2Oi6On2jo5RYgRM,6
462
- parsl-2025.1.13.dist-info/RECORD,,
457
+ parsl/usage_tracking/usage.py,sha256=f9k6QcpbQxkGyP5WTC9PVyv0CA05s9NDpRe5wwRdBTM,9163
458
+ parsl-2025.1.27.data/scripts/exec_parsl_function.py,sha256=YXKVVIa4zXmOtz-0Ca4E_5nQfN_3S2bh2tB75uZZB4w,7774
459
+ parsl-2025.1.27.data/scripts/interchange.py,sha256=dAo8zl82gUFaeu_vNz-OXjkbeORZmwnqj4CMv8DahKY,29130
460
+ parsl-2025.1.27.data/scripts/parsl_coprocess.py,sha256=zrVjEqQvFOHxsLufPi00xzMONagjVwLZbavPM7bbjK4,5722
461
+ parsl-2025.1.27.data/scripts/process_worker_pool.py,sha256=82FoJTye2SysJzPg-N8BpenuHGU7hOI8-Bedq8HV9C0,41851
462
+ parsl-2025.1.27.dist-info/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
463
+ parsl-2025.1.27.dist-info/METADATA,sha256=50SqJsFVPrLu5f6YaTRDepbgCegoonAW_d_t-4P5mm8,4027
464
+ parsl-2025.1.27.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
465
+ parsl-2025.1.27.dist-info/entry_points.txt,sha256=XqnsWDYoEcLbsMcpnYGKLEnSBmaIe1YoM5YsBdJG2tI,176
466
+ parsl-2025.1.27.dist-info/top_level.txt,sha256=PIheYoUFQtF2icLsgOykgU-Cjuwr2Oi6On2jo5RYgRM,6
467
+ parsl-2025.1.27.dist-info/RECORD,,
@@ -1,42 +0,0 @@
1
- import os
2
-
3
- import pytest
4
-
5
- import parsl
6
- from parsl.app.app import python_app
7
- from parsl.tests.configs.local_threads import config
8
-
9
-
10
- def local_setup():
11
- global dfk
12
- dfk = parsl.load(config)
13
-
14
-
15
- def local_teardown():
16
- parsl.dfk().cleanup()
17
-
18
-
19
- @python_app
20
- def slow_double(x, sleep_dur=1, cache=True):
21
- import time
22
- time.sleep(sleep_dur)
23
- return x * 2
24
-
25
-
26
- @pytest.mark.local
27
- def test_checkpointing():
28
- """Testing code snippet from documentation
29
- """
30
-
31
- N = 5 # Number of calls to slow_double
32
- d = [] # List to store the futures
33
- for i in range(0, N):
34
- d.append(slow_double(i))
35
-
36
- # Wait for the results
37
- [i.result() for i in d]
38
-
39
- checkpoint_dir = dfk.checkpoint()
40
- print(checkpoint_dir)
41
-
42
- assert os.path.exists(checkpoint_dir), "Checkpoint dir does not exist"