Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Annotate pn.io.profile decorator #7092

Merged
merged 3 commits into from
Aug 7, 2024
Merged
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
18 changes: 13 additions & 5 deletions panel/io/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,19 @@
from contextlib import contextmanager
from cProfile import Profile
from functools import wraps
from typing import (
Callable, Iterator, Literal, ParamSpec, TypeVar,
)

from ..config import config
from ..util import escape
from .state import state

_P = ParamSpec("_P")
_R = TypeVar("_R")

ProfilingEngine = Literal["pyinstrument", "snakeviz", "memray"]


def render_pyinstrument(sessions, timeline=False, show_all=False):
from pyinstrument.renderers import HTMLRenderer
Expand Down Expand Up @@ -183,7 +191,7 @@ def update_memray(*args):


@contextmanager
def profile_ctx(engine='pyinstrument'):
def profile_ctx(engine: ProfilingEngine = 'pyinstrument') -> Iterator[list[Profile | bytes]]:
"""
A context manager which profiles the body of the with statement
with the supplied profiling engine and returns the profiling object
Expand Down Expand Up @@ -217,7 +225,7 @@ def profile_ctx(engine='pyinstrument'):
tracker.__enter__()
elif engine is None:
pass
sessions = []
sessions: list[Profile | bytes] = []
yield sessions
if engine == 'pyinstrument':
sessions.append(prof.stop())
Expand All @@ -230,7 +238,7 @@ def profile_ctx(engine='pyinstrument'):
os.remove(tmp_file)


def profile(name, engine='pyinstrument'):
def profile(name: str, engine: ProfilingEngine = 'pyinstrument') -> Callable[[Callable[_P, _R]], Callable[_P, _R]]:
"""
A decorator which may be added to any function to record profiling
output.
Expand All @@ -244,9 +252,9 @@ def profile(name, engine='pyinstrument'):
"""
if not isinstance(name, str):
raise ValueError("Profiler must be given a name.")
def wrapper(func):
def wrapper(func: Callable[_P, _R]) -> Callable[_P, _R]:
@wraps(func)
def wrapped(*args, **kwargs):
def wrapped(*args: _P.args, **kwargs: _P.kwargs) -> _R:
if state.curdoc and state.curdoc in state._launching:
return func(*args, **kwargs)
with profile_ctx(engine) as sessions:
Expand Down
Loading