Compare commits

...

4 Commits

Author SHA1 Message Date
Tyler Goodlet 2bb33da9c8 Add a `debug_mode`-state reversion test 2025-05-07 15:06:44 -04:00
Tyler Goodlet 06f7f2e06b Fix ref-err on `logger` input to `get_console_log()`
Particularly on a get-attr of `StackLevelAdapter.handlers` which, when
a `logger: StackLevelAdapter` is passed, we need to *not call* our own
`get_logger()` and just set is as the `log`. Fix the typing to match.
2025-05-07 13:09:33 -04:00
Tyler Goodlet a92d0ebf02 Unset debug-mode on root actor exit
Discovered this bug while testing `modden`'s daemon under various
cancelled-while-booting race conditions where sequential tests would
fail a lingering `assert 0` inside `.to_asyncio.run_as_asyncio_guest()`
to (oddly) catch redundant greenback-re-inits..

XD

Needs a test likely ;P
2025-05-07 10:41:59 -04:00
Tyler Goodlet 8c8d79e475 Expose `.trionics.maybe_collapse_eg` 2025-05-05 17:45:10 -04:00
4 changed files with 57 additions and 13 deletions

View File

@ -83,3 +83,26 @@ def test_implicit_root_via_first_nursery(
assert tractor.current_actor().aid.name == 'root'
trio.run(main)
def test_runtime_vars_unset(
reg_addr: tuple,
debug_mode: bool
):
'''
Ensure any `._state._runtime_vars` are restored to default values
after the root actor-runtime exits!
'''
assert not tractor._state._runtime_vars['_debug_mode']
async def main():
assert not tractor._state._runtime_vars['_debug_mode']
async with tractor.open_nursery(
debug_mode=True,
):
assert tractor._state._runtime_vars['_debug_mode']
# after runtime closure, should be reverted!
assert not tractor._state._runtime_vars['_debug_mode']
trio.run(main)

View File

@ -276,7 +276,8 @@ async def open_root_actor(
if (
debug_mode
and _spawn._spawn_method == 'trio'
and
_spawn._spawn_method == 'trio'
):
_state._runtime_vars['_debug_mode'] = True
@ -512,8 +513,17 @@ async def open_root_actor(
)
await actor.cancel(None) # self cancel
finally:
# revert all process-global runtime state
if (
debug_mode
and
_spawn._spawn_method == 'trio'
):
_state._runtime_vars['_debug_mode'] = False
_state._current_actor = None
_state._last_actor_terminated = actor
logger.runtime(
f'Root actor terminated\n'
f')>\n'

View File

@ -270,7 +270,9 @@ def get_logger(
subsys_spec: str|None = None,
) -> StackLevelAdapter:
'''Return the package log or a sub-logger for ``name`` if provided.
'''
Return the `tractor`-library root logger or a sub-logger for
`name` if provided.
'''
log: Logger
@ -282,7 +284,7 @@ def get_logger(
name != _proj_name
):
# NOTE: for handling for modules that use ``get_logger(__name__)``
# NOTE: for handling for modules that use `get_logger(__name__)`
# we make the following stylistic choice:
# - always avoid duplicate project-package token
# in msg output: i.e. tractor.tractor.ipc._chan.py in header
@ -331,7 +333,7 @@ def get_logger(
def get_console_log(
level: str|None = None,
logger: Logger|None = None,
logger: Logger|StackLevelAdapter|None = None,
**kwargs,
) -> LoggerAdapter:
@ -344,12 +346,23 @@ def get_console_log(
Yeah yeah, i know we can use `logging.config.dictConfig()`. You do it.
'''
log = get_logger(
logger=logger,
**kwargs
) # set a root logger
logger: Logger = log.logger
# get/create a stack-aware-adapter
if (
logger
and
isinstance(logger, StackLevelAdapter)
):
# XXX, for ex. when passed in by a caller wrapping some
# other lib's logger instance with our level-adapter.
log = logger
else:
log: StackLevelAdapter = get_logger(
logger=logger,
**kwargs
)
logger: Logger|StackLevelAdapter = log.logger
if not level:
return log
@ -367,10 +380,7 @@ def get_console_log(
None,
)
):
fmt = LOG_FORMAT
# if logger:
# fmt = None
fmt: str = LOG_FORMAT # always apply our format?
handler = StreamHandler()
formatter = colorlog.ColoredFormatter(
fmt=fmt,

View File

@ -31,4 +31,5 @@ from ._broadcast import (
)
from ._beg import (
collapse_eg as collapse_eg,
maybe_collapse_eg as maybe_collapse_eg,
)