Skip to content

posix, _queue, _types: what the #1359 review threads left, and the frame the method-load opcodes pushed through - #1367

Merged
youknowone merged 4 commits into
mainfrom
agent/stdlib-foundations
Aug 20, 2026
Merged

posix, _queue, _types: what the #1359 review threads left, and the frame the method-load opcodes pushed through#1367
youknowone merged 4 commits into
mainfrom
agent/stdlib-foundations

Conversation

@youknowone

Copy link
Copy Markdown
Owner

Four follow-ups to the review threads on #1359, each verified against the source it claims to follow.

PyFrame pushed LOAD_METHOD and LOAD_SPECIAL results through a stale frame

PyFrame overrides the anchored shared bodies for both opcodes and pushed through &mut self after getattr_str and load_special_resolve, which run app-level code and allocate. A minor collection there relocates a JIT-created frame, so the push landed on the abandoned copy — the failure c0c99bd fixed for the shared helpers, still open in the two overrides that bypass them.

load_method also reads the popped receiver back after that call to compute the bound value, and compute_load_method_bound returns it for the null_or_self slot, so a relocated receiver could be pushed as the call's receiver. It is pinned across the lookup and read out of its slot.

The spawn calls converted sequences and options across their own collection points

collect_iterable returns a plain vector with its own root scope already dropped, so setgroups and posix_spawn's setsigmask / setsigdef held every unconverted entry in stale locals: converting one entry reaches __index__, and the collection that runs there moves the entries behind it.

build_posix_spawn likewise kept the three bound arguments and the keyword dictionary in plain locals across __fspath__, a mapping's keys() and __index__, and parse_spawn_scheduler read both tuple elements before converting the priority.

sched_setaffinity takes the same vector but converts it with isinstance against a fixed type and int_w on an already-checked int, neither of which reaches app-level code, so it is left alone.

SimpleQueue.get(timeout=float('inf')) blocked forever

_queue_SimpleQueue_get_impl runs _PyTime_FromSecondsObject before the sign check, so a value with no nanosecond timestamp is refused rather than turned into a wait. Reading the seconds as a plain float instead made an infinity block forever and a NaN poll once. CPython 3.14.2 answers OverflowError: timestamp out of range for platform time_t and ValueError: Invalid value NaN (not a number); the bounds and both messages are the ones parse_acquire_args already applies for _thread.lock.acquire.

types.CapsuleType was constructible and subclassable

PyCapsule_Type carries no tp_new and no Py_TPFLAGS_BASETYPE. Both the cpyext type and the fallback inherited object.__new__ and accepted subclasses, so either could produce an object carrying the capsule's name without the payload is_capsule reads.

Verification

cargo check -p pyre-interpreter green for dynasm and dynasm,cpyext. The full pyre/check.py gate and the CPython suite are running locally against this tree; the same four changes passed dynasm 442/442, wasm 435/435 and the CPython suite with no regressions on the pre-rebase base, where the one cranelift red was generator_tree_recursion, the documented boundary flake, attributed away by timing it directly against a control binary (0.74 s vs 0.79 s median).

🤖 Generated with Claude Code

https://claude.ai/code/session_01PuYePQknDcMCUsy8omQ1fh

…frame

`PyFrame` overrides the anchored shared bodies for both opcodes and pushed
through `&mut self` after `getattr_str` and `load_special_resolve`, which run
app-level code and allocate.  A minor collection there relocates a JIT-created
frame, so the push landed on the abandoned copy -- the failure c0c99bd
described for the shared helpers.

`load_method` also reads the popped receiver back after that call to compute
the bound value, and returns it for the `null_or_self` slot, so the receiver is
pinned across the lookup and read out of its slot.

Assisted-by: Claude
…t across

`collect_iterable` returns a plain vector with its own root scope already
dropped, so `setgroups` and `posix_spawn`'s `setsigmask` / `setsigdef` held
every unconverted entry in stale locals: converting one entry reaches
`__index__`, and the collection that runs there moves the entries behind it.

`build_posix_spawn` likewise kept the three bound arguments and the keyword
dictionary in plain locals across `__fspath__`, a mapping's `keys()` and
`__index__`, and `parse_spawn_scheduler` read both tuple elements before
converting the priority.  Each is pinned and read back at its use.

`sched_setaffinity` takes the same vector but converts it with `isinstance`
against a fixed type and `int_w` on an already-checked int, neither of which
reaches app-level code.

Assisted-by: Claude
`_queue_SimpleQueue_get_impl` runs `_PyTime_FromSecondsObject` before the sign
check, so a value with no nanosecond timestamp is refused rather than turned
into a wait.  Reading the seconds as a plain float instead made
`get(timeout=float('inf'))` block forever and `get(timeout=float('nan'))` poll
once.  The bounds and the two messages are the ones `parse_acquire_args`
already applies for `_thread.lock.acquire`.

CPython 3.14.2 answers `OverflowError: timestamp out of range for platform
time_t` for an infinity and `ValueError: Invalid value NaN (not a number)` for
a NaN.

Assisted-by: Claude
`PyCapsule_Type` carries no `tp_new` and no `Py_TPFLAGS_BASETYPE`; both the
cpyext type and the fallback `types.CapsuleType` inherited `object.__new__`
and accepted subclasses, so either could produce an object that carries the
capsule's name without the payload `is_capsule` reads.

Assisted-by: Claude
@coderabbitai

coderabbitai Bot commented Aug 20, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@youknowone, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 22 minutes

Limit details: You’ve used all 2 included reviews currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

Wait for the limit to reset, then comment @coderabbitai review or push new commits to the PR.

An organization admin can change what happens after included review limits in Billing.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 056c6c8a-48f9-4353-bf83-3f99045970ed

📥 Commits

Reviewing files that changed from the base of the PR and between dc8ee02 and 3c2e302.

📒 Files selected for processing (5)
  • pyre/pyre-interpreter/src/cpyext/capsule.rs
  • pyre/pyre-interpreter/src/eval.rs
  • pyre/pyre-interpreter/src/module/_queue/mod.rs
  • pyre/pyre-interpreter/src/module/_types/mod.rs
  • pyre/pyre-interpreter/src/module/posix/interp_posix.rs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3c2e302801

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +35 to +38
pyre_object::dictmultiobject::w_dict_setitem_str_no_proxy(
ns,
"__new__",
crate::typedef::make_new_descr(|_| {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep __new__ out of the capsule type dictionary

When code introspects types.CapsuleType, this insertion makes "__new__" in vars(types.CapsuleType) true and exposes a capsule-specific descriptor, whereas CPython's null tp_new and PyPy's W_Capsule.typedef both leave __new__ absent while still rejecting construction. The fallback type in _types/mod.rs duplicates the same observable mismatch; construction should be disabled in the type machinery without adding a dictionary entry.

AGENTS.md reference: AGENTS.md:L165-L166

Useful? React with 👍 / 👎.

@github-actions

Copy link
Copy Markdown

🤖 Codex parity review

Static analysis of this diff vs the local RPython/PyPy sources (commit 3c2e302).
Updated: 2026-08-20T04:34:12.196Z

Files in the reviewed diff
pyre/pyre-interpreter/src/cpyext/capsule.rs
pyre/pyre-interpreter/src/eval.rs
pyre/pyre-interpreter/src/module/_queue/mod.rs
pyre/pyre-interpreter/src/module/_types/mod.rs
pyre/pyre-interpreter/src/module/posix/interp_posix.rs

1. Regressions to PyPy parity introduced by this patch

None.

2. Other mismatches introduced by this patch

None.

3. Pre-existing mismatches (already present before this patch)

None.

4. Structural adaptations

  • pyre/pyre-interpreter/src/eval.rs:4760 ↔ pypy/objspace/std/callmethod.py:79: shadow-stack rooting and FrameAnchor forwarding are Rust moving-GC mechanics around PyPy’s same fallback space.getattr(w_obj, w_name) / stack-push operation; no observable semantic deviation.

  • pyre/pyre-interpreter/src/module/posix/interp_posix.rs:6191 ↔ pypy/module/posix/interp_posix.py:2129: retaining the unpacked group elements in Pyre’s shadow stack is required because Rust vectors/raw references are not translated RPython GC live variables. The resulting iterable conversion and c_uid_t_w behavior remains aligned.

  • pyre/pyre-interpreter/src/cpyext/capsule.rs:48 ↔ pypy/interpreter/typedef.py:55: explicitly disallowing PyCapsule as a base class implements PyPy’s TypeDef rule that only types defining __new__ are acceptable bases. The explicit rejecting __new__ is the Rust representation of the same non-instantiable capsule type shape.

@youknowone
youknowone merged commit 2e1b36e into main Aug 20, 2026
17 checks passed
@youknowone
youknowone deleted the agent/stdlib-foundations branch August 20, 2026 07:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant