[issue30113] Allow helper functions to wrap sys.setprofile

2017-05-12 Thread Louie Lu

Louie Lu added the comment:

PR-1212 Add an explicit test for dispatch_return's assertion, could @benjaminp, 
@tiran or @giampaolo help to review this? Thanks!

--
nosy: +benjamin.peterson, christian.heimes, giampaolo.rodola

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue30113] Allow helper functions to wrap sys.setprofile

2017-04-22 Thread Louie Lu

Changes by Louie Lu :


--
pull_requests: +1368

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue30113] Allow helper functions to wrap sys.setprofile

2017-04-22 Thread Louie Lu

Louie Lu added the comment:

Thanks, Nick. Your analysis is very helpful.


After some testing, I found the problem here is because when we using 
`sys.setprofile` in the helper function, we didn't simulate the call (from 
where profiler create to helper function), that cause profile's frame link 
breakup, so if we want to return to outside of helper function, it will report 
a bad return.

A straightforward method is the latter method you propose, to make a 
profiler-aware function manually insert the frame into profiler's frame stack:

def _adjust_frame(self):
frame = sys._getframe(1)  # Get helper function frame
self.dispatch['call'](self, frame, 0)

And adjust *before* install profiler:

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


Then we can get the correct thing we need.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue30113] Allow helper functions to wrap sys.setprofile

2017-04-21 Thread Nick Coghlan

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_call(setprofile_helper, lambda:print("Profiled!"))
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 4, in profile_call
  File "", 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 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com