From d653cd2c26d9f5a9c11a001009ed10ed80514f14 Mon Sep 17 00:00:00 2001 From: goodboy Date: Thu, 2 Jul 2026 12:17:17 -0400 Subject: [PATCH] Use `sys._getframe()` in `get_logger()` mod lookup `get_caller_mod()` (nested in `get_logger()`) walks the WHOLE call-stack via `inspect.stack()`, which also resolves src-file info for every frame and scans all of `sys.modules` per frame via `inspect.getmodule()`. During nested imports (deep importlib stacks) each module-level `get_logger()` call costs ~5-10ms, making the ~39 such calls dominate `import tractor` wall-time: ~244ms of the ~420ms total (see gh #470). Deats, - resolve the caller frame with `sys._getframe(frames_up)` and map its `f_globals['__name__']` through `sys.modules`: O(1) vs. O(stack x sys.modules). - guard `ValueError` (stack too shallow) -> `None`, matching the existing null-caller handling at all use-sites. - drop the now-unused `inspect` imports; pull `FrameType` from `types` instead. Results: `import tractor` drops 0.42s -> ~0.155s; sequential `.start_actor()` spawn latency ~0.42 -> ~0.18s/actor. Prompt-IO: ai/prompt-io/claude/20260702T155626Z_65bf9df5_prompt_io.md (this patch was generated in some part by [`claude-code`][claude-code-gh]) [claude-code-gh]: https://github.com/anthropics/claude-code --- tractor/log.py | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/tractor/log.py b/tractor/log.py index 6c8c9bc8..53253f83 100644 --- a/tractor/log.py +++ b/tractor/log.py @@ -26,11 +26,6 @@ built on `tractor`. ''' from collections.abc import Mapping from functools import partial -from inspect import ( - FrameInfo, - getmodule, - stack, -) import sys import logging from logging import ( @@ -38,7 +33,10 @@ from logging import ( Logger, StreamHandler, ) -from types import ModuleType +from types import ( + FrameType, + ModuleType, +) import warnings import colorlog # type: ignore @@ -438,16 +436,33 @@ def get_logger( pkg_name: str = _root_name def get_caller_mod( - frames_up:int = 2 - ): + frames_up: int = 2, + ) -> ModuleType|None: ''' - Attempt to get the module which called `tractor.get_logger()`. + Attempt to get the module which called + `tractor.get_logger()`. + + Resolve the caller's frame with `sys._getframe()` and + map its `__name__` through `sys.modules`; `inspect.stack()` + (the previous impl) builds src-file info for EVERY frame + on the stack, scanning all of `sys.modules` per frame via + `inspect.getmodule()`, which made module-level + `get_logger()` calls dominate `import tractor` time + (see gh #470). ''' - callstack: list[FrameInfo] = stack() - caller_fi: FrameInfo = callstack[frames_up] - caller_mod: ModuleType = getmodule(caller_fi.frame) - return caller_mod + try: + caller_frame: FrameType = sys._getframe(frames_up) + except ValueError: + return None + + mod_name: str|None = caller_frame.f_globals.get( + '__name__', + ) + if mod_name is None: + return None + + return sys.modules.get(mod_name) # --- Auto--naming-CASE --- # -------------------------