Nick Coghlan added the comment:

Thanks Louie.

I've adjusted the issue title, as I think the core RFE is that we'd like the 
following helper function to work exactly the same way as calling 
sys.setprofile directly:

    def setprofile_helper(f):
        sys.setprofile(f)

The following utility function can be used to demonstrate the current 
discrepancy:

    def profile_call(setprofile, call):
        pr = profile.Profile()
        setprofile(pr.dispatcher)
        try:
            call()
        finally:
            setprofile(None)
        return pr

Specifically:

```
>>> profile_call(sys.setprofile, lambda:print("Profiled!"))
Profiled!
<profile.Profile object at 0x7fb2265966d8>
>>> profile_call(setprofile_helper, lambda:print("Profiled!"))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in profile_call
  File "<stdin>", line 2, in setprofile_helper
  File "/usr/lib64/python3.5/profile.py", line 209, in trace_dispatch_i
    if self.dispatch[event](self, frame, t):
  File "/usr/lib64/python3.5/profile.py", line 293, in trace_dispatch_return
    assert frame is self.cur[-2].f_back, ("Bad return", self.cur[-3])
AssertionError: ('Bad return', ('profile', 0, 'profiler'))
```

If we can figure out a way to do it reliably, the most desirable approach would 
be to make helper functions like the above "just work", perhaps by remembering 
the stack frame where the profiler was *defined*, and using that as the 
reference point to construct the synthetic stack the first time a trace 
dispatch occurs.

If that transparent-to-the-user approach doesn't appear to be feasible, an 
alternative would be to offer a new private method on Profile objects to adjust 
their synthetic stack by one level, as if `sys.setprofile` had been called 
*before* the call into the helper function.

That is, a profiler-aware alternative to the helper function above might look 
like:

    def profile_helper(pr):
        sys.setprofile(pr.dispatcher)
        pr._adjust_stack()

and that's then the approach that the `__enter__` method would use to implement 
context management support.

The advantage of the latter private option is that it wouldn't need to support 
arbitrary helper functions, just the specific implementation of `__enter__` for 
issue 9285.

In either case, I *don't* think changing the assertion is the right answer - 
instead, I think the internal profiler state needs to be adjusted so the 
assertion passes without modification.

----------
title: Add profile test case for trace_dispatch_return assertion -> Allow 
helper functions to wrap sys.setprofile

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue30113>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to