Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ permissions:
jobs:
build_mkdocs:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ uv.lock
*.csv
*.json
*.txt
*.ipynb
tests_examples/
site/
21 changes: 13 additions & 8 deletions lblprof/custom_sysmon.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ def _handle_call(self, code, instruction_offset):
logging.debug(
f"handle call: filename: {file_name}, func_name: {func_name}, line_no: {line_no}"
)
if "<genexpr>" in func_name:
return
# We get info on who called the function
# Using the tempo line infos instead of frame.f_back allows us to
# get information about last parent that is from user code and not
Expand All @@ -83,6 +85,7 @@ def _handle_call(self, code, instruction_offset):
# Update call stack
# Until we return from the function, all lines executed will have
# the caller line as parent

self.call_stack.append(caller_key)

def _handle_line(self, code, line_number):
Expand Down Expand Up @@ -130,16 +133,18 @@ def _handle_return(self, code, instruction_offset, retval):

# In case the stop_tracing is called from a lower frame than start_tracing,
# we need to activate monitoring for the returned frame
current_frame = sys._getframe().f_back.f_back
current_frame = sys._getframe().f_back
if not sys.monitoring.get_tool(self.tool_id):
sys.monitoring.use_tool_id(self.tool_id, "lblprof-monitor")
sys.monitoring.set_local_events(
self.tool_id,
current_frame.f_code,
sys.monitoring.events.LINE
| sys.monitoring.events.PY_RETURN
| sys.monitoring.events.PY_START,
)
# We check if the returned frame already exists, if yes we activate monitoring for it
if current_frame and current_frame.f_back and current_frame.f_back.f_code:
sys.monitoring.set_local_events(
self.tool_id,
current_frame.f_code,
sys.monitoring.events.LINE
| sys.monitoring.events.PY_RETURN
| sys.monitoring.events.PY_START,
)

# Adding a END_OF_FRAME event to the tree to mark the end of the frame
# This is used to compute the duration of the last line of the frame
Expand Down
2 changes: 1 addition & 1 deletion lblprof/line_stats_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ def _save_events(self) -> None:
with open("events.csv", "w") as f:
for event in self.raw_events_list:
f.write(
f"{event['id']},{event['file_name']},{event['function_name']},{event['line_no']},{event['start_time']}\n"
f"{event['id']},{event['file_name']},{event['function_name']},{event['line_no']},{event['start_time']},{event['stack_trace']}\n"
)

def _save_events_index(self) -> None:
Expand Down
14 changes: 7 additions & 7 deletions lblprof/tests/demo_example_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,9 @@
import runpy

sys.path.append(os.getcwd())
from lblprof import (
show_interactive_tree,
start_tracing,
stop_tracing,
)
from lblprof import show_interactive_tree, start_tracing, stop_tracing, tracer

logging.basicConfig(level=logging.INFO)
logging.basicConfig(level=logging.DEBUG)


path_example_folder = os.path.join(os.path.dirname(__file__), "example_scripts")
Expand All @@ -21,6 +17,8 @@
script_name = "import_pandas.py"
# script_name = "list_comprehension.py"
# script_name = "try_except.py"
script_name = "double_zip.py"
# script_name = "generator_function.py"
script_path = os.path.join(path_example_folder, script_name)


Expand Down Expand Up @@ -56,4 +54,6 @@ def main():
stop_tracing()
# print the tree
# show_tree()
show_interactive_tree(min_time_s=0.01)
show_interactive_tree(min_time_s=0.0)
tracer.tree._save_events()
tracer.tree._save_events_index()
8 changes: 8 additions & 0 deletions lblprof/tests/example_scripts/double_zip.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
def doublezip():
rows = [(1, 2, None), (3, 4, None), (5, 6, None), (7, 8, None)]
_ = list(zip(*[col for col in zip(*rows) if any(cell is not None for cell in col)]))
_ = any(cell is not None for cell in rows[0])


if __name__ == "__main__":
doublezip()
25 changes: 25 additions & 0 deletions lblprof/tests/example_scripts/generator_function.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# import time
# def generator():
# for i in range(10):
# time.sleep(0.05)
# yield i

# if __name__ == "__main__":
# for i in generator():
# print(i)

# gene = list(generator())

# pure_gene = list(time.sleep(0.1) for i in range(10))

# double_gen = list(
# time.sleep(0.1) for i in range(2) for j in range(2) if True
# )

# # rows = [(1, 2, None), (3, 4, None), (5, 6, None)]
# # filtered = list(
# # zip(*[
# # col for col in zip(*rows)
# # if any(cell is not None for cell in col)
# # ])
# # )
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "lblprof"
version = "0.1.5"
version = "0.1.7"
description = "Line by line terminal based profiler"
authors = [
{ name="le-codeur-rapide", email="paul.vezia@gmail.com" }
Expand Down