Skip to content

Implement _stat module #5847

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 27, 2025
Merged

Implement _stat module #5847

merged 5 commits into from
Jun 27, 2025

Conversation

moreal
Copy link
Contributor

@moreal moreal commented Jun 27, 2025

Summary by CodeRabbit

  • New Features

    • Introduced a new module providing file status constants and functions, similar to those found in POSIX and Windows systems.
    • Added support for file type and permission constants, as well as utility functions for interpreting file modes and generating Unix-style permission strings.
  • Tests

    • Removed legacy test cases that were previously marked as expected failures for file status features.
  • Chores

    • Updated spelling configuration to recognize "FIRMLINK" as a valid word.

Copy link

coderabbitai bot commented Jun 27, 2025

Walkthrough

A new stat module has been added to the standard library, providing file status constants and functions for platform compatibility. The module is registered in the virtual machine. Related test overrides marked as expected failures have been removed, and "FIRMLINK" was added to the spelling whitelist.

Changes

File(s) Change Summary
.cspell.json Added "FIRMLINK" to the spelling whitelist.
Lib/test/test_stat.py Removed several @expectedFailure test overrides from TestFilemodeCStat; retained conditional expected failure for test_link on Windows only.
vm/src/stdlib/mod.rs Registered and imported the new stat module in the standard library initialization.
vm/src/stdlib/stat.rs Added new stat module with file type constants, permission bits, utility functions, and exports.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant VM
    participant stat_module

    User->>VM: import _stat
    VM->>stat_module: initialize via make_module
    stat_module-->>VM: module instance with constants/functions
    User->>stat_module: call filemode(mode)
    stat_module-->>User: return permission string
Loading

Poem

A stately new module hops in with glee,
With file bits and flags for all to see.
Old failing tests now hop away,
While "FIRMLINK" is spelled the rabbit way.
A whisker-twitch for Unix and Win,
Let the stat adventures now begin!
🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cca7e8a and 9a7507f.

📒 Files selected for processing (4)
  • .cspell.json (1 hunks)
  • Lib/test/test_stat.py (1 hunks)
  • vm/src/stdlib/mod.rs (2 hunks)
  • vm/src/stdlib/stat.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • vm/src/stdlib/mod.rs
  • Lib/test/test_stat.py
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: moreal
PR: RustPython/RustPython#5847
File: vm/src/stdlib/stat.rs:547-567
Timestamp: 2025-06-27T14:47:28.770Z
Learning: In RustPython's stat module implementation, platform-specific constants like SF_SUPPORTED and SF_SYNTHETIC should be conditionally declared only for the platforms where they're available (e.g., macOS), following CPython's approach of optional declaration rather than providing fallback values for other platforms.
Learnt from: moreal
PR: RustPython/RustPython#5847
File: vm/src/stdlib/stat.rs:547-567
Timestamp: 2025-06-27T14:47:28.770Z
Learning: In RustPython's stat module implementation, platform-specific constants like SF_SUPPORTED and SF_SYNTHETIC should be conditionally declared only for the platforms where they're available (e.g., macOS), following CPython's approach of optional declaration using #ifdef checks rather than providing fallback values for other platforms.
vm/src/stdlib/stat.rs (10)
Learnt from: moreal
PR: RustPython/RustPython#5847
File: vm/src/stdlib/stat.rs:547-567
Timestamp: 2025-06-27T14:47:28.770Z
Learning: In RustPython's stat module implementation, platform-specific constants like SF_SUPPORTED and SF_SYNTHETIC should be conditionally declared only for the platforms where they're available (e.g., macOS), following CPython's approach of optional declaration rather than providing fallback values for other platforms.
Learnt from: moreal
PR: RustPython/RustPython#5847
File: vm/src/stdlib/stat.rs:547-567
Timestamp: 2025-06-27T14:47:28.770Z
Learning: In RustPython's stat module implementation, platform-specific constants like SF_SUPPORTED and SF_SYNTHETIC should be conditionally declared only for the platforms where they're available (e.g., macOS), following CPython's approach of optional declaration using #ifdef checks rather than providing fallback values for other platforms.
Learnt from: CR
PR: RustPython/RustPython#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-06-26T12:52:11.109Z
Learning: To add a Python module to the RustPython interpreter, use 'vm.add_native_module' with the module name and module factory.
Learnt from: CR
PR: RustPython/RustPython#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-06-26T12:52:11.109Z
Learning: When implementing a Python module in Rust for RustPython, use the #[pymodule] attribute and expose functions and classes using #[pyfunction], #[pyclass], and #[pymethod] as appropriate.
Learnt from: CR
PR: RustPython/RustPython#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-06-26T12:52:11.109Z
Learning: Minimize modifications to CPython standard library files in the Lib/ directory; bug fixes should be made through Rust code modifications whenever possible.
Learnt from: CR
PR: RustPython/RustPython#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-06-26T12:52:11.109Z
Learning: When comparing behavior with CPython, use the 'python' command explicitly for CPython and 'cargo run --' for RustPython to avoid confusion.
Learnt from: CR
PR: RustPython/RustPython#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-06-26T12:52:11.109Z
Learning: To find unimplemented methods and contribution opportunities, run './whats_left.py' in the RustPython repository.
Learnt from: CR
PR: RustPython/RustPython#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-06-26T12:52:11.109Z
Learning: Follow Rust best practices for error handling and memory management in all RustPython Rust code.
Learnt from: CR
PR: RustPython/RustPython#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-06-26T12:52:11.109Z
Learning: When testing Python code for RustPython, always use the RustPython interpreter (via 'cargo run -- script.py') instead of the standard 'python' command.
Learnt from: CR
PR: RustPython/RustPython#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-06-26T12:52:11.109Z
Learning: Use the macro system (such as 'pyclass', 'pymodule', 'pyfunction') when implementing Python functionality in Rust for RustPython.
🪛 Biome (1.9.4)
.cspell.json

[error] 137-137: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

⏰ Context from checks skipped due to timeout of 90000ms (10)
  • GitHub Check: Check Rust code with rustfmt and clippy
  • GitHub Check: Run snippets and cpython tests (ubuntu-latest)
  • GitHub Check: Check the WASM package and demo
  • GitHub Check: Run snippets and cpython tests (windows-latest)
  • GitHub Check: Run snippets and cpython tests (macos-latest)
  • GitHub Check: Run rust tests (windows-latest)
  • GitHub Check: Run snippets and cpython tests on wasm-wasi
  • GitHub Check: Run rust tests (ubuntu-latest)
  • GitHub Check: Run rust tests (macos-latest)
  • GitHub Check: Ensure compilation on various targets
🔇 Additional comments (5)
vm/src/stdlib/stat.rs (3)

1-571: Excellent implementation of the stat module following RustPython conventions.

This is a comprehensive implementation of the _stat module that closely follows CPython's behavior with proper platform-specific handling. The code structure, use of conditional compilation, and RustPython-specific attributes (#[pymodule], #[pyfunction], #[pyattr]) are all correctly implemented.

Key strengths:

  • Proper platform-specific type definitions and constants
  • Correct implementation of file type test functions
  • Well-structured filemode string generation
  • Appropriate handling of unsupported platforms (Solaris/BSD) with stubs
  • Follows learned best practices for optional declaration of platform-specific constants

553-566: Platform-specific constants correctly follow CPython's optional declaration approach.

The implementation correctly declares SF_SUPPORTED and SF_SYNTHETIC only for macOS, following CPython's approach of optional declaration rather than providing fallback values for other platforms. This aligns with the established learnings and matches CPython's #ifdef pattern.


65-76: TODO comments appropriately document missing platform support.

The placeholder constants and stub functions for Solaris (S_IFDOOR, S_IFPORT) and BSD (S_IFWHT) are appropriately handled with clear TODO comments. This follows a reasonable incremental implementation approach.

.cspell.json (2)

136-137: Addition of "FIRMLINK" to spell check dictionary is correct.

The addition of "FIRMLINK" to the words list properly supports the new SF_FIRMLINK constant introduced in the stat module. The JSON syntax appears correct with no trailing comma after the last array element.


137-137: Verify JSON syntax if static analysis error persists.

The static analysis tool reports a JSON parse error, but the current code appears syntactically correct with no trailing comma. This may be a false positive from the tool.

#!/bin/bash
# Verify JSON syntax is valid
python -m json.tool .cspell.json > /dev/null && echo "JSON is valid" || echo "JSON syntax error detected"
✨ 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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@moreal moreal force-pushed the impl-stat branch 8 times, most recently from 651f5f8 to 6fc099a Compare June 27, 2025 12:39
@moreal moreal changed the title Implement stat module base Implement _stat module Jun 27, 2025
@moreal moreal force-pushed the impl-stat branch 9 times, most recently from 85e1e01 to 08110ff Compare June 27, 2025 14:38
@moreal moreal marked this pull request as ready for review June 27, 2025 14:38
Copy link

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

🧹 Nitpick comments (1)
vm/src/stdlib/stat.rs (1)

310-321: Consider using const values directly instead of functions for constants.

The S_IMODE_method and S_IFMT_method functions use local const values that differ from the module-level constants. This could lead to confusion.

     const S_IFMT: Mode = 0o170000;
-    const S_IMODE: Mode = 0o7777;
+    const S_IMODE_MASK: Mode = 0o7777;
     
     #[pyfunction(name = "S_IMODE")]
     #[allow(non_snake_case)]
     fn S_IMODE_method(mode: Mode) -> Mode {
-        mode & S_IMODE
+        mode & S_IMODE_MASK
     }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b9b1c85 and cca7e8a.

📒 Files selected for processing (4)
  • .cspell.json (1 hunks)
  • Lib/test/test_stat.py (0 hunks)
  • vm/src/stdlib/mod.rs (2 hunks)
  • vm/src/stdlib/stat.rs (1 hunks)
💤 Files with no reviewable changes (1)
  • Lib/test/test_stat.py
🧰 Additional context used
🧠 Learnings (1)
vm/src/stdlib/stat.rs (3)
Learnt from: CR
PR: RustPython/RustPython#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-06-26T12:52:11.109Z
Learning: To add a Python module to the RustPython interpreter, use 'vm.add_native_module' with the module name and module factory.
Learnt from: CR
PR: RustPython/RustPython#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-06-26T12:52:11.109Z
Learning: When implementing a Python module in Rust for RustPython, use the #[pymodule] attribute and expose functions and classes using #[pyfunction], #[pyclass], and #[pymethod] as appropriate.
Learnt from: CR
PR: RustPython/RustPython#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-06-26T12:52:11.109Z
Learning: Use the macro system (such as 'pyclass', 'pymodule', 'pyfunction') when implementing Python functionality in Rust for RustPython.
🧬 Code Graph Analysis (1)
vm/src/stdlib/mod.rs (2)
vm/src/stdlib/os.rs (2)
  • stat (508-540)
  • stat (886-896)
vm/src/stdlib/stat.rs (1)
  • make_module (569-571)
🪛 Biome (1.9.4)
.cspell.json

[error] 137-137: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

⏰ Context from checks skipped due to timeout of 90000ms (9)
  • GitHub Check: Run snippets and cpython tests (windows-latest)
  • GitHub Check: Check the WASM package and demo
  • GitHub Check: Check Rust code with rustfmt and clippy
  • GitHub Check: Run snippets and cpython tests (ubuntu-latest)
  • GitHub Check: Run snippets and cpython tests (macos-latest)
  • GitHub Check: Run rust tests (windows-latest)
  • GitHub Check: Run rust tests (macos-latest)
  • GitHub Check: Run rust tests (ubuntu-latest)
  • GitHub Check: Ensure compilation on various targets
🔇 Additional comments (6)
vm/src/stdlib/mod.rs (2)

17-17: LGTM! Module declaration follows the established pattern.

The stat module is properly declared following the same pattern as other standard library modules.


93-93: LGTM! Module registration follows the established pattern.

The stat module is correctly registered in the module initialization map with the appropriate "_stat" name, matching Python's convention.

vm/src/stdlib/stat.rs (4)

1-14: LGTM! Module setup and type definitions are well-structured.

The platform-specific type definitions for Mode correctly handle Unix (using libc::mode_t), Windows (u16), and fallback cases (u32). The conditional compilation attributes are appropriate.


135-154: Android-specific handling looks correct.

The conditional compilation for S_IWRITE and S_IEXEC on Android is appropriate since these constants may not be available in Android's libc.


569-571: LGTM! Module creation function is implemented correctly.

The make_module function follows the established pattern for creating Python modules in RustPython.


93-98: Verify that S_ENFMT should use the same value as S_ISGID.

The S_ENFMT constant is defined as libc::S_ISGID on Unix and 0o2000 on non-Unix, which matches S_ISGID. Please confirm this is intentionally the same value.

#!/bin/bash
# Description: Verify S_ENFMT definition in system headers and CPython
# Expected: S_ENFMT should be the same as S_ISGID on most systems

# Check system headers for S_ENFMT definition
rg -A 2 -B 2 "S_ENFMT" /usr/include/ 2>/dev/null || echo "S_ENFMT not found in system headers"

# Search for S_ENFMT in the CPython source to understand the expected behavior
echo "Checking CPython's stat module implementation..."

Copy link
Member

@youknowone youknowone left a comment

Choose a reason for hiding this comment

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

Thank you! And welcome back!

@youknowone youknowone merged commit 910077d into RustPython:main Jun 27, 2025
12 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