Skip to content

Conversation

@youknowone
Copy link
Member

@youknowone youknowone commented Jan 20, 2026

Summary by CodeRabbit

  • Refactor
    • Updated timeout parameter implementation to accept a broader range of numeric input values with enhanced validation and improved error handling.
    • Added robust edge-case management for special input values including negative numbers and numeric overflow detection.
    • All core functionality and existing error handling mechanisms remain unchanged.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 20, 2026

📝 Walkthrough

Walkthrough

The WaitForSingleObject function signature in the Windows API wrapper was updated to accept i64 milliseconds instead of u32. Input validation logic was added to map negative values to INFINITE, reject values exceeding u32::MAX with an overflow error, and cast valid values to u32 for the underlying Windows API call.

Changes

Cohort / File(s) Summary
WaitForSingleObject validation enhancement
crates/vm/src/stdlib/winapi.rs
Updated function signature to accept ms: i64 parameter. Added downstream validation: negative values map to INFINITE, overflow checking for values exceeding u32::MAX, and conditional casting to u32.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A timer once bound by thirty-two bits,
Now takes the full range—no more throwing fits!
We handle the negatives, check for the spills,
And cast safely down through validation's mills.
Windows will wait, and our logic rings true,
A hop toward robustness, through and through! 🐇

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title 'libregrtest from 3.14.2' does not align with the actual changes, which involve updating WaitForSingleObject function signature and adding input validation for the Windows API wrapper. Update the PR title to accurately reflect the main change, such as 'Update WaitForSingleObject signature to accept i64 with validation' or 'Add input validation to WaitForSingleObject for ms parameter'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

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 and usage tips.

@youknowone youknowone marked this pull request as ready for review January 20, 2026 16:23
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@crates/stdlib/src/gc.rs`:
- Around line 5-13: The module attribute definition for gc.garbage uses
#[pyattr] which recreates an empty list on each access; change the attribute to
#[pyattr(once)] on the garbage function so the created list is stored/persistent
across accesses (matching CPython semantics) — update the attribute macro on the
garbage function (fn garbage(vm: &VirtualMachine) -> PyObjectRef) to
#[pyattr(once)] so gc.garbage returns the same mutable list instance each time.

Comment on lines 5 to 13
use crate::vm::{PyObjectRef, PyResult, VirtualMachine, function::FuncArgs};

/// A list of objects which the collector found to be unreachable
/// but could not be freed. RustPython doesn't have cyclic GC,
/// so this is always an empty list.
#[pyattr]
fn garbage(vm: &VirtualMachine) -> PyObjectRef {
vm.ctx.new_list(vec![]).into()
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Find the #[pyattr] macro definition
fd -t f "*.rs" | xargs rg -l "#\[pyattr\]" | head -5

Repository: RustPython/RustPython

Length of output: 515


🏁 Script executed:

# Search for how #[pyattr] macro is defined
rg -t rs "macro.*pyattr|impl.*pyattr" --max-count=20

Repository: RustPython/RustPython

Length of output: 91


🏁 Script executed:

# Look at the gc module context around this function
cat -n crates/stdlib/src/gc.rs

Repository: RustPython/RustPython

Length of output: 2976


🏁 Script executed:

# Check if there's any module initialization or attribute setting
rg -t rs "garbage" crates/stdlib/src/gc.rs -B 5 -A 5

Repository: RustPython/RustPython

Length of output: 91


🏁 Script executed:

# Look for gc.garbage tests in CPython test suite or RustPython tests
fd -t f "test_gc.py" -o "gc_test*" -o "*gc*.py" | xargs rg -l "garbage" 2>/dev/null | head -10

Repository: RustPython/RustPython

Length of output: 467


🏁 Script executed:

# Search for #[pyattr] macro definition and implementation
fd "lib.rs" crates | xargs grep -l "pyattr" | head -5

Repository: RustPython/RustPython

Length of output: 144


🏁 Script executed:

# Look for pyattr macro in derive or macro crates
fd "*.rs" crates | xargs grep -l "macro.*pyattr\|#\[proc_macro"

Repository: RustPython/RustPython

Length of output: 350


🏁 Script executed:

# Search for how pyattr is used elsewhere in stdlib
fd "*.rs" crates/stdlib/src | xargs grep -A 3 "#\[pyattr\]" | head -40

Repository: RustPython/RustPython

Length of output: 348


🏁 Script executed:

# Check for any cached or persistent attribute patterns in the module system
rg "pyattr|PyAttr" crates/pymodule --max-count=30 -B 2 -A 2

Repository: RustPython/RustPython

Length of output: 120


🏁 Script executed:

# Search test directory for gc.garbage related tests
fd "test.*gc\|gc.*test" Lib/test 2>/dev/null || fd "test" Lib | grep gc

Repository: RustPython/RustPython

Length of output: 47


🏁 Script executed:

# Look directly for gc.garbage in test files
rg "garbage" Lib/test -l 2>/dev/null | head -5

Repository: RustPython/RustPython

Length of output: 213


🏁 Script executed:

# Read the pyattr macro definition
head -200 crates/derive/src/lib.rs | tail -100

Repository: RustPython/RustPython

Length of output: 3916


🏁 Script executed:

# Get more of the derive lib file to find pyattr
rg "pyattr" crates/derive/src/lib.rs -B 5 -A 15 | head -80

Repository: RustPython/RustPython

Length of output: 2635


🏁 Script executed:

# Check how pyattr is used in hashlib
rg "#\[pyattr\]" crates/stdlib/src/hashlib.rs -B 2 -A 5

Repository: RustPython/RustPython

Length of output: 725


🏁 Script executed:

# Check how pyattr is used in zlib
rg "#\[pyattr\]" crates/stdlib/src/zlib.rs -B 2 -A 5

Repository: RustPython/RustPython

Length of output: 1542


🏁 Script executed:

# Search for pyattr in entire codebase with more context
rg "pyattr" --max-count=50 -B 3 -A 3 crates

Repository: RustPython/RustPython

Length of output: 50378


🏁 Script executed:

# Check if there are any RustPython tests for gc.garbage
fd "gc" Lib/test --type f | head -10

Repository: RustPython/RustPython

Length of output: 255


🏁 Script executed:

# Look for how gc module is initialized or used in tests
rg "gc\.garbage" Lib 2>/dev/null | head -20

Repository: RustPython/RustPython

Length of output: 1114


Use #[pyattr(once)] to make gc.garbage persistent across accesses.

The #[pyattr] macro without (once) recomputes the value on each attribute access, creating a new empty list every time. This breaks compatibility with CPython, where gc.garbage is a mutable list that persists between reads. Code that modifies it (e.g., gc.garbage.clear() in tests) will lose those changes. Use #[pyattr(once)] instead to cache the result in a static cell, matching the pattern used elsewhere in RustPython for persistent module attributes.

🤖 Prompt for AI Agents
In `@crates/stdlib/src/gc.rs` around lines 5 - 13, The module attribute definition
for gc.garbage uses #[pyattr] which recreates an empty list on each access;
change the attribute to #[pyattr(once)] on the garbage function so the created
list is stored/persistent across accesses (matching CPython semantics) — update
the attribute macro on the garbage function (fn garbage(vm: &VirtualMachine) ->
PyObjectRef) to #[pyattr(once)] so gc.garbage returns the same mutable list
instance each time.

Comment on lines 175 to 183
if gc.garbage:
support.environment_altered = True
print_warning(f"{test_name} created {len(gc.garbage)} "
f"uncollectable object(s)")

# # move the uncollectable objects somewhere, # TODO: RUSTPYTHON, build a functional garbage collector into the interpreter
# # so we don't see them again # TODO: RUSTPYTHON, build a functional garbage collector into the interpreter
# GC_GARBAGE.extend(gc.garbage) # TODO: RUSTPYTHON, build a functional garbage collector into the interpreter
# gc.garbage.clear() # TODO: RUSTPYTHON, build a functional garbage collector into the interpreter
# move the uncollectable objects somewhere,
# so we don't see them again
GC_GARBAGE.extend(gc.garbage)
gc.garbage.clear()
Copy link
Contributor

Choose a reason for hiding this comment

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

See #4158

@youknowone youknowone force-pushed the regrtest branch 2 times, most recently from eff49b4 to 6c17e07 Compare January 21, 2026 09:14
@youknowone youknowone merged commit 726a053 into RustPython:main Jan 21, 2026
14 checks passed
@youknowone youknowone deleted the regrtest branch January 21, 2026 12:35
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.

2 participants