Skip to content

Commit 26ea0d3

Browse files
committed
docs: incorporate Bound guidance and examples
1 parent 0089b51 commit 26ea0d3

File tree

2 files changed

+53
-5
lines changed

2 files changed

+53
-5
lines changed

.agents/tasks/2025/08/21-0939-codetype-interface

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,20 @@ Here's relevant information:
1717
* design-docs/design-001.md - shows how we write design documentation
1818
* https://docs.python.org/3/library/sys.monitoring.html - Documentation of the Python sys.montoring API
1919
* https://docs.python.org/3/reference/datamodel.html#code-objects - Description of Python Code Objects.
20+
21+
--- FOLLOW UP TASK ---
22+
Please address any inline comments on the diff, as well as any additional instructions below.
23+
24+
According to the PyO3 documentation it is preferred to use instead of Py<T>. Is it possible that the code object wrapper takes that into account? Here is relevant info:
25+
* https://pyo3.rs/v0.25.1/types.html
26+
* https://docs.rs/pyo3/0.25.1/pyo3/index.html
27+
28+
Also please add usage examples to the design documentation
29+
--- FOLLOW UP TASK ---
30+
Please address any inline comments on the diff, as well as any additional instructions below.
31+
32+
According to the PyO3 documentation it is preferred to use `Bound<'_, T>` instead of Py<T>. Is it possible that the code object wrapper takes that into account? Here is relevant info:
33+
* https://pyo3.rs/v0.25.1/types.html
34+
* https://docs.rs/pyo3/0.25.1/pyo3/index.html
35+
36+
Also please add usage examples to the design documentation

design-docs/code-object.md

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ The Python Monitoring API delivers a generic `CodeType` object to every tracing
1818

1919
```rs
2020
pub struct CodeObjectWrapper {
21-
/// Strong reference to the Python `CodeType` object.
22-
obj: Py<PyAny>,
21+
/// Owned reference to the Python `CodeType` object.
22+
/// Stored as `Py<PyCode>` so it can be held outside the GIL.
23+
obj: Py<PyCode>,
2324
/// Stable identity equivalent to `id(code)`.
2425
id: usize,
2526
/// Lazily populated cache for expensive lookups.
@@ -42,8 +43,13 @@ pub struct LineEntry {
4243
}
4344

4445
impl CodeObjectWrapper {
45-
/// Construct from a generic Python object. Computes `id` eagerly.
46-
pub fn new(py: Python<'_>, obj: &Bound<'_, PyAny>) -> Self;
46+
/// Construct from a `CodeType` object. Computes `id` eagerly.
47+
pub fn new(py: Python<'_>, obj: &Bound<'_, PyCode>) -> Self;
48+
49+
/// Borrow the owned `Py<PyCode>` as a `Bound<'py, PyCode>`.
50+
/// This follows PyO3's recommendation to prefer `Bound<'_, T>` over `Py<T>`
51+
/// for object manipulation.
52+
pub fn as_bound<'py>(&'py self, py: Python<'py>) -> Bound<'py, PyCode>;
4753

4854
/// Accessors fetch from the cache or perform a one‑time lookup under the GIL.
4955
pub fn filename<'py>(&'py self, py: Python<'py>) -> PyResult<&'py str>;
@@ -70,8 +76,33 @@ fn on_py_start(&mut self, py: Python<'_>, code: &CodeObjectWrapper, offset: i32)
7076
// ...and similarly for the remaining callbacks.
7177
```
7278

79+
## Usage Examples
80+
81+
### Constructing the wrapper inside a tracer
82+
83+
```rs
84+
fn on_line(&mut self, py: Python<'_>, code: &Bound<'_, PyCode>, lineno: u32) {
85+
let wrapper = CodeObjectWrapper::new(py, code);
86+
let filename = wrapper.filename(py).unwrap_or("<unknown>");
87+
eprintln!("{}:{}", filename, lineno);
88+
}
89+
```
90+
91+
### Reusing a cached wrapper
92+
93+
```rs
94+
let wrapper = CodeObjectWrapper::new(py, code);
95+
cache.insert(wrapper.id(), wrapper.clone());
96+
97+
if let Some(saved) = cache.get(&wrapper.id()) {
98+
let qualname = saved.qualname(py)?;
99+
println!("qualified name: {}", qualname);
100+
}
101+
```
102+
73103
## Performance Considerations
74-
- `Py<PyAny>` allows cloning the wrapper without holding the GIL, enabling cheap event propagation.
104+
- `Py<PyCode>` allows cloning the wrapper without holding the GIL, enabling cheap event propagation.
105+
- Methods bind the owned reference to `Bound<'py, PyCode>` on demand, following PyO3's `Bound`‑first guidance and avoiding accidental `Py` clones.
75106
- Fields are loaded lazily and stored inside `OnceCell` containers to avoid repeated attribute lookups.
76107
- `line_for_offset` memoizes the full line table the first time it is requested; subsequent calls perform an in‑memory binary search.
77108
- Storing strings and small integers directly in the cache eliminates conversion cost on hot paths.

0 commit comments

Comments
 (0)