diff --git a/tractor/_debug.py b/tractor/_debug.py index 9c1fb71..6040d3f 100644 --- a/tractor/_debug.py +++ b/tractor/_debug.py @@ -274,14 +274,31 @@ def _mk_pdb(): return pdb -def _set_trace(actor): - log.runtime(f"\nAttaching pdb to actor: {actor.uid}\n") - +def _set_trace(actor=None): pdb = _mk_pdb() - pdb.set_trace( - # start 2 levels up in user code - frame=sys._getframe().f_back.f_back, - ) + + if actor is not None: + log.runtime(f"\nAttaching pdb to actor: {actor.uid}\n") + + pdb.set_trace( + # start 2 levels up in user code + frame=sys._getframe().f_back.f_back, + ) + + else: + # we entered the global ``breakpoint()`` built-in from sync code + global _in_debug, _pdb_release_hook + _in_debug = 'sync' + + def nuttin(): + pass + + _pdb_release_hook = nuttin + + pdb.set_trace( + # start 2 levels up in user code + frame=sys._getframe().f_back, + ) breakpoint = partial( diff --git a/tractor/_entry.py b/tractor/_entry.py index 670f03c..2f57048 100644 --- a/tractor/_entry.py +++ b/tractor/_entry.py @@ -64,8 +64,7 @@ def _trio_main( # we don't need it thanks to our cancellation machinery. signal.signal(signal.SIGINT, signal.SIG_IGN) - # TODO: make a global func to set this or is it too hacky? - # os.environ['PYTHONBREAKPOINT'] = 'tractor._debug.breakpoint' + log.info(f"Started new trio process for {actor.uid}") if actor.loglevel is not None: log.info( diff --git a/tractor/_mp_fixup_main.py b/tractor/_mp_fixup_main.py index 7869561..78d3e9f 100644 --- a/tractor/_mp_fixup_main.py +++ b/tractor/_mp_fixup_main.py @@ -67,7 +67,7 @@ def _fixup_main_from_name(mod_name: str) -> None: main_module = types.ModuleType("__mp_main__") main_content = runpy.run_module(mod_name, run_name="__mp_main__", - alter_sys=True) + alter_sys=True) # type: ignore main_module.__dict__.update(main_content) sys.modules['__main__'] = sys.modules['__mp_main__'] = main_module @@ -95,6 +95,6 @@ def _fixup_main_from_path(main_path: str) -> None: # old_main_modules.append(current_main) main_module = types.ModuleType("__mp_main__") main_content = runpy.run_path(main_path, - run_name="__mp_main__") + run_name="__mp_main__") # type: ignore main_module.__dict__.update(main_content) sys.modules['__main__'] = sys.modules['__mp_main__'] = main_module diff --git a/tractor/_root.py b/tractor/_root.py index ec2ccfd..e48ca98 100644 --- a/tractor/_root.py +++ b/tractor/_root.py @@ -4,6 +4,7 @@ Root actor runtime ignition(s). from contextlib import asynccontextmanager from functools import partial import importlib +import os from typing import Tuple, Optional, List, Any import typing import warnings @@ -55,6 +56,11 @@ async def open_root_actor( """Async entry point for ``tractor``. """ + # Override the global debugger hook to make it play nice with + # ``trio``, see: + # https://github.com/python-trio/trio/issues/1155#issuecomment-742964018 + os.environ['PYTHONBREAKPOINT'] = 'tractor._debug._set_trace' + # mark top most level process as root actor _state._runtime_vars['_is_root'] = True