← 输入框|github.com|刷新
Skip to content

Validate sleep against Python 3.14 signed time bounds - #9051

Merged
youknowone merged 1 commit into
RustPython:mainfrom
youknowdot:fix-sleep-signed-time-range
Oct 10, 2026
Merged

youknowone merged 1 commit into
RustPython:mainfrom
youknowdot:fix-sleep-signed-time-range

Conversation

@youknowdot

@youknowdot youknowdot commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Extract the independent signed-time range validation from #8954 (43065e79ddc46eafeca58cb39398ac007b5d25f7), adapted locally to Python 3.14 on main 3af5f8a15314446d2b28a90e429c938dc7b8beeb.

  • Validate time.sleep using signed 64-bit nanoseconds, with checked integer multiplication and timeout rounding away from zero.
  • Preserve 3.14's actual-float-payload-first / otherwise-__index__ protocol, including subclass behavior. Do not adopt the mega's 3.15 input widening or its new shared pytime module.
  • Preserve audit ordering, NaN/negative distinctions, and exact range/conversion exceptions.
  • Keep qualified type diagnostics lossless and propagate class-dictionary lookup exceptions, without changing shared type helpers.

Reference: CPython 3.14.7 sleep, signed-time conversion, and type metadata formatting.

Related work

Open #5907 addresses related invalid sleep inputs and is not being replaced or modified by this PR. Its current patch targets the old split-platform vm/src implementation, applies u64-second versus u32-millisecond bounds, accepts general float conversion, and expects ValueError for infinity/huge values. Current main has a unified audited sleep function, while the exact 3.14 contract requires signed nanoseconds and OverflowError. Reusing that patch would require replacing its central implementation and test expectations. Merged #5906 and #7073 are already in the base.

Validation

  • Exact CPython 3.14.7 and this native head pass the complete updated time snippet and canonical test_sleep_exceptions.
  • Native snippet pytest passes.
  • Both interpreters pass 34 bounded evidence cases: 19 range/protocol cases, 10 qualified-type diagnostics, and 5 class-dictionary lookup cases preserving exception identity.
  • Every invalid-input runtime probe was externally limited to five seconds. All tested invalid values fail before the platform sleeper. Huge-duration calls were deliberately not executed on unchanged main.
  • VM Clippy and separate C-API Clippy with warnings denied; normal repository commit hooks.
  • Independent source reviews checked conversion precedence, rounding, signed bounds, lossless names, lock release and dictionary comparison errors before native validation.

Coverage is in the existing Python snippet; canonical tests, shared duration conversion, platform sleepers and README are unchanged. No Rust behavioral tests or implementation-name guards were added. Local validation is bounded Linux validation, not a complete workspace/cross-platform test claim or a test of very large accepted sleeps. Full hosted CI is pending; this remains a draft for review.

AI-assisted implementation and validation with OpenAI Codex; model identifier unavailable. No human review is implied.

Summary by CodeRabbit

  • Bug Fixes
    • time.sleep now handles fractional and integer durations consistently, rejects invalid values with the appropriate errors, and reports unsupported argument types more accurately.
    • Added coverage for out-of-range durations, NaN values, and unsupported argument types.

Assisted-by: OpenAI Codex:model identifier unavailable
@coderabbitai

coderabbitai Bot commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: RustPython/RustPython/.coderabbit.yml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: b8505de1-b2f1-46eb-bbf7-40bf74a3c625

📥 Commits

Reviewing files that changed from the base of the PR and between 3af5f8a and d22a003.


📒 Files selected for processing (2)
  • crates/vm/src/stdlib/time.rs
  • extra_tests/snippets/stdlib_time.py

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 2 remain after this review.



📝 Walkthrough

Walkthrough

time.sleep now converts float and indexable arguments to nanoseconds with explicit range checks and error handling. New tests check range errors, NaN, and unsupported argument types.

Changes

time.sleep argument conversion

Layer / File(s) Summary
Nanosecond conversion and exception checks
crates/vm/src/stdlib/time.rs, extra_tests/snippets/stdlib_time.py
time.sleep rounds floats away from zero, checks the signed 64-bit nanosecond range, and converts other arguments through __index__ with overflow checks. Negative durations raise ValueError; unsupported objects raise TypeError with their qualified type name. Tests check these error cases.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Suggested reviewers: youknowone


Merge Risk: ⚪ Minimal · up to d22a0

time.sleep now validates its argument against signed 64-bit nanosecond bounds and raises the expected exceptions for out-of-range, NaN and unsupported inputs. No actionable merge-blocking risk was found. The author reports bounded Linux testing only, with full CI still pending.

Pre-merge checks | Passed 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: validating time.sleep against Python 3.14 signed time bounds.
Docstring Coverage Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 2 files.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@youknowone
youknowone marked this pull request as ready for review October 10, 2026 10:58
@youknowone
youknowone enabled auto-merge (squash) October 10, 2026 10:58
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-10T11:07:40.080713Z d22a003 Draft marked ready
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@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: d22a003464

ℹ️ 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 +159 to +160
dict.get_item_opt(identifier!(vm, __module__), vm)?
.ok_or_else(|| vm.new_attribute_error("__module__"))?

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 Preserve TypeError when heap types have no module

On WebAssembly, time.sleep(sys.stdout) reaches this branch because make_stdstream_object creates the stream class with py_class!, whose new_class(None, ...) leaves the heap-type dictionary without __module__ (crates/wasm/src/wasm_builtins.rs:32 and crates/vm/src/macros.rs:38). This ok_or_else therefore replaces the original unsupported-input TypeError with AttributeError("__module__"); before this change the diagnostic used class().name() and remained a TypeError. Treat an absent module as an unqualified type name, or populate it for every internal heap type.

AGENTS.md reference: AGENTS.md:L11-L11

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I checked the missing-module case against exact CPython 3.14.7 using a heap type whose real namespace is exposed through classdictcell, then removing module from that namespace. CPython raises AttributeError("module"), and the published RustPython head does the same. The existing five-case type-dictionary oracle also verifies that lookup exceptions retain their identity. Falling back to an unqualified name here would therefore change verified CPython behavior. The internal WASM construction path is a separate type-metadata question; I have not run WASM locally or changed that construction.

@youknowone
youknowone merged commit 146bb80 into RustPython:main Oct 10, 2026
30 checks passed
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