Re: [PATCH v2 22/58] perf python: Add perf.pyi stubs file

sashiko-bot
2026-04-23T04:20:15Z

Sashiko AI review found 3 potential issue(s):
- [Medium] Missing build system integration for `perf.pyi`
- [Medium] Inaccurate and incomplete API method signatures in `perf.pyi`
- [Medium] Hallucinated and missing attributes in event class stubs
--

commit 91be6bb21ba4a262cbe51c81656804886324284d
Author: Ian Rogers <irogers@google.com>

perf python: Add perf.pyi stubs file

This commit adds Python type stubs (perf.pyi) for the perf module to improve
IDE support and static analysis. It includes docstrings for classes, methods,
and constants based on C source and JSON definitions.

> diff --git a/tools/perf/python/perf.pyi b/tools/perf/python/perf.pyi
> new file mode 100644
> index 0000000000000..7ab0dfc44d1cb
> --- /dev/null
> +++ b/tools/perf/python/perf.pyi

Since perf.pyi isn't added to tools/perf/util/setup.py or
tools/perf/Makefile.perf, will this file actually get installed? Python type
stubs typically need to be distributed and installed in the site-packages
directory to be discovered by IDEs and static analysis tools like mypy.

> @@ -0,0 +1,579 @@
> +"""Type stubs for the perf Python module."""
> +from typing import Callable, Dict, List, Optional, Any, Iterator

Are there missing functions in this module? The module-level function
perf.tracepoint() is explicitly exported by the C extension but is completely
missing from these stubs.

[ ... ]

> +class counts_values:
> + """Raw counter values."""
> + val: int
> + ena: int
> + run: int

Are these attributes complete? The C extension also includes id, lost, and
values attributes for this class.

[ ... ]

> +class evsel:
> + """Event selector, represents a single event being monitored."""
> + def __init__(
> + self,
> + type: int = ...,
> + config: int = ...,
> + sample_freq: int = ...,
> + sample_period: int = ...,
> + sample_type: int = ...,
> + read_format: int = ...,
> + disabled: bool = ...,
> + inherit: bool = ...,
> + pinned: bool = ...,
> + exclusive: bool = ...,
> + exclude_user: bool = ...,
> + exclude_kernel: bool = ...,
> + exclude_hv: bool = ...,
> + exclude_idle: bool = ...,
> + mmap: bool = ...,
> + context_switch: bool = ...,
> + comm: bool = ...,
> + freq: bool = ...,
> + idx: int = ...,
> + ) -> None: ...

Do these arguments match the C API? The C extension accepts over 20 keyword
arguments (including inherit_stat, enable_on_exec, watermark, etc.), which
are omitted here. Additionally, the idx argument doesn't appear to be
supported by the C code.

> + def __str__(self) -> str:
> + """Return string representation of the event."""
> + ...
> + def open(self) -> None:

Does this match the C implementation? In the C code, open() accepts
cpus, threads, group, and inherit arguments, but this stub restricts
it to zero arguments.

[ ... ]

> +class sample_event:
> + """Represents a sample event from perf."""
> + evsel: evsel
> + sample_cpu: int
> + sample_time: int
> + sample_pid: int
> + type: int
> + brstack: Optional['branch_stack']
> + callchain: Optional['callchain']

Is this missing some properties and methods exported by the C extension?
Attributes like sym_end and methods like srccode() and insn() are missing
from this stub.

> + def __getattr__(self, name: str) -> Any: ...
> +
> +class mmap_event:
> + """Represents a mmap event from perf."""
> + type: int
> + pid: int
> + tid: int
> + addr: int

Does the C extension export addr here? It appears to export a start
attribute instead of addr, and also includes a misc field that is missing
from this stub.

Additionally, event classes exported by the C extension (except sample_event)
include fields generated by the sample_members macro (like sample_pid,
sample_tid, sample_time). Should those be included in these event stubs?

> + len: int
> + pgoff: int
> + filename: str
> +
> +class lost_event:
> + """Represents a lost events record."""
> + type: int

Does the PyMemberDef array in C actually export a type attribute for
lost_event? Referencing it in Python might result in an AttributeError.

[ ... ]

> +class read_event:
> + """Represents a READ record."""
> + type: int
> + pid: int
> + tid: int
> + value: int

Do type and value exist on read_event at runtime? The C implementation
doesn't seem to export these, which could lead to AttributeError at runtime.

> +
> +class switch_event:

Is this class named correctly? The C extension registers this type as
perf.context_switch_event rather than switch_event.

[ ... ]

> +class evlist:
> + def __init__(self, cpus: cpu_map, threads: thread_map) -> None: ...
> + def open(self) -> None:
> + """Open the events in the list."""
> + ...
> + def close(self) -> None:
> + """Close the events in the list."""
> + ...
> + def mmap(self) -> None:

Does this match the C API? The C implementation of evlist.mmap() accepts
optional pages and overwrite arguments, but this stub restricts it to
zero arguments.

> + """Memory map the event buffers."""
> + ...
> + def poll(self, timeout: int) -> int:

Should timeout be optional here? The C implementation defaults to -1 and
can be called without arguments.

[ ... ]

--
Sashiko AI review · https://sashiko.dev/#/patchset/20260423035526.1537178-1-irogers@google.com?part=22