Add sys.get_caller()
function
#238
Replies: 12 comments 6 replies
-
Oh, so this doesn't replace |
Beta Was this translation helpful? Give feedback.
-
I'd be interested in helping out with this, I can put up a PR sometime this week. |
Beta Was this translation helpful? Give feedback.
-
There are some interesting questions, what happens if the frame corresponds to a class or module. I guess we'll find out. :-) |
Beta Was this translation helpful? Give feedback.
-
FWIW, in 2011 I proposed adding something like There was also some discussion on python-ideas: |
Beta Was this translation helpful? Give feedback.
-
The motivation is similar to https://bugs.python.org/issue12857, but this suggestion would skip the frame, so instead of I suspect that with a bit of tweaking of the temporary function created to build a module or class, we could provide all the information that people were after. |
Beta Was this translation helpful? Give feedback.
-
The function for a module or class just wraps the code object, taking it's name from the code object, and it's globals and builtins from the class/module. |
Beta Was this translation helpful? Give feedback.
-
Maybe the argument should have the same numerical value as the corresponding |
Beta Was this translation helpful? Give feedback.
-
For anyone curious about modules or classes, they actually look fine: from gc import get_referrers
from sys import _getframe
from types import FunctionType
def print_current_function() -> None:
code = _getframe(1).f_code
funcs = [o for o in get_referrers(code) if isinstance(o, FunctionType)]
if not funcs:
raise RuntimeError("No function for current frame!")
if 1 < len(funcs):
raise RuntimeError("Multiple candidate functions found!")
print(funcs[0])
# This succeeds on 3.11, but raises "RuntimeError: No function for current frame!" on 3.10!
print_current_function() # <function <module> at ...>
class C:
print_current_function() # <function C at ...> |
Beta Was this translation helpful? Give feedback.
-
I put up a draft PR at python/cpython#30950. I was able to replace The asyncio and warnings callsites need There are also some callsites (e.g., bdb) which pass the frame to a tracing API. I assume that also needs the full frame. |
Beta Was this translation helpful? Give feedback.
-
I don't like "getfunc". What function? |
Beta Was this translation helpful? Give feedback.
-
I'd settle for |
Beta Was this translation helpful? Give feedback.
-
For historical context on why I originally added sys._getframe() along with links to existing important use cases. |
Beta Was this translation helpful? Give feedback.
-
e.g.
We can then use this wherever we currently use
sys.getframe()
to avoid creating frame objects.E.g
sys._getframe(3).f_globals
can be replaced withsys.get_caller(2).__globals__
.sys._getframe()
is currently used in:asyncio
(only for debugging, I think)logging
warnings
typing
And many tests.
The implementation is quite simple and cheap:
Beta Was this translation helpful? Give feedback.
All reactions