Skip to content

Commit 25c9d89

Browse files
johnslavikCopilot
andcommitted
Align stubs with documented/declared public API surface
Judgement calls, per the principle: will people want to import these symbols in their code that uses the profiling API? profiling.tracing ----------------- - Remove Profile.snapshot_stats(): not in __all__, not in docs. It is an internal implementation step called by create_stats(); users call create_stats() directly. - Remove module-level main(): not in __all__, not in docs. It is the CLI entry point wired up by the (already-deleted) __main__.py stub. - Keep dump_stats, runcall, create_stats, print_stats: all explicitly documented in the profiling.tracing module reference. - Keep private _T, _P, _Label aliases: needed internally by the stub to express the runcall() overload and stats dict type. profiling.sampling — collector submodule stubs ----------------------------------------------- - Remove normalize_location, extract_lineno, filter_internal_frames from collector.pyi: implementation helpers used inside collector subclasses; not in sampling.__all__, not documented. Users subclass Collector with collect() and export() only. - Remove DEFAULT_LOCATION and THREAD_STATUS_* re-exports from collector.pyi: leaked from constants.py; import from profiling.sampling.constants if needed. - Remove get_opcode_mapping from opcode_utils.pyi: internal mapping used to build opcode-name look-up tables; not documented, never imported by user code. - Remove re-exports of filter_internal_frames, format_opcode, get_opcode_info from gecko_collector.pyi: imported for internal use, not part of GeckoCollector's public contract. - Strip GeckoCollector internal tracking attributes (has_gil_start, no_gil_start, on_cpu_start, etc.): 20+ state dicts tracking GIL/CPU marker transitions; purely implementation detail. Users call __init__ → collect → export. - Remove FileStats, TreeNode, get_python_path_info, extract_module_name from heatmap_collector.pyi: internal data structures and path helpers for the HTML generation pipeline; not in sampling.__all__, not documented. - Strip HeatmapCollector internal state counters (line_samples, file_samples, call_graph, etc.): implementation detail of the line-level sample accumulation. - Remove re-exports of extract_lineno, normalize_location, format_opcode, get_opcode_info from heatmap_collector.pyi: same pattern — imported for internal use only. - Remove re-exports of extract_lineno, get_opcode_mapping, StringTable from stack_collector.pyi. - Strip CollapsedStackCollector.stack_counter and FlamegraphCollector internal state (thread_status_counts, per_thread_stats, etc.): sample accumulation internals. - Strip DiffFlamegraphCollector.baseline_binary_path attribute: constructor parameter, not a user-facing attribute. - Remove extract_lineno, MICROSECONDS_PER_SECOND, PROFILING_MODE_CPU re-exports from pstats_collector.pyi. - Strip PstatsCollector internal state (result, stats, callers, skip_idle attributes): implementation detail of sample aggregation. - Remove GeckoCollector, PstatsCollector, CollapsedStackCollector, FlamegraphCollector re-exports from binary_reader.pyi: imported internally by binary_reader.py, not part of BinaryReader's API. profiling.sampling — sample and cli modules ------------------------------------------- - Strip sample.pyi of all re-exports (BinaryCollector, Collector, all five PROFILING_MODE_* constants, GeckoCollector, HeatmapCollector, LiveStatsCollector, PstatsCollector, CollapsedStackCollector, FlamegraphCollector): sample.py imports these for internal use; they are not part of sample's public interface and are already accessible from their own modules. - Remove unwinder: Incomplete from SampleProfiler: internal C extension handle, not user-accessible. - Strip cli.pyi to main() only: cli.py is the CLI implementation; all the symbols it re-exported (ChildProcessMonitor, BinaryCollector, BinaryReader, 6 SORT_MODE constants) belong to their own modules. - Delete _child_monitor.pyi: private module (_-prefixed); previously kept because cli.pyi re-exported ChildProcessMonitor, but now that cli.pyi is stripped there is no public re-export, and users have no reason to import from profiling.sampling._child_monitor directly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 36e4dde commit 25c9d89

File tree

11 files changed

+3
-150
lines changed

11 files changed

+3
-150
lines changed

stdlib/profiling/sampling/_child_monitor.pyi

Lines changed: 0 additions & 16 deletions
This file was deleted.

stdlib/profiling/sampling/binary_reader.pyi

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@ from typing import Any
55
from typing_extensions import Self
66

77
from .collector import Collector as Collector
8-
from .gecko_collector import GeckoCollector as GeckoCollector
9-
from .pstats_collector import PstatsCollector as PstatsCollector
10-
from .stack_collector import CollapsedStackCollector as CollapsedStackCollector, FlamegraphCollector as FlamegraphCollector
118

129
class BinaryReader:
1310
filename: str

stdlib/profiling/sampling/cli.pyi

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1 @@
1-
from ._child_monitor import ChildProcessMonitor as ChildProcessMonitor
2-
from .binary_collector import BinaryCollector as BinaryCollector
3-
from .binary_reader import BinaryReader as BinaryReader
4-
from .constants import (
5-
PROFILING_MODE_ALL as PROFILING_MODE_ALL,
6-
PROFILING_MODE_CPU as PROFILING_MODE_CPU,
7-
PROFILING_MODE_EXCEPTION as PROFILING_MODE_EXCEPTION,
8-
PROFILING_MODE_GIL as PROFILING_MODE_GIL,
9-
PROFILING_MODE_WALL as PROFILING_MODE_WALL,
10-
SORT_MODE_CUMTIME as SORT_MODE_CUMTIME,
11-
SORT_MODE_CUMUL_PCT as SORT_MODE_CUMUL_PCT,
12-
SORT_MODE_NSAMPLES as SORT_MODE_NSAMPLES,
13-
SORT_MODE_NSAMPLES_CUMUL as SORT_MODE_NSAMPLES_CUMUL,
14-
SORT_MODE_SAMPLE_PCT as SORT_MODE_SAMPLE_PCT,
15-
SORT_MODE_TOTTIME as SORT_MODE_TOTTIME,
16-
)
17-
181
def main() -> None: ...

stdlib/profiling/sampling/collector.pyi

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,6 @@ from _typeshed import StrOrBytesPath
33
from abc import ABC, abstractmethod
44
from typing import Any
55

6-
from .constants import (
7-
DEFAULT_LOCATION as DEFAULT_LOCATION,
8-
THREAD_STATUS_GIL_REQUESTED as THREAD_STATUS_GIL_REQUESTED,
9-
THREAD_STATUS_HAS_EXCEPTION as THREAD_STATUS_HAS_EXCEPTION,
10-
THREAD_STATUS_HAS_GIL as THREAD_STATUS_HAS_GIL,
11-
THREAD_STATUS_ON_CPU as THREAD_STATUS_ON_CPU,
12-
THREAD_STATUS_UNKNOWN as THREAD_STATUS_UNKNOWN,
13-
)
14-
15-
def normalize_location(location: tuple[int, int, int, int] | None) -> tuple[int, int, int, int]: ...
16-
def extract_lineno(location: tuple[int, int, int, int] | None) -> int: ...
17-
def filter_internal_frames(frames: list[Any]) -> list[Any]: ...
18-
196
class Collector(ABC, metaclass=abc.ABCMeta):
207
@abstractmethod
218
def collect(self, stack_frames: Any, timestamps_us: list[int] | None = None) -> None: ...
Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,8 @@
11
from typing import Any
22

3-
from .collector import Collector as Collector, filter_internal_frames as filter_internal_frames
4-
from .opcode_utils import format_opcode as format_opcode, get_opcode_info as get_opcode_info
3+
from .collector import Collector as Collector
54

65
class GeckoCollector(Collector):
7-
sample_interval_usec: int
8-
skip_idle: bool
9-
opcodes_enabled: bool
10-
start_time: float
11-
global_strings: list[str]
12-
global_string_map: dict[str, int]
13-
threads: dict[int, Any]
14-
libs: list[Any]
15-
sample_count: int
16-
last_sample_time: int
17-
interval: float
18-
has_gil_start: dict[int, float]
19-
no_gil_start: dict[int, float]
20-
on_cpu_start: dict[int, float]
21-
off_cpu_start: dict[int, float]
22-
python_code_start: dict[int, float]
23-
native_code_start: dict[int, float]
24-
gil_wait_start: dict[int, float]
25-
exception_start: dict[int, float]
26-
no_exception_start: dict[int, float]
27-
gc_start_per_thread: dict[int, float]
28-
initialized_threads: set[int]
29-
opcode_state: dict[Any, Any]
306
def __init__(self, sample_interval_usec: int, *, skip_idle: bool = False, opcodes: bool = False) -> None: ...
317
def collect(self, stack_frames: Any, timestamps_us: list[int] | None = None) -> None: ...
328
def export(self, filename: str) -> None: ...

stdlib/profiling/sampling/heatmap_collector.pyi

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,9 @@
11
from _typeshed import StrOrBytesPath
2-
from collections import Counter
3-
from dataclasses import dataclass
42
from typing import Any
53

6-
from .collector import extract_lineno as extract_lineno, normalize_location as normalize_location
7-
from .opcode_utils import format_opcode as format_opcode, get_opcode_info as get_opcode_info
84
from .stack_collector import StackTraceCollector as StackTraceCollector
95

10-
@dataclass
11-
class FileStats:
12-
filename: str
13-
module_name: str
14-
module_type: str
15-
total_samples: int
16-
total_self_samples: int
17-
num_lines: int
18-
max_samples: int
19-
max_self_samples: int
20-
percentage: float = ...
21-
22-
@dataclass
23-
class TreeNode:
24-
files: list[FileStats] = ...
25-
samples: int = ...
26-
count: int = ...
27-
children: dict[str, TreeNode] = ...
28-
29-
def get_python_path_info() -> dict[str, Any]: ...
30-
def extract_module_name(filename: str, path_info: dict[str, Any]) -> str: ...
31-
326
class HeatmapCollector(StackTraceCollector):
33-
FILE_INDEX_FORMAT: str
34-
line_samples: Counter[Any]
35-
file_samples: dict[str, Counter[int]]
36-
line_self_samples: Counter[Any]
37-
file_self_samples: dict[str, Counter[int]]
38-
call_graph: dict[Any, set[Any]]
39-
callers_graph: dict[Any, set[Any]]
40-
function_definitions: dict[Any, Any]
41-
line_to_function: dict[Any, Any]
42-
edge_samples: Counter[Any]
43-
line_opcodes: dict[Any, dict[Any, Any]]
44-
stats: dict[str, Any]
45-
opcodes_enabled: bool
46-
file_index: dict[str, str]
477
def __init__(self, *args: Any, **kwargs: Any) -> None: ...
488
def set_stats(
499
self,
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
def get_opcode_info(opcode_num: int) -> dict[str, str | bool]: ...
22
def format_opcode(opcode_num: int) -> str: ...
3-
def get_opcode_mapping() -> dict[str, dict[int, str] | dict[int, int]]: ...

stdlib/profiling/sampling/pstats_collector.pyi

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
11
from _typeshed import StrOrBytesPath
22
from typing import Any
33

4-
from .collector import Collector as Collector, extract_lineno as extract_lineno
5-
from .constants import MICROSECONDS_PER_SECOND as MICROSECONDS_PER_SECOND, PROFILING_MODE_CPU as PROFILING_MODE_CPU
4+
from .collector import Collector as Collector
65

76
class PstatsCollector(Collector):
8-
result: dict[Any, Any]
9-
stats: dict[Any, Any]
10-
sample_interval_usec: int
11-
callers: dict[Any, Any]
12-
skip_idle: bool
137
def __init__(self, sample_interval_usec: int, *, skip_idle: bool = False) -> None: ...
148
def collect(self, stack_frames: Any, timestamps_us: list[int] | None = None) -> None: ...
159
def export(self, filename: StrOrBytesPath) -> None: ...

stdlib/profiling/sampling/sample.pyi

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,6 @@
1-
from _typeshed import Incomplete
21
from collections import deque
32

4-
from .binary_collector import BinaryCollector as BinaryCollector
53
from .collector import Collector as Collector
6-
from .constants import (
7-
PROFILING_MODE_ALL as PROFILING_MODE_ALL,
8-
PROFILING_MODE_CPU as PROFILING_MODE_CPU,
9-
PROFILING_MODE_EXCEPTION as PROFILING_MODE_EXCEPTION,
10-
PROFILING_MODE_GIL as PROFILING_MODE_GIL,
11-
PROFILING_MODE_WALL as PROFILING_MODE_WALL,
12-
)
13-
from .gecko_collector import GeckoCollector as GeckoCollector
14-
from .heatmap_collector import HeatmapCollector as HeatmapCollector
15-
from .live_collector import LiveStatsCollector as LiveStatsCollector
16-
from .pstats_collector import PstatsCollector as PstatsCollector
17-
from .stack_collector import CollapsedStackCollector as CollapsedStackCollector, FlamegraphCollector as FlamegraphCollector
184

195
class SampleProfiler:
206
pid: int
@@ -23,7 +9,6 @@ class SampleProfiler:
239
mode: int
2410
collect_stats: bool
2511
blocking: bool
26-
unwinder: Incomplete
2712
sample_intervals: deque[float]
2813
total_samples: int
2914
realtime_stats: bool
Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
import abc
22
from _typeshed import StrOrBytesPath
3-
from collections import Counter
43
from typing import Any
54

6-
from .collector import Collector as Collector, extract_lineno as extract_lineno
7-
from .opcode_utils import get_opcode_mapping as get_opcode_mapping
8-
from .string_table import StringTable as StringTable
5+
from .collector import Collector as Collector
96

107
class StackTraceCollector(Collector, metaclass=abc.ABCMeta):
118
sample_interval_usec: int
@@ -15,16 +12,11 @@ class StackTraceCollector(Collector, metaclass=abc.ABCMeta):
1512
def process_frames(self, frames: list[Any], thread_id: int, weight: int = 1) -> None: ...
1613

1714
class CollapsedStackCollector(StackTraceCollector):
18-
stack_counter: Counter[str]
1915
def __init__(self, *args: Any, **kwargs: Any) -> None: ...
2016
def process_frames(self, frames: list[Any], thread_id: int, weight: int = 1) -> None: ...
2117
def export(self, filename: StrOrBytesPath) -> None: ...
2218

2319
class FlamegraphCollector(StackTraceCollector):
24-
stats: dict[str, Any]
25-
thread_status_counts: dict[str, int]
26-
samples_with_gc_frames: int
27-
per_thread_stats: dict[int, Any]
2820
def __init__(self, *args: Any, **kwargs: Any) -> None: ...
2921
def collect(self, stack_frames: Any, timestamps_us: list[int] | None = None) -> None: ...
3022
def set_stats(
@@ -40,5 +32,4 @@ class FlamegraphCollector(StackTraceCollector):
4032
def process_frames(self, frames: list[Any], thread_id: int, weight: int = 1) -> None: ...
4133

4234
class DiffFlamegraphCollector(FlamegraphCollector):
43-
baseline_binary_path: str
4435
def __init__(self, sample_interval_usec: int, *, baseline_binary_path: str, skip_idle: bool = False) -> None: ...

0 commit comments

Comments
 (0)