Actual Behavior
When hitting a breakpoint in a workflow, the debugger freezes with the following symptoms:
- Infinite loader in “local variables section”
- All debug actions stop working (Step over / Continue etc.)
- The following stack trace is printed:
Traceback (most recent call last):
File "/Users/user/.vscode/extensions/ms-python.debugpy-2024.5.11001011-darwin-arm64/bundled/libs/debugpy/_vendored/pydevd/pydevd.py", line 1783, in process_internal_commands
int_cmd.do_it(self)
File "/Users/user/.vscode/extensions/ms-python.debugpy-2024.5.11001011-darwin-arm64/bundled/libs/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_comm.py", line 528, in do_it
self.method(dbg, *self.args, **self.kwargs)
File "/Users/user/.vscode/extensions/ms-python.debugpy-2024.5.11001011-darwin-arm64/bundled/libs/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_constants.py", line 489, in new_func
with filter_all_warnings():
File "/Users/user/.pyenv/versions/3.10.12/lib/python3.10/contextlib.py", line 135, in __enter__
return next(self.gen)
File "/Users/user/.vscode/extensions/ms-python.debugpy-2024.5.11001011-darwin-arm64/bundled/libs/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_constants.py", line 480, in filter_all_warnings
with warnings.catch_warnings():
File "/Users/user/.pyenv/versions/3.10.12/lib/python3.10/warnings.py", line 446, in __init__
self._module = sys.modules['warnings'] if module is None else module
File "/Users/user/project/.venv/lib/python3.10/site-packages/temporalio/worker/workflow_sandbox/_importer.py", line 393, in __getitem__
return self.current[key]
KeyError: 'warnings'
I assume the problem and resolution has something to do with the sandbox, and the “warnings” module which seems to be required by the debugpy extension.
If you have any recommended solutions that would be appreciated.
Thank you!
Steps to reproduce:
- Use vscode, python debugger extension. Both latest versions.
- Use the attached launch configuration
- Place breakpoint on “return x” in the workflow
- Run the workflow.
Code
"""example_workflow.py"""
from temporalio import workflow
@workflow.defn
class ExampleWorkflow:
@workflow.run
async def run(self, x: str) -> str:
return x
"""run_worker.py"""
import asyncio
from temporalio.client import Client
from temporalio.worker import Worker
from example_workflow import ExampleWorkflow
async def main():
client = await Client.connect("localhost:7233", namespace="example_namespace")
worker = Worker(
client,
task_queue="my-queue",
workflows=[ExampleWorkflow],
debug_mode=True,
)
await worker.run()
if __name__ == "__main__":
asyncio.run(main())
Launch configuration
{
"name": "Python",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/run_worker.py",
"console": "integratedTerminal",
"cwd": "${workspaceFolder}",
"args": [],
"stopOnEntry": false,
"justMyCode": false,
}