Skip to content

Commit 96f3429

Browse files
pdepetrometa-codesync[bot]
authored andcommitted
Fix tintype PYTHON_API.md to match the actual library API
Summary: Audited tintype/PYTHON_API.md against the C++ binding (_snapshot.cpp), the type stub (_snapshot.pyi), the Python wrappers, and SnapshotCapture.cpp, then corrected the inaccuracies: - Removed the incorrect "stacktrace ID 0" model. Thread/traceback captures key the stacktrace by the native thread identifier (not 0), and the exception-chain path creates no separate thread stacktrace (only sequential IDs starting from 1). Fixed the take_snapshot parameter docs and the Snapshot.stacktraces attribute description. - Corrected the enable_sampling Raises note: it raises RuntimeError under free-threaded (no-GIL) Python, not "Python < 3.12" (no such version check exists). - Documented the previously-missing snapshot_all_threads RuntimeError under free-threaded Python. - Added the undocumented Snapshot.get_next_snapshot() and SnapshotReader.get_working_file_path() methods. - Completed the get_stats() key list: snapshot_breakdown.frames_filtered, snapshot_breakdown.snapshots_discarded, object_queue_breakdown.objects_cache_hit, object_queue_breakdown.string_bytes_cache_hit, top-level errors, and top-level file_extension. - Fixed the broken FILE_FORMAT.md link to point to snapshot_lib/FILE_FORMAT.md. ___ Differential Revision: D108816489 fbshipit-source-id: fc9864f6598c8e554ef7c01a6f9bb05f7564a6c1
1 parent 57fbf69 commit 96f3429

1 file changed

Lines changed: 14 additions & 8 deletions

File tree

PYTHON_API.md

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,9 @@ Take a snapshot. Multiple snapshots can be taken before `finalize()`.
145145

146146
**Parameters:**
147147
- `traceback_or_exception` (`TracebackType | BaseException | None`, default `None`):
148-
- `None`: Capture the current call stack (thread snapshot, stacktrace ID 0).
149-
- `TracebackType`: Capture the frames from a traceback object (stacktrace ID 0).
150-
- `BaseException`: Capture the exception's traceback and the full `__cause__`/`__context__` chain. The thread stacktrace gets ID 0; exception stacktraces get sequential IDs starting from 1.
148+
- `None`: Capture the current call stack as a single stacktrace keyed by the native thread identifier (same as `threading.get_ident()`).
149+
- `TracebackType`: Capture the frames from a traceback object as a single stacktrace keyed by the native thread identifier.
150+
- `BaseException`: Capture the exception's traceback and the full `__cause__`/`__context__` chain. No separate thread stacktrace is captured; the exception stacktraces get sequential IDs starting from 1.
151151
- `max_frames` (`int | None`, default `None`): Maximum number of frames to capture per stacktrace. `None` means no limit. When the limit is reached, the stacktrace is marked as truncated.
152152
- `max_object_depth` (`int | None`, default `None`): Maximum depth of object graph traversal. Depth 0 is the frame's local variables. When the limit is reached, non-primitive objects are serialized as their `repr()` string with no children. `None` means no limit. When triggered, the `object_depth_truncated` flag is set on the `Stacktrace` object (the `truncated` flag is NOT affected — it only reflects frame omission).
153153
- `timeout` (`float | None`, default `None`): Maximum time in seconds for the entire snapshot operation. `None` means no timeout. If the timeout is reached, processing stops and any in-progress frame is discarded. Completed frames are preserved.
@@ -185,10 +185,12 @@ Get timing and performance statistics. Only populated if `initialize(collect_sta
185185
- `total_objects`: Total number of objects serialized to the heap
186186
- `snapshot_breakdown`: Granular snapshot timing:
187187
- `write_frame_record_time_ms`
188-
- `total_frame_count`, `total_objects_processed`
188+
- `total_frame_count`, `frames_filtered`, `total_objects_processed`, `snapshots_discarded`
189189
- `object_queue_breakdown`: Granular object queue timing:
190190
- `object_lookup_time_ms`, `object_processing_time_ms`, `repr_time_ms`, `slots_time_ms`, `attr_access_time_ms`, `class_members_time_ms`, `serialization_time_ms`
191-
- `objects_skipped`
191+
- `objects_skipped`, `objects_cache_hit`, `string_bytes_cache_hit`
192+
- `errors`: Total number of errors encountered across all subsystems.
193+
- `file_extension`: Source-file embedding stats: `{time_ms, count, bytes}`.
192194
- `object_stats`: Per-type statistics mapping type name to `{count, total_time_ms, avg_time_us, total_bytes, avg_bytes}`
193195
- `finalize_breakdown`: Granular finalize timing:
194196
- `file_table_time_ms`, `environment_time_ms`, `manifest_time_ms`, `metadata_time_ms`, `msync_time_ms`, `compression_time_ms`, `output_file_time_ms`, `cleanup_time_ms`
@@ -211,6 +213,8 @@ Capture all Python threads' call stacks in a single snapshot record. Uses `sys._
211213

212214
Auto-initializes with `collect_stats=False` if not already initialized.
213215

216+
**Raises:** `RuntimeError` if running under free-threaded (no-GIL) Python, where capturing other threads' frames can deadlock. Use `take_snapshot()` to capture the current thread instead.
217+
214218
**Reentrancy:** While `snapshot_all_threads()` is running, concurrent calls to `take_snapshot()`, `take_snapshot(exception)`, and `snapshot_all_threads()` return `None` immediately. The reverse also holds — `snapshot_all_threads()` returns `None` if `take_snapshot()` is in progress.
215219

216220
**Stacktrace IDs:** Each stacktrace's `id` is the native thread identifier (same as `threading.get_ident()`), not the sequential IDs used by exception chain snapshots. Thread stacktraces have `exception_object = None`.
@@ -251,7 +255,7 @@ Start periodic sampling. Spawns a C++ timer thread that periodically takes snaps
251255
- `max_object_depth` (`int | None`, default `None`): Maximum depth of object graph traversal. `None` means no limit.
252256
- `timeout` (`float`, default `1.0`): Timeout per sample in seconds. In `ALL_THREADS` mode, this is passed to `snapshot_all_threads()`.
253257

254-
**Raises:** `RuntimeError` if sampling is already active or if Python < 3.12.
258+
**Raises:** `RuntimeError` if sampling is already active, or if running under free-threaded (no-GIL) Python, where sampling is unsupported because capturing other threads' frames can deadlock.
255259

256260
The sampling timer thread is invisible to `snapshot_all_threads()` — it has no Python frames and does not appear in snapshots.
257261

@@ -350,6 +354,7 @@ Open a snapshot file for reading. The file may be zstd-compressed or uncompresse
350354
| `get_stats()` | `dict[str, int]` | Get statistics. Returns live stats for borrowed readers, file stats for file-based readers. |
351355
| `get_all_source_files()` | `list[SourceFile]` | Get all embedded source files. |
352356
| `get_extracted_files_dir()` | `str` | Path to temp directory with extracted source files. |
357+
| `get_working_file_path()` | `str \| None` | Path to the file mmapped by this reader: the temporary decompressed file for file-based readers, or the writer's backing file for borrowed-memory readers. `None` if unavailable. |
353358
| `get_last_error()` | `str` | Last error message. Empty if no error. |
354359
| `_read_raw_object(offset)` | `dict \| bool \| None` | Read a raw object from the heap by offset. Internal use only. |
355360
| `get_python_object(python_id, object_map)` | `Any` | Resolve a Python object ID to a Python object. |
@@ -371,7 +376,7 @@ Represents a single snapshot record. Contains one or more stacktraces and an obj
371376
|-----------|------|-------------|
372377
| `timestamp` | `int` | Unix timestamp in microseconds when the snapshot was taken. |
373378
| `truncated` | `bool` | `True` if this snapshot was truncated due to cancellation, `max_frames`, or timeout. |
374-
| `stacktraces` | `dict[int, Stacktrace]` | Map from stacktrace ID to `Stacktrace`. ID 0 is the thread/traceback snapshot; IDs 1+ are exception chain entries. |
379+
| `stacktraces` | `dict[int, Stacktrace]` | Map from stacktrace ID to `Stacktrace`. For thread/traceback snapshots the key is the native thread identifier; for exception snapshots the keys are sequential IDs starting from 1. |
375380
| `object_map` | `dict[int, int]` | Map from Python object ID to heap offset, used to resolve variable references. |
376381

377382
#### Methods
@@ -380,6 +385,7 @@ Represents a single snapshot record. Contains one or more stacktraces and an obj
380385
|--------|-------------|-------------|
381386
| `frames()` | `list[Frame]` | Convenience accessor: frames from the first stacktrace. |
382387
| `get_prev_snapshot()` | `Snapshot \| None` | Get the previous snapshot in the linked list, or `None` if this is the first snapshot. Caches the result. |
388+
| `get_next_snapshot()` | `Snapshot \| None` | Get the next (chronologically newer) snapshot, or `None` if this is the most recent snapshot. Caches the result. For borrowed (live) readers, a `None` result is not cached, since newer snapshots may still be appended. |
383389
| `get_python_object(python_id)` | `Any` | Resolve a Python object ID using this snapshot's object map and reader. |
384390

385391
### `Stacktrace`
@@ -545,4 +551,4 @@ with sampling(interval, path=path):
545551

546552
## Related Documentation
547553

548-
- [FILE_FORMAT.md](FILE_FORMAT.md) — Binary file format specification with byte-level struct definitions.
554+
- [FILE_FORMAT.md](snapshot_lib/FILE_FORMAT.md) — Binary file format specification with byte-level struct definitions.

0 commit comments

Comments
 (0)