Fix windows socket by youknowone · Pull Request #6408 · RustPython/RustPython
Summary by CodeRabbit
Release Notes
-
API Changes
- Socket methods
fileno()anddetach()now return integer values instead of raw socket objects. Code using these methods may require updates.
- Socket methods
-
Refactoring
- Internal path handling implementation updated with improved buffer handling mechanisms.
✏️ Tip: You can customize this high-level summary in your review settings.
Walkthrough
Two public method signatures updated for improved type handling: Socket methods detach() and fileno() now return i64 instead of RawSocket, and the path splitting utility _path_splitroot now returns Wtf8Buf pairs instead of String pairs with a PyResult wrapper.
Changes
| Cohort / File(s) | Summary |
|---|---|
Socket API Return Type Updates crates/stdlib/src/socket.rs |
Updated public method signatures: detach() and fileno() now return i64 instead of RawSocket. Implementation adjusted to convert socket file descriptors and invalid socket constants to i64. Call sites in close() and repr_str adapted to handle the new return types. |
Path Splitting Buffer Refactor crates/vm/src/stdlib/nt.rs |
Refactored _path_splitroot signature to return (Wtf8Buf, Wtf8Buf) instead of PyResult<(String, String)>. Parameter vm renamed to _vm (unused). Implementation now uses Wtf8Buf::from_wide for buffer handling instead of String decoding via UTF-16 conversion. |
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~20 minutes
- Verify type consistency across socket method call sites, particularly in
close()andrepr_str()where type conversions occur - Confirm Wtf8Buf conversions in
_path_splitrootpreserve correct buffer semantics and handle edge cases (empty paths, invalid inputs) - Ensure no downstream callers of these methods are affected by the signature changes
Suggested reviewers
- ShaharNaveh
Poem
🐰 A socket's file now dances with i64,
And paths split wide through buffers galore,
Where Wtf8 buffers take String's old place,
The refactor hops with encoding grace! ✨
Pre-merge checks and finishing touches
❌ Failed checks (1 inconclusive)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Title check | ❓ Inconclusive | The title 'Fix windows socket' is vague and overly generic, failing to convey the specific nature of the changes made to socket return types and related Windows path handling. | Provide a more descriptive title that specifies the main changes, such as 'Change socket fileno/detach return types to i64' or 'Update socket API to use i64 instead of RawSocket'. |
✅ 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%. |
✨ Finishing touches
- 📝 Generate docstrings
🧪 Generate unit tests (beta)
- Create PR with unit tests
- Post copyable unit tests in a comment
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.
Comment @coderabbitai help to get the list of available commands and usage tips.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
crates/stdlib/src/socket.rs (1)
1462-1468: Verify Windows SOCKET handle range assumptions.The code assumes that socket handles fit within
i64::MAXon Windows. While this is true in practice (Windows SOCKET handles are kernel handles that won't exceed this range), the cast fromusize(which SOCKET is on 64-bit Windows) toi64could theoretically overflow for values abovei64::MAX.Consider adding a debug assertion or comment documenting this assumption.
#[pymethod] fn close(&self) -> io::Result<()> { let sock = self.detach(); + // Windows SOCKET handles are kernel handles that always fit in i64 if sock != INVALID_SOCKET as i64 { close_inner(sock as RawSocket)?; } Ok(()) }
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (3)
Lib/test/test_selectors.pyis excluded by!Lib/**Lib/test/test_socketserver.pyis excluded by!Lib/**Lib/test/test_zipimport.pyis excluded by!Lib/**
📒 Files selected for processing (2)
crates/stdlib/src/socket.rs(2 hunks)crates/vm/src/stdlib/nt.rs(3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.rs: Follow the default rustfmt code style by runningcargo fmtto format Rust code
Always run clippy to lint Rust code (cargo clippy) before completing tasks and fix any warnings or lints introduced by changes
Follow Rust best practices for error handling and memory management
Use the macro system (pyclass,pymodule,pyfunction, etc.) when implementing Python functionality in Rust
Files:
crates/vm/src/stdlib/nt.rscrates/stdlib/src/socket.rs
🧬 Code graph analysis (1)
crates/vm/src/stdlib/nt.rs (1)
crates/wtf8/src/lib.rs (1)
from_wide(336-352)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: Run rust tests (windows-latest)
- GitHub Check: Run rust tests (macos-latest)
- GitHub Check: Run snippets and cpython tests on wasm-wasi
- GitHub Check: Check the WASM package and demo
- GitHub Check: Run snippets and cpython tests (windows-latest)
- GitHub Check: Run rust tests (ubuntu-latest)
- GitHub Check: Check Rust code with clippy
- GitHub Check: Run snippets and cpython tests (macos-latest)
- GitHub Check: Run snippets and cpython tests (ubuntu-latest)
- GitHub Check: Ensure compilation on various targets
🔇 Additional comments (3)
crates/stdlib/src/socket.rs (2)
1068-1068: LGTM!The
repr_strformatting correctly useszelf.fileno()directly now thatfileno()returnsi64instead ofRawSocket.
1478-1483: Thefileno()method correctly returnsi64for consistency withdetach().The implementation properly handles closed sockets by returning
INVALID_SOCKET as i64(-1) and correctly casts valid socket file descriptors toi64. The existing caller in__repr__(line 1068) is compatible with thei64return type.crates/vm/src/stdlib/nt.rs (1)
1125-1131: The function design is correct; no caller updates are needed.This is a
#[pyfunction]exposed to Python, not an internal Rust API. The#[pyfunction]macro automatically converts types implementingToPyObject(includingWtf8Bufand tuples thereof) to Python objects. The return type(Wtf8Buf, Wtf8Buf)correctly produces a Python tuple of two strings without requiring manual conversion by callers—there are no Rust callers to update.The
_vmparameter is unused but follows the established pattern in the codebase (e.g.,re.rs,gc.rs,typing.rs,os.rs,imp.rs) where unused parameters are retained for API consistency.Likely an incorrect or invalid review comment.
Comment on lines +1472 to 1475
| fn detach(&self) -> i64 { | ||
| let sock = self.sock.write().take(); | ||
| sock.map_or(INVALID_SOCKET, into_sock_fileno) | ||
| sock.map_or(INVALID_SOCKET as i64, |s| into_sock_fileno(s) as i64) | ||
| } |
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
rg -n --type rust '\.detach\s*\(' -B 3 -A 3Repository: RustPython/RustPython
Length of output: 508
🏁 Script executed:
rg -n 'fn detach' crates/stdlib/src/socket.rs -B 2 -A 5Repository: RustPython/RustPython
Length of output: 335
🏁 Script executed:
rg -n 'into_sock_fileno|close_inner' crates/stdlib/src/socket.rs -B 2 -A 5Repository: RustPython/RustPython
Length of output: 1943
🏁 Script executed:
rg -n 'fn fileno' crates/stdlib/src/socket.rs -B 2 -A 5Repository: RustPython/RustPython
Length of output: 315
🏁 Script executed:
rg -n 'INVALID_SOCKET|cfg.*windows' crates/stdlib/src/socket.rs | head -40
Repository: RustPython/RustPython
Length of output: 1563
🏁 Script executed:
sed -n '2374,2385p' crates/stdlib/src/socket.rsRepository: RustPython/RustPython
Length of output: 333
🏁 Script executed:
rg -n 'RawSocket' crates/stdlib/src/socket.rs | grep -E 'type|cfg' | head -20
Repository: RustPython/RustPython
Length of output: 171
🏁 Script executed:
# Check if there are any comments or TODOs about Windows socket limitations rg -n 'TODO|FIXME|BUG|XXX|HACK' crates/stdlib/src/socket.rs | grep -i 'socket\|window\|handle\|fd'
Repository: RustPython/RustPython
Length of output: 47
Verify the return type change impact across the codebase.
The detach() method now returns i64 instead of RawSocket. This is a breaking API change affecting:
- The
close()method (line 1463), which has been properly updated to handlei64and cast back toRawSocketforclose_inner() - Python code calling
detach(), which receivesi64(Python'sintsafely represents this range)
On Windows, casting RawSocket (which is usize) to i64 can theoretically overflow if a socket handle exceeds i64::MAX. This same issue also affects the fileno() method (line 1482), suggesting it may be an accepted limitation of the current design. Consider documenting whether this is a known limitation or requires a fix.
This was referenced