Is there a Python profiler that preserves function arguments?
I'm profiling a Python function `foo()` that takes a single argument, but that argument makes a huge difference in what the function actually does. Currently I'm using `cProfile`, which records every call to `foo()` as if it was the same, preventing me from figuring out what's going on. Is there a way to get `cProfile`, or any other Python profiler, to preserve function call arguments, so when I look at the call stack later (especially using a visualizer like SnakeViz) I can distinguish between `foo('bar')` and `foo('qux')`? P.S. arguably this is a code design issue: since `foo('bar')` and `foo('qux')` do very different things, they should be distinctly-named separate functions, like `foo_bar()` and `foo_qux()`. However, the question is whether I can profile them as-is, without refactoring. -- https://mail.python.org/mailman/listinfo/python-list
Profiler showing path dependency?
Consider a simple call graph: `main()` calls `foo()`, which calls `bar()`. Then `main()` calls `qux()` which also calls `bar()`, but with different parameters. When you run the above through cProfile and view the result in SnakeViz, you will see `main()` calling `foo()` and `qux()`, with each of them calling `bar()`. However, if you hover or click on `bar()`, you will see the global aggregate statistics for it. For example, the number of times it has been called, and their total time cost. Is there a way to get a path-dependent profiler breakdown for `bar()`? Specifically for this example, statistics for when it is called by `foo()`, and separately statistics for when it is called by `qux()`. -- https://mail.python.org/mailman/listinfo/python-list
Automatically advancing a bi-directional generator to the point of accepting a non-None value?
Suppose we write a very simple bi-directional generator in Python: def share_of_total(): s = 0 new_num = 0 while True: new_num = yield new_num / (s or 1) s += new_num share_calculator = share_of_total() next(share_calculator) # Without this we get the TypeError for num in [1, 2, 3]: print(share_calculator.send(num)) This generator just accepts a number and yields a float representing its share of the sum of all previously provided numbers. We would ideally like to just use it immediately as follows: share_calculator = share_of_total() print(share_calculator.send(num)) However, this causes `TypeError: can't send non-None value to a just-started generator`. All users of the `share_of_total()` must remember to execute `next(share_calculator)` before the generator is usable as intended. Is there an elegant way to make `share_calculator` immediately usable - i.e. to be able to immediately call `share_calculator.send(num)` after creating `share_calculator`? I know it can be done with a fairly trivial wrapper, but I was hoping for a more elegant solution that doesn't require boilerplate. -- https://mail.python.org/mailman/listinfo/python-list