How do I access the stack frame of a test immediately as it's called in PyTest?

A developer building a custom PyTest plugin wants to capture the stack frame of each test right as it starts executing. The goal is to inspect the local and global namespaces of the test function to analyze accessible objects by name. They currently achieve this using a profiling hook (sys.setprofile) that triggers on function calls when the test name matches the frame being executed. However, this approach adds noticeable performance overhead and interferes with some test suites. The user is looking for a more efficient and direct PyTest mechanism, such as using a hook like pytest_pyfunc_call, to access the test’s execution frame without the profiling overhead.

Hey! I’ve tackled something similar. Using sys.setprofile works, but it’s slow. A better way in PyTest is to hook into pytest_pyfunc_call, which runs right before the test function is executed. You can access the function object from the pyfuncitem and then inspect its frame using the inspect module:

import inspect import pytest

@pytest.hookimpl(hookwrapper=True) def pytest_pyfunc_call(pyfuncitem): frame = inspect.currentframe().f_back # frame of the test function call print(“Local variables at test start:”, frame.f_locals) yield

This gives you access to locals and globals without adding profiling overhead.

Yep, exactly! sys.setprofile works but is overkill. Using pytest_pyfunc_call is cleaner and much faster. One thing I do is yield from the hook first and then inspect the frame if needed — you can also attach extra metadata to the pyfuncitem to avoid repeated inspection in other hooks.

Also, a tip: if you need persistent access to the test’s frame or variables across multiple hooks, consider using a small helper in your plugin to store frame.f_locals keyed by pyfuncitem.nodeid. This avoids repeated inspect.currentframe() calls and keeps overhead minimal.