[doc] sys.setprofile / sys.getprofile asymetry
| BPO | 25726 |
|---|---|
| Nosy | @birkenfeld, @stefanseefeld |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee = None
closed_at = None
created_at = <Date 2015-11-24.23:04:27.109>
labels = ['3.11', 'type-bug', '3.9', '3.10', 'docs']
title = '[doc] sys.setprofile / sys.getprofile asymetry'
updated_at = <Date 2021-12-07.15:35:18.401>
user = 'https://github.com/stefanseefeld'
bugs.python.org fields:
activity = <Date 2021-12-07.15:35:18.401>
actor = 'iritkatriel'
assignee = 'docs@python'
closed = False
closed_date = None
closer = None
components = ['Documentation']
creation = <Date 2015-11-24.23:04:27.109>
creator = 'stefan'
dependencies = []
files = []
hgrepos = []
issue_num = 25726
keywords = []
message_count = 2.0
messages = ['255301', '260234']
nosy_count = 3.0
nosy_names = ['georg.brandl', 'stefan', 'docs@python']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue25726'
versions = ['Python 3.9', 'Python 3.10', 'Python 3.11']
Linked PRs
- gh-143338
I'm using the cProfile module to profile my code.
I tried to temporarily disable the profiler by using:
prof = sys.getprofile()
sys.setprofile(None)
...
sys.setprofile(prof)
resulting in an error.
The reason is that with cProfile, sys.getprofile returns the profile object itself, which isn't suitable as argument for sys.setprofile (which expects a callable).
Notice that if I use the profile module instead of cProfile, the above works fine.
Ok, this is because internally, sys.setprofile (or to be exact, PyEval_SetProfile) sets two things: a C function, and a "profileobj", which is the argument to setprofile().
sys.setprofile sets the C function to the "profile_trampoline", which supports calling Python profile functions. The profileobj is the Python profile function.
The C profiler sets the C function to a different callback, and uses the profileobj for storing the reference to the Profiler object.
sys.getprofile just returns the profileobj, which means that you can't save/restore the profiler state with the two functions when using cProfile.
There is not much we can do here except for explicitly documenting this.
I just stumbled upon this today in https://github.com/bloomberg/memray/issues/665
I'm not sure that I agree that this is a documentation bug, as opposed to an implementation bug. Wouldn't it make more sense for sys.getprofile() to raise an exception rather than return an incorrect answer when c_profilefunc is not set to the profile_trampoline? Or, perhaps if not an exception, perhaps return a sentinel object indicating that, although a trace function is installed, it cannot be returned?
Granted this is an edge case, but the current behavior seems to leak internal implementation details (the existence of profile_trampoline), and allows accessing the private state of C tracers as well (nothing in the documentation suggests that the profile object will be exposed to Python code).