dbos 1.8.0a8__tar.gz → 1.9.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of dbos might be problematic. Click here for more details.

Files changed (109) hide show
  1. {dbos-1.8.0a8 → dbos-1.9.0}/PKG-INFO +1 -1
  2. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_core.py +2 -1
  3. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_dbos.py +25 -25
  4. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/cli/cli.py +6 -6
  5. {dbos-1.8.0a8 → dbos-1.9.0}/pyproject.toml +1 -1
  6. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_admin_server.py +12 -7
  7. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_async.py +9 -7
  8. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_async_workflow_management.py +3 -3
  9. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_classdecorators.py +27 -0
  10. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_concurrency.py +9 -3
  11. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_dbos.py +40 -20
  12. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_failures.py +8 -4
  13. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_fastapi.py +3 -1
  14. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_flask.py +3 -1
  15. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_queue.py +11 -6
  16. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_scheduler.py +3 -1
  17. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_workflow_introspection.py +27 -9
  18. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_workflow_management.py +10 -6
  19. {dbos-1.8.0a8 → dbos-1.9.0}/LICENSE +0 -0
  20. {dbos-1.8.0a8 → dbos-1.9.0}/README.md +0 -0
  21. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/__init__.py +0 -0
  22. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/__main__.py +0 -0
  23. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_admin_server.py +0 -0
  24. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_app_db.py +0 -0
  25. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_classproperty.py +0 -0
  26. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_client.py +0 -0
  27. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_conductor/conductor.py +0 -0
  28. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_conductor/protocol.py +0 -0
  29. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_context.py +0 -0
  30. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_croniter.py +0 -0
  31. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_dbos_config.py +0 -0
  32. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_debug.py +0 -0
  33. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_docker_pg_helper.py +0 -0
  34. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_error.py +0 -0
  35. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_event_loop.py +0 -0
  36. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_fastapi.py +0 -0
  37. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_flask.py +0 -0
  38. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_kafka.py +0 -0
  39. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_kafka_message.py +0 -0
  40. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_logger.py +0 -0
  41. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_migrations/env.py +0 -0
  42. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_migrations/script.py.mako +0 -0
  43. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_migrations/versions/04ca4f231047_workflow_queues_executor_id.py +0 -0
  44. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_migrations/versions/27ac6900c6ad_add_queue_dedup.py +0 -0
  45. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_migrations/versions/50f3227f0b4b_fix_job_queue.py +0 -0
  46. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_migrations/versions/5c361fc04708_added_system_tables.py +0 -0
  47. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_migrations/versions/66478e1b95e5_consolidate_queues.py +0 -0
  48. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_migrations/versions/83f3732ae8e7_workflow_timeout.py +0 -0
  49. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_migrations/versions/933e86bdac6a_add_queue_priority.py +0 -0
  50. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_migrations/versions/a3b18ad34abe_added_triggers.py +0 -0
  51. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_migrations/versions/d76646551a6b_job_queue_limiter.py +0 -0
  52. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_migrations/versions/d76646551a6c_workflow_queue.py +0 -0
  53. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_migrations/versions/d994145b47b6_consolidate_inputs.py +0 -0
  54. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_migrations/versions/eab0cc1d9a14_job_queue.py +0 -0
  55. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_migrations/versions/f4b9b32ba814_functionname_childid_op_outputs.py +0 -0
  56. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_outcome.py +0 -0
  57. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_queue.py +0 -0
  58. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_recovery.py +0 -0
  59. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_registrations.py +0 -0
  60. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_roles.py +0 -0
  61. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_scheduler.py +0 -0
  62. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_schemas/__init__.py +0 -0
  63. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_schemas/application_database.py +0 -0
  64. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_schemas/system_database.py +0 -0
  65. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_serialization.py +0 -0
  66. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_sys_db.py +0 -0
  67. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_templates/dbos-db-starter/README.md +0 -0
  68. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_templates/dbos-db-starter/__package/__init__.py +0 -0
  69. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_templates/dbos-db-starter/__package/main.py.dbos +0 -0
  70. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_templates/dbos-db-starter/__package/schema.py +0 -0
  71. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_templates/dbos-db-starter/alembic.ini +0 -0
  72. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_templates/dbos-db-starter/dbos-config.yaml.dbos +0 -0
  73. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_templates/dbos-db-starter/migrations/env.py.dbos +0 -0
  74. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_templates/dbos-db-starter/migrations/script.py.mako +0 -0
  75. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_templates/dbos-db-starter/migrations/versions/2024_07_31_180642_init.py +0 -0
  76. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_templates/dbos-db-starter/start_postgres_docker.py +0 -0
  77. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_tracer.py +0 -0
  78. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_utils.py +0 -0
  79. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/_workflow_commands.py +0 -0
  80. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/cli/_github_init.py +0 -0
  81. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/cli/_template_init.py +0 -0
  82. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/dbos-config.schema.json +0 -0
  83. {dbos-1.8.0a8 → dbos-1.9.0}/dbos/py.typed +0 -0
  84. {dbos-1.8.0a8 → dbos-1.9.0}/tests/__init__.py +0 -0
  85. {dbos-1.8.0a8 → dbos-1.9.0}/tests/atexit_no_ctor.py +0 -0
  86. {dbos-1.8.0a8 → dbos-1.9.0}/tests/atexit_no_launch.py +0 -0
  87. {dbos-1.8.0a8 → dbos-1.9.0}/tests/classdefs.py +0 -0
  88. {dbos-1.8.0a8 → dbos-1.9.0}/tests/client_collateral.py +0 -0
  89. {dbos-1.8.0a8 → dbos-1.9.0}/tests/client_worker.py +0 -0
  90. {dbos-1.8.0a8 → dbos-1.9.0}/tests/conftest.py +0 -0
  91. {dbos-1.8.0a8 → dbos-1.9.0}/tests/dupname_classdefs1.py +0 -0
  92. {dbos-1.8.0a8 → dbos-1.9.0}/tests/dupname_classdefsa.py +0 -0
  93. {dbos-1.8.0a8 → dbos-1.9.0}/tests/more_classdefs.py +0 -0
  94. {dbos-1.8.0a8 → dbos-1.9.0}/tests/queuedworkflow.py +0 -0
  95. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_cli.py +0 -0
  96. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_client.py +0 -0
  97. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_config.py +0 -0
  98. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_croniter.py +0 -0
  99. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_debug.py +0 -0
  100. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_docker_secrets.py +0 -0
  101. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_fastapi_roles.py +0 -0
  102. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_kafka.py +0 -0
  103. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_outcome.py +0 -0
  104. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_package.py +0 -0
  105. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_schema_migration.py +0 -0
  106. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_singleton.py +0 -0
  107. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_spans.py +0 -0
  108. {dbos-1.8.0a8 → dbos-1.9.0}/tests/test_sqlalchemy.py +0 -0
  109. {dbos-1.8.0a8 → dbos-1.9.0}/version/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dbos
3
- Version: 1.8.0a8
3
+ Version: 1.9.0
4
4
  Summary: Ultra-lightweight durable execution in Python
5
5
  Author-Email: "DBOS, Inc." <contact@dbos.dev>
6
6
  License: MIT
@@ -49,6 +49,7 @@ from ._context import (
49
49
  get_local_dbos_context,
50
50
  )
51
51
  from ._error import (
52
+ DBOSAwaitedWorkflowCancelledError,
52
53
  DBOSException,
53
54
  DBOSMaxStepRetriesExceeded,
54
55
  DBOSNonExistentWorkflowError,
@@ -370,7 +371,7 @@ def _get_wf_invoke_func(
370
371
  r: R = dbos._sys_db.await_workflow_result(status["workflow_uuid"])
371
372
  return r
372
373
  except DBOSWorkflowCancelledError as error:
373
- raise
374
+ raise DBOSAwaitedWorkflowCancelledError(status["workflow_uuid"])
374
375
  except Exception as error:
375
376
  if not dbos.debug_mode:
376
377
  dbos._sys_db.update_workflow_outcome(
@@ -1,7 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import asyncio
4
- import atexit
5
4
  import hashlib
6
5
  import inspect
7
6
  import os
@@ -1219,39 +1218,40 @@ class DBOS:
1219
1218
  return rv
1220
1219
 
1221
1220
  @classproperty
1222
- def workflow_id(cls) -> str:
1223
- """Return the workflow ID for the current context, which must be executing a workflow function."""
1224
- ctx = assert_current_dbos_context()
1225
- assert (
1226
- ctx.is_within_workflow()
1227
- ), "workflow_id is only available within a DBOS operation."
1228
- return ctx.workflow_id
1221
+ def workflow_id(cls) -> Optional[str]:
1222
+ """Return the ID of the currently executing workflow. If a workflow is not executing, return None."""
1223
+ ctx = get_local_dbos_context()
1224
+ if ctx and ctx.is_within_workflow():
1225
+ return ctx.workflow_id
1226
+ else:
1227
+ return None
1229
1228
 
1230
1229
  @classproperty
1231
- def step_id(cls) -> int:
1232
- """Return the step ID for the currently executing step. This is a unique identifier of the current step within the workflow."""
1233
- ctx = assert_current_dbos_context()
1234
- assert (
1235
- ctx.is_step() or ctx.is_transaction()
1236
- ), "step_id is only available within a DBOS step."
1237
- return ctx.function_id
1230
+ def step_id(cls) -> Optional[int]:
1231
+ """Return the step ID for the currently executing step. This is a unique identifier of the current step within the workflow. If a step is not currently executing, return None."""
1232
+ ctx = get_local_dbos_context()
1233
+ if ctx and (ctx.is_step() or ctx.is_transaction()):
1234
+ return ctx.function_id
1235
+ else:
1236
+ return None
1238
1237
 
1239
1238
  @classproperty
1240
- def step_status(cls) -> StepStatus:
1241
- """Return the status of the currently executing step."""
1242
- ctx = assert_current_dbos_context()
1243
- assert ctx.is_step(), "step_status is only available within a DBOS step."
1244
- assert ctx.step_status is not None
1245
- return ctx.step_status
1239
+ def step_status(cls) -> Optional[StepStatus]:
1240
+ """Return the status of the currently executing step. If a step is not currently executing, return None."""
1241
+ ctx = get_local_dbos_context()
1242
+ if ctx and ctx.is_step():
1243
+ return ctx.step_status
1244
+ else:
1245
+ return None
1246
1246
 
1247
1247
  @classproperty
1248
1248
  def parent_workflow_id(cls) -> str:
1249
1249
  """
1250
- Return the workflow ID for the parent workflow.
1251
-
1252
- `parent_workflow_id` must be accessed from within a workflow function.
1250
+ This method is deprecated and should not be used.
1253
1251
  """
1254
-
1252
+ dbos_logger.warning(
1253
+ "DBOS.parent_workflow_id is deprecated and should not be used"
1254
+ )
1255
1255
  ctx = assert_current_dbos_context()
1256
1256
  assert (
1257
1257
  ctx.is_within_workflow()
@@ -10,7 +10,7 @@ from typing import Any, Optional
10
10
  import jsonpickle # type: ignore
11
11
  import sqlalchemy as sa
12
12
  import typer
13
- from rich import print
13
+ from rich import print as richprint
14
14
  from rich.prompt import IntPrompt
15
15
  from typing_extensions import Annotated, List
16
16
 
@@ -196,7 +196,7 @@ def init(
196
196
  path.join(templates_dir, template), project_name, config_mode=config
197
197
  )
198
198
  except Exception as e:
199
- print(f"[red]{e}[/red]")
199
+ richprint(f"[red]{e}[/red]")
200
200
 
201
201
 
202
202
  def _resolve_project_name_and_template(
@@ -217,9 +217,9 @@ def _resolve_project_name_and_template(
217
217
  if template not in templates:
218
218
  raise Exception(f"Template {template} not found in {templates_dir}")
219
219
  else:
220
- print("\n[bold]Available templates:[/bold]")
220
+ richprint("\n[bold]Available templates:[/bold]")
221
221
  for idx, template_name in enumerate(templates, 1):
222
- print(f" {idx}. {template_name}")
222
+ richprint(f" {idx}. {template_name}")
223
223
  while True:
224
224
  try:
225
225
  choice = IntPrompt.ask(
@@ -231,13 +231,13 @@ def _resolve_project_name_and_template(
231
231
  template = templates[choice - 1]
232
232
  break
233
233
  else:
234
- print(
234
+ richprint(
235
235
  "[red]Invalid selection. Please choose a number from the list.[/red]"
236
236
  )
237
237
  except (KeyboardInterrupt, EOFError):
238
238
  raise typer.Abort()
239
239
  except ValueError:
240
- print("[red]Please enter a valid number.[/red]")
240
+ richprint("[red]Please enter a valid number.[/red]")
241
241
 
242
242
  if template in git_templates:
243
243
  if project_name is None:
@@ -27,7 +27,7 @@ dependencies = [
27
27
  ]
28
28
  requires-python = ">=3.9"
29
29
  readme = "README.md"
30
- version = "1.8.0a8"
30
+ version = "1.9.0"
31
31
 
32
32
  [project.license]
33
33
  text = "MIT"
@@ -20,7 +20,7 @@ from dbos import (
20
20
  WorkflowHandle,
21
21
  _workflow_commands,
22
22
  )
23
- from dbos._error import DBOSWorkflowCancelledError
23
+ from dbos._error import DBOSAwaitedWorkflowCancelledError
24
24
  from dbos._schemas.system_database import SystemSchema
25
25
  from dbos._sys_db import SystemDatabase, WorkflowStatusString
26
26
  from dbos._utils import INTERNAL_QUEUE_NAME, GlobalParams
@@ -142,7 +142,6 @@ def test_admin_recovery(config: DBOSConfig) -> None:
142
142
 
143
143
  @DBOS.workflow()
144
144
  def test_workflow(var: str, var2: str) -> str:
145
- DBOS.logger.info("WFID: " + DBOS.workflow_id)
146
145
  nonlocal wf_counter
147
146
  wf_counter += 1
148
147
  res = test_step(var2)
@@ -307,7 +306,7 @@ def test_admin_workflow_resume(dbos: DBOS, sys_db: SystemDatabase) -> None:
307
306
  )
308
307
  assert response.status_code == 204
309
308
  event.set()
310
- with pytest.raises(DBOSWorkflowCancelledError):
309
+ with pytest.raises(DBOSAwaitedWorkflowCancelledError):
311
310
  handle.get_result()
312
311
  info = _workflow_commands.get_workflow(sys_db, wfid)
313
312
  assert info is not None
@@ -464,7 +463,9 @@ def test_list_workflows(dbos: DBOS) -> None:
464
463
 
465
464
  @DBOS.workflow()
466
465
  def test_workflow_2(my_time: datetime) -> str:
467
- return DBOS.workflow_id + " completed at " + my_time.isoformat()
466
+ workflow_id = DBOS.workflow_id
467
+ assert workflow_id is not None
468
+ return workflow_id + " completed at " + my_time.isoformat()
468
469
 
469
470
  # Start workflows
470
471
  handle_1 = DBOS.start_workflow(test_workflow_1)
@@ -656,7 +657,9 @@ def test_get_workflow_by_id(dbos: DBOS) -> None:
656
657
 
657
658
  @DBOS.workflow()
658
659
  def test_workflow_2(my_time: datetime) -> str:
659
- return DBOS.workflow_id + " completed at " + my_time.isoformat()
660
+ workflow_id = DBOS.workflow_id
661
+ assert workflow_id is not None
662
+ return workflow_id + " completed at " + my_time.isoformat()
660
663
 
661
664
  # Start workflows
662
665
  handle_1 = DBOS.start_workflow(test_workflow_1)
@@ -713,7 +716,9 @@ def test_admin_garbage_collect(dbos: DBOS) -> None:
713
716
 
714
717
  @DBOS.workflow()
715
718
  def workflow() -> str:
716
- return DBOS.workflow_id
719
+ workflow_id = DBOS.workflow_id
720
+ assert workflow_id is not None
721
+ return workflow_id
717
722
 
718
723
  workflow()
719
724
 
@@ -745,7 +750,7 @@ def test_admin_global_timeout(dbos: DBOS) -> None:
745
750
  timeout=5,
746
751
  )
747
752
  response.raise_for_status()
748
- with pytest.raises(DBOSWorkflowCancelledError):
753
+ with pytest.raises(DBOSAwaitedWorkflowCancelledError):
749
754
  handle.get_result()
750
755
 
751
756
 
@@ -18,7 +18,7 @@ from dbos import (
18
18
  from dbos._context import assert_current_dbos_context
19
19
  from dbos._dbos import WorkflowHandle
20
20
  from dbos._dbos_config import ConfigFile
21
- from dbos._error import DBOSException, DBOSWorkflowCancelledError
21
+ from dbos._error import DBOSAwaitedWorkflowCancelledError, DBOSException
22
22
 
23
23
 
24
24
  @pytest.mark.asyncio
@@ -302,7 +302,9 @@ async def test_sleep(dbos: DBOS) -> None:
302
302
  @DBOS.workflow()
303
303
  async def test_sleep_workflow(secs: float) -> str:
304
304
  await dbos.sleep_async(secs)
305
- return DBOS.workflow_id
305
+ workflow_id = DBOS.workflow_id
306
+ assert workflow_id is not None
307
+ return workflow_id
306
308
 
307
309
  start_time = time.time()
308
310
  sleep_uuid = await test_sleep_workflow(1.5)
@@ -490,20 +492,20 @@ async def test_workflow_timeout_async(dbos: DBOS) -> None:
490
492
  DBOS.sleep(0.1)
491
493
 
492
494
  with SetWorkflowTimeout(0.1):
493
- with pytest.raises(DBOSWorkflowCancelledError):
495
+ with pytest.raises(DBOSAwaitedWorkflowCancelledError):
494
496
  await blocked_workflow()
495
497
  handle = await DBOS.start_workflow_async(blocked_workflow)
496
- with pytest.raises(DBOSWorkflowCancelledError):
498
+ with pytest.raises(DBOSAwaitedWorkflowCancelledError):
497
499
  await handle.get_result()
498
500
 
499
501
  @DBOS.workflow()
500
502
  async def parent_workflow_with_timeout() -> None:
501
503
  assert assert_current_dbos_context().workflow_deadline_epoch_ms is None
502
504
  with SetWorkflowTimeout(0.1):
503
- with pytest.raises(DBOSWorkflowCancelledError):
505
+ with pytest.raises(DBOSAwaitedWorkflowCancelledError):
504
506
  await blocked_workflow()
505
507
  handle = await DBOS.start_workflow_async(blocked_workflow)
506
- with pytest.raises(DBOSWorkflowCancelledError):
508
+ with pytest.raises(DBOSAwaitedWorkflowCancelledError):
507
509
  await handle.get_result()
508
510
  assert assert_current_dbos_context().workflow_deadline_epoch_ms is None
509
511
 
@@ -524,7 +526,7 @@ async def test_workflow_timeout_async(dbos: DBOS) -> None:
524
526
  # Verify if a parent called with a timeout calls a blocked child
525
527
  # the deadline propagates and the children are also cancelled.
526
528
  with SetWorkflowTimeout(1.0):
527
- with pytest.raises(DBOSWorkflowCancelledError):
529
+ with pytest.raises(DBOSAwaitedWorkflowCancelledError):
528
530
  await parent_workflow()
529
531
 
530
532
  with pytest.raises(Exception) as exc_info:
@@ -7,7 +7,7 @@ from typing import List
7
7
  import pytest
8
8
 
9
9
  from dbos import DBOS, Queue, SetWorkflowID
10
- from dbos._error import DBOSWorkflowCancelledError
10
+ from dbos._error import DBOSAwaitedWorkflowCancelledError
11
11
  from dbos._sys_db import StepInfo, WorkflowStatus
12
12
  from tests.conftest import queue_entries_are_cleaned_up
13
13
 
@@ -46,7 +46,7 @@ async def test_cancel_workflow_async(dbos: DBOS) -> None:
46
46
  await DBOS.cancel_workflow_async(wfid)
47
47
  workflow_event.set()
48
48
 
49
- with pytest.raises(DBOSWorkflowCancelledError):
49
+ with pytest.raises(DBOSAwaitedWorkflowCancelledError):
50
50
  handle.get_result()
51
51
  assert steps_completed == 1
52
52
 
@@ -85,7 +85,7 @@ async def test_resume_workflow_async(dbos: DBOS) -> None:
85
85
  DBOS.cancel_workflow(wfid)
86
86
  workflow_event.set()
87
87
 
88
- with pytest.raises(DBOSWorkflowCancelledError):
88
+ with pytest.raises(DBOSAwaitedWorkflowCancelledError):
89
89
  handle.get_result()
90
90
  assert steps_completed == 1
91
91
 
@@ -911,3 +911,30 @@ def test_class_step_without_dbos(dbos: DBOS, config: DBOSConfig) -> None:
911
911
  DBOS.launch()
912
912
 
913
913
  assert inst.step(input) == input + input
914
+
915
+
916
+ def test_class_with_only_steps(dbos: DBOS) -> None:
917
+
918
+ class StepClass:
919
+ def __init__(self, x: int) -> None:
920
+ self.x = x
921
+
922
+ @DBOS.step()
923
+ def step(self, x: int, expr: Callable[[int, int], int]) -> int:
924
+ return expr(self.x, x)
925
+
926
+ input = 5
927
+ inst = StepClass(5)
928
+
929
+ l = lambda x, y: x + y
930
+
931
+ @DBOS.workflow()
932
+ def test_workflow() -> int:
933
+ return inst.step(input, l) + inst.step(input, l)
934
+
935
+ handle = DBOS.start_workflow(test_workflow)
936
+ assert handle.get_result() == input * 4
937
+
938
+ steps = DBOS.list_workflow_steps(handle.workflow_id)
939
+ assert len(steps) == 2
940
+ assert steps[1]["output"] == steps[1]["output"] == input * 2
@@ -14,7 +14,9 @@ def test_concurrent_workflows(dbos: DBOS) -> None:
14
14
  @DBOS.workflow()
15
15
  def test_workflow() -> str:
16
16
  time.sleep(1)
17
- return DBOS.workflow_id
17
+ workflow_id = DBOS.workflow_id
18
+ assert workflow_id is not None
19
+ return workflow_id
18
20
 
19
21
  def test_thread(id: str) -> str:
20
22
  with SetWorkflowID(id):
@@ -48,7 +50,9 @@ def test_concurrent_conflict_uuid(dbos: DBOS) -> None:
48
50
  condition.notify()
49
51
  condition.release()
50
52
 
51
- return DBOS.workflow_id
53
+ workflow_id = DBOS.workflow_id
54
+ assert workflow_id is not None
55
+ return workflow_id
52
56
 
53
57
  @DBOS.workflow()
54
58
  def test_workflow() -> str:
@@ -74,7 +78,9 @@ def test_concurrent_conflict_uuid(dbos: DBOS) -> None:
74
78
  condition.notify()
75
79
  condition.release()
76
80
 
77
- return DBOS.workflow_id
81
+ workflow_id = DBOS.workflow_id
82
+ assert workflow_id is not None
83
+ return workflow_id
78
84
 
79
85
  def test_txn_thread(id: str) -> str:
80
86
  with SetWorkflowID(id):
@@ -28,7 +28,6 @@ from dbos._error import (
28
28
  DBOSAwaitedWorkflowCancelledError,
29
29
  DBOSConflictingRegistrationError,
30
30
  DBOSMaxStepRetriesExceeded,
31
- DBOSWorkflowCancelledError,
32
31
  )
33
32
  from dbos._schemas.system_database import SystemSchema
34
33
  from dbos._sys_db import GetWorkflowsInput
@@ -61,9 +60,11 @@ def test_simple_workflow(dbos: DBOS) -> None:
61
60
  @DBOS.step()
62
61
  def test_step(var: str) -> str:
63
62
  assert DBOS.step_id == 2
64
- assert DBOS.step_status.step_id == 2
65
- assert DBOS.step_status.current_attempt is None
66
- assert DBOS.step_status.max_attempts is None
63
+ step_status = DBOS.step_status
64
+ assert step_status is not None
65
+ assert step_status.step_id == 2
66
+ assert step_status.current_attempt is None
67
+ assert step_status.max_attempts is None
67
68
  nonlocal step_counter
68
69
  step_counter += 1
69
70
  DBOS.logger.info("I'm test_step " + var)
@@ -133,10 +134,6 @@ def test_child_workflow(dbos: DBOS) -> None:
133
134
  @DBOS.workflow()
134
135
  def test_workflow(var: str, var2: str) -> str:
135
136
  DBOS.logger.info("I'm test_workflow")
136
- if len(DBOS.parent_workflow_id):
137
- DBOS.logger.info(" This is a child test_workflow")
138
- # Note this assertion is only true if child wasn't assigned an ID explicitly
139
- assert DBOS.workflow_id.startswith(DBOS.parent_workflow_id)
140
137
  nonlocal wf_counter
141
138
  wf_counter += 1
142
139
  res = test_transaction(var2)
@@ -651,7 +648,9 @@ def test_retrieve_workflow(dbos: DBOS) -> None:
651
648
  @DBOS.workflow()
652
649
  def test_sleep_workflow(secs: float) -> str:
653
650
  dbos.sleep(secs)
654
- return DBOS.workflow_id
651
+ workflow_id = DBOS.workflow_id
652
+ assert workflow_id is not None
653
+ return workflow_id
655
654
 
656
655
  @DBOS.workflow()
657
656
  def test_sleep_workthrow(secs: float) -> str:
@@ -732,7 +731,9 @@ def test_retrieve_workflow_in_workflow(dbos: DBOS) -> None:
732
731
  @DBOS.workflow()
733
732
  def test_sleep_workflow(secs: float) -> str:
734
733
  dbos.sleep(secs)
735
- return DBOS.workflow_id
734
+ workflow_id = DBOS.workflow_id
735
+ assert workflow_id is not None
736
+ return workflow_id
736
737
 
737
738
  @DBOS.workflow()
738
739
  def test_workflow_status_a() -> str:
@@ -793,7 +794,9 @@ def test_sleep(dbos: DBOS) -> None:
793
794
  @DBOS.workflow()
794
795
  def test_sleep_workflow(secs: float) -> str:
795
796
  dbos.sleep(secs)
796
- return DBOS.workflow_id
797
+ workflow_id = DBOS.workflow_id
798
+ assert workflow_id is not None
799
+ return workflow_id
797
800
 
798
801
  start_time = time.time()
799
802
  sleep_uuid = test_sleep_workflow(1.5)
@@ -1489,7 +1492,7 @@ def test_workflow_timeout(dbos: DBOS) -> None:
1489
1492
  # Verify a blocked workflow called with a timeout is cancelled
1490
1493
  wfid = str(uuid.uuid4())
1491
1494
  with SetWorkflowTimeout(0.1):
1492
- with pytest.raises(DBOSWorkflowCancelledError):
1495
+ with pytest.raises(DBOSAwaitedWorkflowCancelledError):
1493
1496
  with SetWorkflowID(wfid):
1494
1497
  blocked_workflow()
1495
1498
  assert assert_current_dbos_context().workflow_deadline_epoch_ms is None
@@ -1501,7 +1504,7 @@ def test_workflow_timeout(dbos: DBOS) -> None:
1501
1504
  status.workflow_deadline_epoch_ms is not None
1502
1505
  and status.workflow_deadline_epoch_ms > start_time
1503
1506
  )
1504
- with pytest.raises(DBOSWorkflowCancelledError):
1507
+ with pytest.raises(DBOSAwaitedWorkflowCancelledError):
1505
1508
  handle.get_result()
1506
1509
 
1507
1510
  # Change the workflow status to pending
@@ -1514,17 +1517,17 @@ def test_workflow_timeout(dbos: DBOS) -> None:
1514
1517
  # Recover the workflow, verify it still times out
1515
1518
  handles = DBOS._recover_pending_workflows()
1516
1519
  assert len(handles) == 1
1517
- with pytest.raises(DBOSWorkflowCancelledError):
1520
+ with pytest.raises(DBOSAwaitedWorkflowCancelledError):
1518
1521
  handles[0].get_result()
1519
1522
 
1520
1523
  @DBOS.workflow()
1521
1524
  def parent_workflow_with_timeout() -> None:
1522
1525
  assert assert_current_dbos_context().workflow_deadline_epoch_ms is None
1523
1526
  with SetWorkflowTimeout(0.1):
1524
- with pytest.raises(DBOSWorkflowCancelledError):
1527
+ with pytest.raises(DBOSAwaitedWorkflowCancelledError):
1525
1528
  blocked_workflow()
1526
1529
  handle = DBOS.start_workflow(blocked_workflow)
1527
- with pytest.raises(DBOSWorkflowCancelledError):
1530
+ with pytest.raises(DBOSAwaitedWorkflowCancelledError):
1528
1531
  handle.get_result()
1529
1532
  assert assert_current_dbos_context().workflow_deadline_epoch_ms is None
1530
1533
 
@@ -1545,7 +1548,7 @@ def test_workflow_timeout(dbos: DBOS) -> None:
1545
1548
  # Verify if a parent called with a timeout calls a blocked child
1546
1549
  # the deadline propagates and the children are also cancelled.
1547
1550
  with SetWorkflowTimeout(1.0):
1548
- with pytest.raises(DBOSWorkflowCancelledError):
1551
+ with pytest.raises(DBOSAwaitedWorkflowCancelledError):
1549
1552
  parent_workflow()
1550
1553
 
1551
1554
  with pytest.raises(DBOSAwaitedWorkflowCancelledError):
@@ -1573,7 +1576,9 @@ def test_custom_names(dbos: DBOS) -> None:
1573
1576
 
1574
1577
  @DBOS.workflow(name=workflow_name)
1575
1578
  def workflow() -> str:
1576
- return DBOS.workflow_id
1579
+ workflow_id = DBOS.workflow_id
1580
+ assert workflow_id is not None
1581
+ return workflow_id
1577
1582
 
1578
1583
  handle = queue.enqueue(workflow)
1579
1584
  assert handle.get_status().name == workflow_name
@@ -1581,7 +1586,9 @@ def test_custom_names(dbos: DBOS) -> None:
1581
1586
 
1582
1587
  @DBOS.step(name=step_name)
1583
1588
  def step() -> str:
1584
- return DBOS.workflow_id
1589
+ workflow_id = DBOS.workflow_id
1590
+ assert workflow_id is not None
1591
+ return workflow_id
1585
1592
 
1586
1593
  handle = queue.enqueue(step)
1587
1594
  assert handle.get_status().name == f"<temp>.{step_name}"
@@ -1589,7 +1596,9 @@ def test_custom_names(dbos: DBOS) -> None:
1589
1596
 
1590
1597
  @DBOS.transaction(name=txn_name)
1591
1598
  def txn() -> str:
1592
- return DBOS.workflow_id
1599
+ workflow_id = DBOS.workflow_id
1600
+ assert workflow_id is not None
1601
+ return workflow_id
1593
1602
 
1594
1603
  handle = queue.enqueue(txn)
1595
1604
  assert handle.get_status().name == f"<temp>.{txn_name}"
@@ -1614,12 +1623,22 @@ def test_custom_names(dbos: DBOS) -> None:
1614
1623
  async def test_step_without_dbos(dbos: DBOS, config: DBOSConfig) -> None:
1615
1624
  DBOS.destroy(destroy_registry=True)
1616
1625
 
1626
+ is_dbos_active = False
1627
+
1617
1628
  @DBOS.step()
1618
1629
  def step(x: int) -> int:
1630
+ if is_dbos_active:
1631
+ assert DBOS.workflow_id is not None
1632
+ else:
1633
+ assert DBOS.workflow_id is None
1619
1634
  return x
1620
1635
 
1621
1636
  @DBOS.step()
1622
1637
  async def async_step(x: int) -> int:
1638
+ if is_dbos_active:
1639
+ assert DBOS.workflow_id is not None
1640
+ else:
1641
+ assert DBOS.workflow_id is None
1623
1642
  return x
1624
1643
 
1625
1644
  assert step(5) == 5
@@ -1631,6 +1650,7 @@ async def test_step_without_dbos(dbos: DBOS, config: DBOSConfig) -> None:
1631
1650
  assert await async_step(5) == 5
1632
1651
 
1633
1652
  DBOS.launch()
1653
+ is_dbos_active = True
1634
1654
 
1635
1655
  assert step(5) == 5
1636
1656
  assert await async_step(5) == 5
@@ -382,9 +382,11 @@ def test_step_status(dbos: DBOS) -> None:
382
382
  @DBOS.step(retries_allowed=True, interval_seconds=0, max_attempts=max_attempts)
383
383
  def failing_step() -> None:
384
384
  nonlocal step_counter
385
- assert DBOS.step_status.step_id == 1
386
- assert DBOS.step_status.current_attempt == step_counter
387
- assert DBOS.step_status.max_attempts == max_attempts
385
+ step_status = DBOS.step_status
386
+ assert step_status is not None
387
+ assert step_status.step_id == 1
388
+ assert step_status.current_attempt == step_counter
389
+ assert step_status.max_attempts == max_attempts
388
390
  step_counter += 1
389
391
  if step_counter < max_attempts:
390
392
  raise Exception("fail")
@@ -442,7 +444,9 @@ def test_keyboardinterrupt_during_retries(dbos: DBOS) -> None:
442
444
  @DBOS.workflow()
443
445
  def failing_workflow() -> str:
444
446
  failing_step()
445
- return DBOS.workflow_id
447
+ workflow_id = DBOS.workflow_id
448
+ assert workflow_id is not None
449
+ return workflow_id
446
450
 
447
451
  with pytest.raises(KeyboardInterrupt):
448
452
  failing_workflow()
@@ -112,7 +112,9 @@ def test_endpoint_recovery(dbos_fastapi: Tuple[DBOS, FastAPI]) -> None:
112
112
 
113
113
  @DBOS.workflow()
114
114
  def test_workflow(var1: str) -> tuple[str, str]:
115
- return var1, DBOS.workflow_id
115
+ workflow_id = DBOS.workflow_id
116
+ assert workflow_id is not None
117
+ return var1, workflow_id
116
118
 
117
119
  @app.get("/{var1}/{var2}")
118
120
  def test_endpoint(var1: str, var2: str) -> dict[str, str]:
@@ -72,7 +72,9 @@ def test_endpoint_recovery(dbos_flask: Tuple[DBOS, Flask]) -> None:
72
72
 
73
73
  @DBOS.workflow()
74
74
  def test_workflow(var1: str) -> tuple[str, str]:
75
- return var1, DBOS.workflow_id
75
+ workflow_id = DBOS.workflow_id
76
+ assert workflow_id is not None
77
+ return var1, workflow_id
76
78
 
77
79
  @app.route("/<var1>/<var2>")
78
80
  def test_endpoint(var1: str, var2: str) -> dict[str, str]:
@@ -1,5 +1,4 @@
1
1
  import asyncio
2
- import logging
3
2
  import multiprocessing
4
3
  import multiprocessing.synchronize
5
4
  import os
@@ -27,7 +26,7 @@ from dbos import (
27
26
  )
28
27
  from dbos._context import assert_current_dbos_context
29
28
  from dbos._dbos import WorkflowHandleAsync
30
- from dbos._error import DBOSAwaitedWorkflowCancelledError, DBOSWorkflowCancelledError
29
+ from dbos._error import DBOSAwaitedWorkflowCancelledError
31
30
  from dbos._schemas.system_database import SystemSchema
32
31
  from dbos._sys_db import WorkflowStatusString
33
32
  from dbos._utils import GlobalParams
@@ -943,7 +942,7 @@ def test_timeout_queue(dbos: DBOS) -> None:
943
942
 
944
943
  with SetWorkflowTimeout(1.0):
945
944
  handle = DBOS.start_workflow(blocked_parent_workflow)
946
- with pytest.raises(DBOSWorkflowCancelledError):
945
+ with pytest.raises(DBOSAwaitedWorkflowCancelledError):
947
946
  handle.get_result()
948
947
  with pytest.raises(DBOSAwaitedWorkflowCancelledError):
949
948
  DBOS.retrieve_workflow(child_id).get_result()
@@ -1343,7 +1342,9 @@ def test_worker_concurrency_across_versions(dbos: DBOS, client: DBOSClient) -> N
1343
1342
 
1344
1343
  @DBOS.workflow()
1345
1344
  def test_workflow() -> str:
1346
- return DBOS.workflow_id
1345
+ workflow_id = DBOS.workflow_id
1346
+ assert workflow_id is not None
1347
+ return workflow_id
1347
1348
 
1348
1349
  # First enqueue a workflow on the other version, then on the current version
1349
1350
  other_version = "other_version"
@@ -1417,7 +1418,9 @@ def test_unsetting_timeout(dbos: DBOS) -> None:
1417
1418
  def child() -> str:
1418
1419
  for _ in range(5):
1419
1420
  DBOS.sleep(1)
1420
- return DBOS.workflow_id
1421
+ workflow_id = DBOS.workflow_id
1422
+ assert workflow_id is not None
1423
+ return workflow_id
1421
1424
 
1422
1425
  @DBOS.workflow()
1423
1426
  def parent(child_one: str, child_two: str) -> None:
@@ -1448,7 +1451,9 @@ def test_queue_executor_id(dbos: DBOS) -> None:
1448
1451
 
1449
1452
  @DBOS.workflow()
1450
1453
  def example_workflow() -> str:
1451
- return DBOS.workflow_id
1454
+ workflow_id = DBOS.workflow_id
1455
+ assert workflow_id is not None
1456
+ return workflow_id
1452
1457
 
1453
1458
  # Set an executor ID
1454
1459
  original_executor_id = str(uuid.uuid4())
@@ -195,7 +195,9 @@ def test_scheduler_oaoo(dbos: DBOS) -> None:
195
195
  nonlocal wf_counter
196
196
  wf_counter += 1
197
197
  nonlocal workflow_id
198
- workflow_id = DBOS.workflow_id
198
+ wf_id = DBOS.workflow_id
199
+ assert wf_id is not None
200
+ workflow_id = wf_id
199
201
 
200
202
  @DBOS.transaction()
201
203
  def test_transaction() -> None:
@@ -456,7 +456,9 @@ def test_set_get_event(dbos: DBOS) -> None:
456
456
  DBOS.set_event("key", value)
457
457
  stepOne()
458
458
  DBOS.get_event("fake_id", "fake_value", 0)
459
- return DBOS.get_event(DBOS.workflow_id, "key", 1)
459
+ workflow_id = DBOS.workflow_id
460
+ assert workflow_id is not None
461
+ return DBOS.get_event(workflow_id, "key", 1)
460
462
 
461
463
  @DBOS.step()
462
464
  def stepOne() -> None:
@@ -500,7 +502,9 @@ def test_callchild_first_sync(dbos: DBOS) -> None:
500
502
 
501
503
  @DBOS.workflow()
502
504
  def child_workflow() -> str:
503
- return DBOS.workflow_id
505
+ workflow_id = DBOS.workflow_id
506
+ assert workflow_id is not None
507
+ return workflow_id
504
508
 
505
509
  wfid = str(uuid.uuid4())
506
510
  with SetWorkflowID(wfid):
@@ -540,7 +544,9 @@ async def test_callchild_direct_asyncio(dbos: DBOS) -> None:
540
544
 
541
545
  @DBOS.workflow()
542
546
  async def child_workflow() -> str:
543
- return DBOS.workflow_id
547
+ workflow_id = DBOS.workflow_id
548
+ assert workflow_id is not None
549
+ return workflow_id
544
550
 
545
551
  wfid = str(uuid.uuid4())
546
552
  with SetWorkflowID(wfid):
@@ -773,7 +779,9 @@ def test_callchild_middle_async_thread(dbos: DBOS) -> None:
773
779
 
774
780
  @DBOS.step()
775
781
  def stepOne() -> str:
776
- return DBOS.workflow_id
782
+ workflow_id = DBOS.workflow_id
783
+ assert workflow_id is not None
784
+ return workflow_id
777
785
 
778
786
  @DBOS.step()
779
787
  def stepTwo() -> None:
@@ -781,7 +789,9 @@ def test_callchild_middle_async_thread(dbos: DBOS) -> None:
781
789
 
782
790
  @DBOS.workflow()
783
791
  def child_workflow() -> str:
784
- return DBOS.workflow_id
792
+ workflow_id = DBOS.workflow_id
793
+ assert workflow_id is not None
794
+ return workflow_id
785
795
 
786
796
  wfid = str(uuid.uuid4())
787
797
  with SetWorkflowID(wfid):
@@ -821,7 +831,9 @@ async def test_callchild_first_asyncio(dbos: DBOS) -> None:
821
831
 
822
832
  @DBOS.step()
823
833
  def stepOne() -> str:
824
- return DBOS.workflow_id
834
+ workflow_id = DBOS.workflow_id
835
+ assert workflow_id is not None
836
+ return workflow_id
825
837
 
826
838
  @DBOS.step()
827
839
  def stepTwo() -> None:
@@ -829,7 +841,9 @@ async def test_callchild_first_asyncio(dbos: DBOS) -> None:
829
841
 
830
842
  @DBOS.workflow()
831
843
  async def child_workflow() -> str:
832
- return DBOS.workflow_id
844
+ workflow_id = DBOS.workflow_id
845
+ assert workflow_id is not None
846
+ return workflow_id
833
847
 
834
848
  wfid = str(uuid.uuid4())
835
849
  with SetWorkflowID(wfid):
@@ -1045,11 +1059,15 @@ def test_call_as_step_within_step(dbos: DBOS) -> None:
1045
1059
 
1046
1060
  @DBOS.workflow()
1047
1061
  def getStatusWorkflow() -> str:
1048
- return getStatus(DBOS.workflow_id)
1062
+ workflow_id = DBOS.workflow_id
1063
+ assert workflow_id is not None
1064
+ return getStatus(workflow_id)
1049
1065
 
1050
1066
  @DBOS.transaction()
1051
1067
  def transactionStatus() -> None:
1052
- DBOS.get_workflow_status(DBOS.workflow_id)
1068
+ workflow_id = DBOS.workflow_id
1069
+ assert workflow_id is not None
1070
+ DBOS.get_workflow_status(workflow_id)
1053
1071
 
1054
1072
  wfid = str(uuid.uuid4())
1055
1073
  with SetWorkflowID(wfid):
@@ -9,7 +9,7 @@ import sqlalchemy as sa
9
9
  # Public API
10
10
  from dbos import DBOS, Queue, SetWorkflowID
11
11
  from dbos._dbos import DBOSConfiguredInstance
12
- from dbos._error import DBOSWorkflowCancelledError
12
+ from dbos._error import DBOSAwaitedWorkflowCancelledError
13
13
  from dbos._schemas.application_database import ApplicationSchema
14
14
  from dbos._utils import INTERNAL_QUEUE_NAME, GlobalParams
15
15
  from dbos._workflow_commands import garbage_collect, global_timeout
@@ -52,7 +52,7 @@ def test_cancel_resume(dbos: DBOS) -> None:
52
52
  main_thread_event.wait()
53
53
  DBOS.cancel_workflow(wfid)
54
54
  workflow_event.set()
55
- with pytest.raises(DBOSWorkflowCancelledError):
55
+ with pytest.raises(DBOSAwaitedWorkflowCancelledError):
56
56
  handle.get_result()
57
57
  assert steps_completed == 1
58
58
 
@@ -103,7 +103,7 @@ def test_cancel_resume_txn(dbos: DBOS) -> None:
103
103
  main_thread_event.wait()
104
104
  DBOS.cancel_workflow(wfid)
105
105
  workflow_event.set()
106
- with pytest.raises(DBOSWorkflowCancelledError):
106
+ with pytest.raises(DBOSAwaitedWorkflowCancelledError):
107
107
  handle.get_result()
108
108
  assert txn_completed == 1
109
109
 
@@ -652,7 +652,9 @@ def test_garbage_collection(dbos: DBOS) -> None:
652
652
  def blocked_workflow() -> str:
653
653
  txn(0)
654
654
  event.wait()
655
- return DBOS.workflow_id
655
+ workflow_id = DBOS.workflow_id
656
+ assert workflow_id is not None
657
+ return workflow_id
656
658
 
657
659
  num_workflows = 10
658
660
 
@@ -729,7 +731,9 @@ def test_global_timeout(dbos: DBOS) -> None:
729
731
  def blocked_workflow() -> str:
730
732
  while not event.wait(0):
731
733
  DBOS.sleep(0.1)
732
- return DBOS.workflow_id
734
+ workflow_id = DBOS.workflow_id
735
+ assert workflow_id is not None
736
+ return workflow_id
733
737
 
734
738
  num_workflows = 10
735
739
  handles = [DBOS.start_workflow(blocked_workflow) for _ in range(num_workflows)]
@@ -742,7 +746,7 @@ def test_global_timeout(dbos: DBOS) -> None:
742
746
 
743
747
  # Verify all workflows started before the global timeout are cancelled
744
748
  for handle in handles:
745
- with pytest.raises(DBOSWorkflowCancelledError):
749
+ with pytest.raises(DBOSAwaitedWorkflowCancelledError):
746
750
  handle.get_result()
747
751
  event.set()
748
752
  assert final_handle.get_result() is not None
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes