Skip to content

Conversation

@youknowone
Copy link
Member

@youknowone youknowone commented Dec 20, 2025

Summary by CodeRabbit

  • New Features

    • Added a comprehensive runtime path configuration that detects virtualenvs and build layouts to derive executable, prefixes, and module search paths.
  • Improvements

    • sys.* attributes (executable, prefixes, path, flags, options, argv) now reflect a centralized runtime configuration for consistent behavior.
    • VM initialization and runtime settings (optimize, UTF‑8, signal handling, safe path) read from the consolidated config; stdlib paths are prepended to module search paths.
  • Other

    • Minor dictionary update (spellings).

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 20, 2025

Walkthrough

Adds a Paths struct and PyConfig combining Settings+Paths; introduces a new getpath module to compute runtime paths; changes VM construction and many modules to read configuration from vm.state.config.settings and vm.state.config.paths instead of vm.state.settings.

Changes

Cohort / File(s) Summary
Configuration Types
crates/vm/src/vm/setting.rs
Adds Paths struct and PyConfig struct with pub fn new(settings: Settings, paths: Paths) -> Self.
Path Computation Module
crates/vm/src/getpath.rs, crates/vm/src/lib.rs
New getpath module with init_path_config(settings: &Settings) -> Paths; implements venv/build-dir detection, landmark searches, and module_search_paths; exported via lib.rs.
VM Core & Initialization
crates/vm/src/vm/mod.rs, crates/vm/src/vm/interpreter.rs, crates/vm/src/vm/compile.rs
VM now constructed with PyConfig instead of Settings; PyGlobalState stores config: PyConfig; reads moved to config.settings.* / config.paths.*; run_script reads safe_path from config.
Interpreter startup integration
src/interpreter.rs, crates/vm/src/vm/interpreter.rs
Interpreter init computes Paths via getpath::init_path_config(&settings) and builds PyConfig; startup path insertion now updates config.paths.module_search_paths (stdlib precedence preserved).
stdlib: settings access updates
crates/vm/src/stdlib/*.rs (builtins.rs, imp.rs, io.rs, signal.rs, syslog.rs)
Multiple modules switched reads from vm.state.settings.* to vm.state.config.settings.* (optimize, check_hash_pycs_mode, utf8_mode, install_signal_handlers, argv, verbose).
sys module refactor
crates/vm/src/stdlib/sys.rs
Replaced inlined env/venv logic with config-based lookups; many functions now return String and pull values from vm.state.config.paths and vm.state.config.settings; flags built from FlagsData::from_settings(&vm.state.config.settings).
Root library changes
src/lib.rs
Replaced vm.state.settings.* reads with vm.state.config.settings.*; adjusted embedded sys.path insertion filename; profile writing uses vm.state.as_ref().config.settings.
Small / Data
.cspell.dict/cpython.txt
Adds new dictionary entry platstdlib.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant CLI as CLI / Launcher
participant Settings as Settings
participant getpath as getpath::init_path_config
participant PyConfig as PyConfig (Settings + Paths)
participant VM as VirtualMachine::new
participant Stdlib as stdlib modules

CLI->>Settings: parse runtime options (argv, env)
Settings->>getpath: pass Settings
getpath-->>getpath: resolve executable, detect venv/build dir, compute prefixes & module_search_paths
getpath-->>PyConfig: return Paths
Settings->>PyConfig: PyConfig::new(settings, paths)
PyConfig->>VM: VirtualMachine::new(config, ctx)
VM->>Stdlib: modules read config via vm.state.config.settings / vm.state.config.paths
Stdlib-->>VM: return values (argv, path, prefixes, flags)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Focus review on crates/vm/src/getpath.rs (cross-platform path/venv/build detection and tests).
  • Verify call sites for changed return types in crates/vm/src/stdlib/sys.rs and adjust consumers.
  • Ensure all VM constructors and tests were updated to accept PyConfig (crates/vm/src/vm/mod.rs, interpreter entry points, integration tests).
  • Check for leftover direct uses of vm.state.settings where vm.state.config should be used.

Suggested reviewers

  • ShaharNaveh
  • arihant2math
  • coolreader18

Poem

🐰
I hopped through paths both short and long,
I hummed a venv-detecting song.
PyConfig stitched each route so neat,
Now modules find their home to greet. 🥕

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Introduce PyConfig to implement Paths correctly' accurately describes the main change: introducing a new PyConfig struct and Paths struct to consolidate configuration, along with refactoring across the codebase to use this new configuration approach.
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.

❤️ Share

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

@youknowone youknowone force-pushed the getpath branch 2 times, most recently from d2c4418 to 82e213e Compare December 20, 2025 13:11
@github-actions
Copy link
Contributor

Code has been automatically formatted

The code in this PR has been formatted using cargo fmt --all.
Please pull the latest changes before pushing again:

git pull origin getpath

@youknowone youknowone force-pushed the getpath branch 2 times, most recently from 77307f5 to 561304d Compare December 20, 2025 14:06
@youknowone youknowone marked this pull request as ready for review December 20, 2025 14:29
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib.rs (1)

235-247: flame-it profiling still references removed settings field

PyGlobalState now stores config: PyConfig, so vm.state.as_ref().settings no longer exists. Under feature = "flame-it" this will fail to compile.

Update the call to pull Settings from config:

Proposed fix
-        if let Err(e) = write_profile(&vm.state.as_ref().settings) {
+        if let Err(e) = write_profile(&vm.state.as_ref().config.settings) {
             error!("Error writing profile information: {}", e);
         }
🧹 Nitpick comments (3)
src/interpreter.rs (2)

50-55: Redundant init_path_config call before Interpreter::with_init

Here you call rustpython_vm::getpath::init_path_config(&settings) and ignore the result, while rustpython_vm::Interpreter::with_init now also computes paths and wraps them in PyConfig.

Unless you intend side effects inside init_path_config (it appears pure), this call is redundant work on every startup and can be removed.

Proposed simplification
-        let settings = self.settings.unwrap_or_default();
-
-        // Initialize path configuration before interpreter creation (like getpath.py)
-        rustpython_vm::getpath::init_path_config(&settings);
-
-        Interpreter::with_init(settings, |vm| {
+        let settings = self.settings.unwrap_or_default();
+        Interpreter::with_init(settings, |vm| {
             for hook in self.init_hooks {
                 hook(vm);
             }
         })

112-131: Stdlib path injection into both path_list and module_search_paths looks sound

Collecting additional_paths from BUILDTIME_RUSTPYTHONPATH (or rustpython_pylib::LIB_PATH) and then prepending them to both state.config.settings.path_list and state.config.paths.module_search_paths ensures:

  • legacy Settings::path_list consumers still see the stdlib paths, and
  • sys.path (driven by module_search_paths) has stdlib ahead of user paths.

This matches the intent of the new Paths model and aligns CLI behavior with the VM config. You might later consider de‑duplicating paths if getpath ends up inserting the same entries, but functionally this is correct.

crates/vm/src/getpath.rs (1)

376-381: Use platform-agnostic path for test portability.

The hardcoded /tmp path won't exist on Windows. Consider using std::env::temp_dir() or a cross-platform approach.

🔎 Suggested fix
     #[test]
     fn test_search_up() {
         // Test with a path that doesn't have any landmarks
-        let result = search_up_file("/tmp", &["nonexistent_landmark_xyz"]);
+        let result = search_up_file(std::env::temp_dir(), &["nonexistent_landmark_xyz"]);
         assert!(result.is_none());
     }
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6660170 and 561304d.

📒 Files selected for processing (16)
  • .cspell.dict/cpython.txt (1 hunks)
  • crates/stdlib/src/syslog.rs (1 hunks)
  • crates/vm/src/getpath.rs (1 hunks)
  • crates/vm/src/import.rs (1 hunks)
  • crates/vm/src/lib.rs (1 hunks)
  • crates/vm/src/stdlib/builtins.rs (2 hunks)
  • crates/vm/src/stdlib/imp.rs (1 hunks)
  • crates/vm/src/stdlib/io.rs (1 hunks)
  • crates/vm/src/stdlib/signal.rs (1 hunks)
  • crates/vm/src/stdlib/sys.rs (7 hunks)
  • crates/vm/src/vm/compile.rs (1 hunks)
  • crates/vm/src/vm/interpreter.rs (2 hunks)
  • crates/vm/src/vm/mod.rs (11 hunks)
  • crates/vm/src/vm/setting.rs (1 hunks)
  • src/interpreter.rs (2 hunks)
  • src/lib.rs (4 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.rs: Follow the default rustfmt code style by running cargo fmt to 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/stdlib/src/syslog.rs
  • crates/vm/src/vm/setting.rs
  • src/lib.rs
  • crates/vm/src/lib.rs
  • crates/vm/src/stdlib/imp.rs
  • crates/vm/src/import.rs
  • src/interpreter.rs
  • crates/vm/src/getpath.rs
  • crates/vm/src/stdlib/builtins.rs
  • crates/vm/src/vm/compile.rs
  • crates/vm/src/stdlib/io.rs
  • crates/vm/src/vm/mod.rs
  • crates/vm/src/stdlib/signal.rs
  • crates/vm/src/vm/interpreter.rs
  • crates/vm/src/stdlib/sys.rs
🧠 Learnings (1)
📚 Learning: 2025-12-09T08:46:58.660Z
Learnt from: youknowone
Repo: RustPython/RustPython PR: 6358
File: crates/vm/src/exception_group.rs:173-185
Timestamp: 2025-12-09T08:46:58.660Z
Learning: In crates/vm/src/exception_group.rs, the derive() method intentionally always creates a BaseExceptionGroup instance rather than preserving the original exception class type. This is a deliberate design decision that differs from CPython's behavior.

Applied to files:

  • crates/vm/src/stdlib/builtins.rs
🧬 Code graph analysis (4)
crates/stdlib/src/syslog.rs (1)
crates/vm/src/stdlib/sys.rs (1)
  • argv (121-129)
crates/vm/src/vm/setting.rs (1)
crates/vm/src/vm/mod.rs (1)
  • new (117-220)
crates/vm/src/vm/mod.rs (1)
crates/vm/src/vm/setting.rs (1)
  • new (32-34)
crates/vm/src/vm/interpreter.rs (4)
crates/vm/src/getpath.rs (1)
  • init_path_config (108-171)
src/interpreter.rs (2)
  • settings (63-66)
  • new (47-49)
crates/vm/src/vm/mod.rs (1)
  • new (117-220)
crates/vm/src/vm/setting.rs (1)
  • new (32-34)
⏰ 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). (1)
  • GitHub Check: Run snippets and cpython tests (windows-latest)
🔇 Additional comments (34)
.cspell.dict/cpython.txt (1)

45-45: Correct dictionary maintenance for new terminology.

The new entry platstdlib is correctly inserted in alphabetical order between patma and posonlyarg. This addition supports the new path configuration terminology introduced by the PyConfig refactor.

crates/stdlib/src/syslog.rs (1)

29-29: LGTM! Configuration access path updated correctly.

The migration from vm.state.settings.argv to vm.state.config.settings.argv is consistent with the broader refactoring to use PyConfig-based configuration.

crates/vm/src/stdlib/imp.rs (1)

94-94: LGTM! Configuration access updated correctly.

The change from vm.state.settings.check_hash_pycs_mode to vm.state.config.settings.check_hash_pycs_mode aligns with the PyConfig-based configuration model.

crates/vm/src/vm/setting.rs (1)

4-21: LGTM! Well-structured path configuration.

The Paths struct provides a clean separation between user-configurable settings and computed runtime paths, with clear documentation for each field mapping to Python's sys module attributes.

crates/vm/src/vm/compile.rs (1)

41-41: LGTM! Configuration access path updated correctly.

The migration from vm.state.settings.safe_path to vm.state.config.settings.safe_path is consistent with the PyConfig-based configuration model.

crates/vm/src/lib.rs (1)

63-63: LGTM! Public getpath module added.

Adding the getpath module to the public API surface is necessary to expose path configuration functionality for VM initialization, aligning with the PR's objective to implement Python-like path configuration.

crates/vm/src/import.rs (1)

209-209: LGTM! Configuration access path updated correctly.

The migration from vm.state.settings.verbose to vm.state.config.settings.verbose is consistent with the broader PyConfig-based refactoring.

crates/vm/src/stdlib/signal.rs (1)

117-117: LGTM! Configuration access path updated correctly.

The migration from vm.state.settings.install_signal_handlers to vm.state.config.settings.install_signal_handlers is consistent with the PyConfig-based configuration model.

crates/vm/src/stdlib/builtins.rs (2)

135-135: LGTM! Configuration access path updated correctly.

The migration from vm.state.settings.optimize to vm.state.config.settings.optimize is consistent with the PyConfig-based configuration model. The logic correctly defaults to the configured optimization level when the compile() function's optimize parameter is -1.


1083-1083: LGTM! Configuration access path updated correctly.

The migration from vm.state.settings.optimize to vm.state.config.settings.optimize is consistent with the PyConfig-based configuration model. The debug mode derivation logic remains unchanged.

src/lib.rs (2)

172-180: Config-based safe-path check looks correct

Using vm.state.config.settings.safe_path instead of the old vm.state.settings.safe_path keeps behavior the same while aligning with the new PyConfig layout. No issues here.


192-203: Faulthandler flag and banner gating correctly migrated to config.settings

Switching to vm.state.config.settings.faulthandler, quiet, and verbose preserves semantics and matches the new configuration model. The REPL banner conditions remain unchanged logically.

crates/vm/src/stdlib/io.rs (1)

2397-2412: UTF-8 mode lookup correctly switched to config.settings

Using vm.state.config.settings.utf8_mode in the encoding selection preserves previous behavior and is consistent with the new PyConfig layout. No further changes needed here.

crates/vm/src/vm/interpreter.rs (1)

46-58: Config + path initialization in Interpreter::with_init is well-structured

Creating paths = getpath::init_path_config(&settings) and then PyConfig::new(settings, paths) before calling VirtualMachine::new(config, ctx) cleanly encapsulates all runtime configuration into PyConfig while keeping the public API as Settings.

This is the right place to centralize path configuration for both without_stdlib and stdlib-enabled interpreters.

crates/vm/src/vm/mod.rs (6)

53-106: Global state now correctly wraps settings in PyConfig

Re‑exporting Paths and PyConfig, and changing PyGlobalState to hold config: PyConfig, is consistent with the new configuration model. This keeps all VM settings and derived paths together while preserving access to other global fields.


115-190: VirtualMachine::new correctly adapted to PyConfig

Using config.settings.hash_seed and config.settings.int_max_str_digits to derive the hash secret and digit limit matches previous behavior, and storing the whole config into PyGlobalState ensures later code can access both raw settings and paths via self.state.config. No structural or initialization issues spotted.


230-259: Encoding import diagnostics now reference config.settings.path_list

Switching path_contains_env to iterate over self.state.config.settings.path_list keeps the guidance messages accurate under the new config structure; callers still configure search paths via Settings::path_list, just accessed through config.


303-359: Stdio initialization using config.settings.buffered_stdio looks correct

Reading buffered_stdio from self.state.config.settings inside make_stdio maintains the previous buffered/unbuffered behavior and centralizes the flag in the new config. The rest of the logic (choosing buffering mode, line buffering, and wrapping in TextIOWrapper) is unchanged.


367-395: External library and stdlib presence checks correctly migrated

  • The allow_external_library gate now uses self.state.config.settings.allow_external_library, keeping semantics for importlib package initialization.
  • _expect_stdlib now checks !self.state.config.settings.path_list.is_empty(), which is consistent with the new config layout and still signals whether stdlib paths are configured.

Both changes are simple, accurate migrations.


506-509: Compile options now correctly read optimize from config.settings

compile_opts() using self.state.config.settings.optimize keeps behavior identical while routing through PyConfig. No issues here.

crates/vm/src/getpath.rs (7)

1-11: LGTM! Clear module documentation and appropriate imports.

The module structure follows Python's getpath.py reference with proper landmark-based search approach.


12-66: LGTM! Platform-specific landmarks correctly mirror CPython's getpath.py.

The Windows/POSIX split with appropriate directory structures (lib/pythonX.Y vs Lib, lib-dynload vs DLLs) aligns with standard Python installations.


68-100: LGTM! Well-designed upward search helpers with safe termination.

The loop correctly terminates when current.pop() returns false at the filesystem root, preventing infinite loops.


108-171: LGTM! Clear step-by-step implementation following CPython's getpath.py algorithm.

The function properly handles venv detection, build directory detection, and prefix calculation with clear documentation for each step.


186-215: LGTM!

The function correctly checks both standard venv layouts (../pyvenv.cfg and ./pyvenv.cfg). The _executable parameter is appropriately prefixed to indicate intentional non-use.


235-259: LGTM! Correct priority order for prefix calculation.

The search order (build directory → ZIP landmark → stdlib landmarks → default) follows CPython's getpath.py behavior.


300-333: LGTM! Path construction matches CPython behavior.

Adding the ZIP path regardless of existence is correct—CPython's sys.path also includes computed paths without validating their existence.

crates/vm/src/stdlib/sys.rs (7)

97-112: LGTM! Prefix accessors correctly migrated to config.paths.

The return type change from &'static str to String is appropriate since these values are now computed at runtime rather than being compile-time constants.


120-129: LGTM!

Correctly accesses argv from config.settings as it's a user-provided setting.


159-172: LGTM! Executable paths correctly sourced from config.paths.

Both _base_executable and executable properly read from the computed paths rather than re-computing them.


208-217: LGTM!

sys.path correctly reads from config.paths.module_search_paths, which is computed by init_path_config.


246-269: LGTM!

Both _xoptions and warnoptions correctly access their data from config.settings.


406-409: LGTM!

Flags correctly derived from config.settings via FlagsData::from_settings.


164-167: LGTM!

Correctly accesses write_bytecode from config.settings.

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: 0

🧹 Nitpick comments (2)
crates/vm/src/vm/setting.rs (1)

23-35: Consider deriving Debug and Clone for PyConfig.

Paths derives Debug, Clone, Default, but PyConfig has no derives. For debugging and potential cloning needs (e.g., spawning sub-interpreters or diagnostics), consider adding:

+#[derive(Debug, Clone)]
 pub struct PyConfig {
     pub settings: Settings,
     pub paths: Paths,
 }

Note: Settings would also need Debug and Clone derives for this to work. If Settings can't easily derive these due to conditional fields, this can be deferred.

crates/vm/src/getpath.rs (1)

350-362: Silent failure on pyvenv.cfg read errors.

parse_pyvenv_home uses .ok()? which silently ignores file read errors. While this is acceptable for optional venv detection, consider logging at verbose/debug level when running with -v for better diagnostics.

This is a minor enhancement that could be deferred.

📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 561304d and 4d125b9.

📒 Files selected for processing (15)
  • .cspell.dict/cpython.txt (1 hunks)
  • crates/stdlib/src/syslog.rs (1 hunks)
  • crates/vm/src/getpath.rs (1 hunks)
  • crates/vm/src/import.rs (1 hunks)
  • crates/vm/src/stdlib/builtins.rs (2 hunks)
  • crates/vm/src/stdlib/imp.rs (1 hunks)
  • crates/vm/src/stdlib/io.rs (1 hunks)
  • crates/vm/src/stdlib/signal.rs (1 hunks)
  • crates/vm/src/stdlib/sys.rs (7 hunks)
  • crates/vm/src/vm/compile.rs (1 hunks)
  • crates/vm/src/vm/interpreter.rs (2 hunks)
  • crates/vm/src/vm/mod.rs (11 hunks)
  • crates/vm/src/vm/setting.rs (1 hunks)
  • src/interpreter.rs (1 hunks)
  • src/lib.rs (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (9)
  • crates/vm/src/stdlib/io.rs
  • crates/vm/src/vm/compile.rs
  • src/lib.rs
  • crates/vm/src/import.rs
  • crates/vm/src/stdlib/signal.rs
  • crates/vm/src/stdlib/imp.rs
  • src/interpreter.rs
  • crates/stdlib/src/syslog.rs
  • .cspell.dict/cpython.txt
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.rs: Follow the default rustfmt code style by running cargo fmt to 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/builtins.rs
  • crates/vm/src/vm/interpreter.rs
  • crates/vm/src/vm/setting.rs
  • crates/vm/src/vm/mod.rs
  • crates/vm/src/getpath.rs
  • crates/vm/src/stdlib/sys.rs
🧠 Learnings (1)
📚 Learning: 2025-12-09T08:46:58.660Z
Learnt from: youknowone
Repo: RustPython/RustPython PR: 6358
File: crates/vm/src/exception_group.rs:173-185
Timestamp: 2025-12-09T08:46:58.660Z
Learning: In crates/vm/src/exception_group.rs, the derive() method intentionally always creates a BaseExceptionGroup instance rather than preserving the original exception class type. This is a deliberate design decision that differs from CPython's behavior.

Applied to files:

  • crates/vm/src/stdlib/builtins.rs
🧬 Code graph analysis (4)
crates/vm/src/vm/interpreter.rs (4)
crates/vm/src/getpath.rs (1)
  • init_path_config (108-171)
src/interpreter.rs (2)
  • settings (59-62)
  • new (47-49)
crates/vm/src/vm/setting.rs (1)
  • new (32-34)
crates/vm/src/vm/mod.rs (1)
  • new (117-220)
crates/vm/src/vm/setting.rs (1)
crates/vm/src/vm/mod.rs (1)
  • new (117-220)
crates/vm/src/vm/mod.rs (1)
crates/vm/src/vm/setting.rs (1)
  • new (32-34)
crates/vm/src/getpath.rs (2)
crates/vm/src/stdlib/sys.rs (8)
  • std (443-443)
  • std (584-584)
  • std (1069-1069)
  • std (1099-1099)
  • path (209-217)
  • executable (170-172)
  • prefix (98-100)
  • exec_prefix (106-108)
crates/vm/src/vm/setting.rs (1)
  • default (171-205)
⏰ 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). (11)
  • GitHub Check: Run snippets and cpython tests (windows-latest)
  • GitHub Check: Run snippets and cpython tests (macos-latest)
  • GitHub Check: Run rust tests (macos-latest)
  • GitHub Check: Run tests under miri
  • GitHub Check: Run rust tests (windows-latest)
  • GitHub Check: Run rust tests (ubuntu-latest)
  • GitHub Check: Run snippets and cpython tests (ubuntu-latest)
  • GitHub Check: Ensure compilation on various targets
  • GitHub Check: Check Rust code with clippy
  • GitHub Check: Run snippets and cpython tests on wasm-wasi
  • GitHub Check: Check the WASM package and demo
🔇 Additional comments (21)
crates/vm/src/stdlib/builtins.rs (1)

135-135: LGTM!

The configuration access path updates from vm.state.settings.optimize to vm.state.config.settings.optimize are consistent with the broader PyConfig migration in this PR. The logic remains unchanged.

Also applies to: 1083-1083

crates/vm/src/vm/setting.rs (1)

4-21: Well-structured path configuration.

The Paths struct cleanly encapsulates all runtime path configuration fields that mirror CPython's PyConfig path outputs. The documentation comments for each field clearly indicate their purpose (e.g., sys.executable, sys.prefix).

crates/vm/src/vm/interpreter.rs (1)

50-57: Clean initialization flow for path configuration.

The initialization sequence properly separates concerns:

  1. Compute path configuration from settings
  2. Create PyConfig combining settings and paths
  3. Pass the unified config to VirtualMachine::new

This integrates well with the new getpath module and maintains a clear data flow.

crates/vm/src/vm/mod.rs (4)

53-53: Public exports correctly expanded.

Adding Paths and PyConfig to the public exports alongside existing CheckHashPycsMode and Settings properly exposes the new configuration types for downstream users.


89-90: State structure properly updated.

PyGlobalState now holds config: PyConfig instead of raw settings, centralizing configuration access through the new unified structure.


117-174: VM construction cleanly migrated to PyConfig.

The VirtualMachine::new signature change and internal initialization logic properly consume the new PyConfig structure. All config field accesses (hash_seed, int_max_str_digits) correctly use config.settings.*.


230-230: Consistent config access pattern throughout.

All internal usages have been systematically updated to use self.state.config.settings.* instead of self.state.settings.*, maintaining consistency across the codebase.

Also applies to: 306-306, 367-367, 378-378, 508-508

crates/vm/src/getpath.rs (5)

1-11: Well-documented module following CPython's getpath.py pattern.

The module documentation clearly explains the purpose and references the CPython equivalent. The landmark-based search approach mirrors Python's path calculation logic.


72-89: Robust upward search implementation.

The search_up function correctly handles the base case by checking current.pop() return value, preventing infinite loops when reaching the filesystem root.


108-171: Solid path configuration initialization.

The init_path_config function follows a logical flow:

  1. Get executable path
  2. Check environment variables
  3. Detect venv configuration
  4. Detect build directory
  5. Calculate prefix/base_prefix
  6. Calculate exec_prefix
  7. Calculate base_executable
  8. Build module search paths

The step-by-step comments align with the implementation, making the code maintainable.


364-388: Good test coverage for basic scenarios.

The tests verify non-panicking initialization, upward search behavior, and default prefix generation. Consider adding tests for venv detection and build directory detection in future iterations.


336-347: The which crate dependency is properly configured.

The which crate is listed in crates/vm/Cargo.toml as which = "8" under [target.'cfg(not(target_arch = "wasm32"))'.dependencies], which correctly aligns with the code's conditional compilation. The edge case handling via the ? operator is correct—env::args_os().next()? properly returns None if no arguments exist, and the function's return type Option<PathBuf> propagates this appropriately.

crates/vm/src/stdlib/sys.rs (9)

98-112: Systematic migration to vm.state.config.paths looks correct.

The prefix-related functions now correctly source their values from the centralized PyConfig.paths structure. The return type change from &'static str to String is consistent with the PR's objective to compute paths dynamically.


121-129: LGTM: argv correctly migrated to vm.state.config.settings.


160-162: LGTM: Simplified return type from PyObjectRef to String.


165-167: LGTM: dont_write_bytecode correctly migrated.


170-172: LGTM: Simplified return type from PyObjectRef to String.


209-217: LGTM: path correctly sources from vm.state.config.paths.module_search_paths.


247-258: LGTM: _xoptions correctly migrated to vm.state.config.settings.


261-269: LGTM: warnoptions correctly migrated to vm.state.config.settings.


407-409: LGTM: flags correctly constructs from vm.state.config.settings.

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: 0

🧹 Nitpick comments (1)
crates/vm/src/getpath.rs (1)

188-191: Consider removing unused parameter or documenting future use.

The _executable parameter is prefixed with underscore indicating intentional non-use, but it may be worth a brief comment explaining if this is for future compatibility with Python's behavior.

📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4d125b9 and 5bb549e.

📒 Files selected for processing (15)
  • .cspell.dict/cpython.txt (1 hunks)
  • crates/stdlib/src/syslog.rs (1 hunks)
  • crates/vm/src/getpath.rs (1 hunks)
  • crates/vm/src/import.rs (1 hunks)
  • crates/vm/src/stdlib/builtins.rs (2 hunks)
  • crates/vm/src/stdlib/imp.rs (1 hunks)
  • crates/vm/src/stdlib/io.rs (1 hunks)
  • crates/vm/src/stdlib/signal.rs (1 hunks)
  • crates/vm/src/stdlib/sys.rs (7 hunks)
  • crates/vm/src/vm/compile.rs (1 hunks)
  • crates/vm/src/vm/interpreter.rs (2 hunks)
  • crates/vm/src/vm/mod.rs (13 hunks)
  • crates/vm/src/vm/setting.rs (1 hunks)
  • src/interpreter.rs (1 hunks)
  • src/lib.rs (5 hunks)
✅ Files skipped from review due to trivial changes (1)
  • .cspell.dict/cpython.txt
🚧 Files skipped from review as they are similar to previous changes (6)
  • crates/vm/src/stdlib/signal.rs
  • crates/vm/src/stdlib/imp.rs
  • src/interpreter.rs
  • crates/stdlib/src/syslog.rs
  • crates/vm/src/vm/compile.rs
  • crates/vm/src/stdlib/io.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.rs: Follow the default rustfmt code style by running cargo fmt to 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/import.rs
  • crates/vm/src/stdlib/builtins.rs
  • crates/vm/src/vm/interpreter.rs
  • crates/vm/src/vm/setting.rs
  • crates/vm/src/getpath.rs
  • crates/vm/src/vm/mod.rs
  • crates/vm/src/stdlib/sys.rs
  • src/lib.rs
🧠 Learnings (1)
📚 Learning: 2025-12-09T08:46:58.660Z
Learnt from: youknowone
Repo: RustPython/RustPython PR: 6358
File: crates/vm/src/exception_group.rs:173-185
Timestamp: 2025-12-09T08:46:58.660Z
Learning: In crates/vm/src/exception_group.rs, the derive() method intentionally always creates a BaseExceptionGroup instance rather than preserving the original exception class type. This is a deliberate design decision that differs from CPython's behavior.

Applied to files:

  • crates/vm/src/stdlib/builtins.rs
🧬 Code graph analysis (3)
crates/vm/src/vm/interpreter.rs (3)
crates/vm/src/getpath.rs (1)
  • init_path_config (108-171)
crates/vm/src/vm/setting.rs (1)
  • new (32-34)
crates/vm/src/vm/mod.rs (1)
  • new (117-220)
crates/vm/src/vm/setting.rs (1)
crates/vm/src/vm/mod.rs (1)
  • new (117-220)
crates/vm/src/vm/mod.rs (1)
crates/vm/src/vm/setting.rs (1)
  • new (32-34)
⏰ 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). (11)
  • GitHub Check: Run rust tests (ubuntu-latest)
  • GitHub Check: Run snippets and cpython tests (ubuntu-latest)
  • GitHub Check: Run rust tests (windows-latest)
  • GitHub Check: Run snippets and cpython tests (windows-latest)
  • GitHub Check: Run snippets and cpython tests (macos-latest)
  • GitHub Check: Run tests under miri
  • GitHub Check: Run snippets and cpython tests on wasm-wasi
  • GitHub Check: Run rust tests (macos-latest)
  • GitHub Check: Check the WASM package and demo
  • GitHub Check: Ensure compilation on various targets
  • GitHub Check: Check Rust code with clippy
🔇 Additional comments (26)
crates/vm/src/getpath.rs (7)

1-11: LGTM! Well-structured module with clear documentation.

The module header clearly references Python's getpath.py and explains the purpose. The imports are clean and appropriate for the functionality.


14-66: LGTM! Platform-specific landmarks are well-designed.

The platform modules provide a clean abstraction with consistent interfaces across POSIX and Windows. Version-based path construction correctly uses the crate's version constants.


72-89: LGTM! Clean upward directory search implementation.

The generic search_up function is well-designed with a test closure pattern. The loop correctly terminates when pop() returns false at the filesystem root.


108-171: LGTM! Well-structured path configuration workflow.

The function follows Python's getpath.py workflow with clear step-by-step comments. Each step has appropriate fallbacks, ensuring the function never fails.


284-298: LGTM! Correct base_executable derivation logic.

The function properly handles venv scenarios by constructing the path from the home directory, with a sensible fallback to the current executable.


335-347: LGTM! Platform-appropriate executable path resolution.

Using which::which for proper PATH resolution on native platforms and falling back to direct path on wasm32 is appropriate.


364-388: Tests provide basic coverage.

The tests verify non-panicking behavior and basic functionality. Consider adding tests for venv detection and build directory detection in follow-up work.

crates/vm/src/import.rs (1)

209-209: LGTM! Configuration access path correctly updated.

The change from vm.state.settings.verbose to vm.state.config.settings.verbose is consistent with the PR's migration to PyConfig-based configuration.

crates/vm/src/stdlib/builtins.rs (2)

134-135: LGTM! Optimize setting access correctly migrated.

The change to vm.state.config.settings.optimize is consistent with the configuration migration.


1083-1083: LGTM! Debug mode derivation correctly updated.

The debug_mode calculation now uses the migrated config path consistently with other changes in this PR.

src/lib.rs (5)

172-180: LGTM! Safe path check correctly migrated.

The configuration access is properly updated. The inline Python code for path insertion is appropriate for this use case.


192-198: LGTM! Faulthandler check correctly migrated.

The faulthandler initialization logic correctly uses the new config path.


201-202: LGTM! Quiet and verbose checks correctly migrated.

Both settings are now accessed through the unified vm.state.config.settings path.


235-235: LGTM! Inspect check correctly migrated.

The inspect flag access is consistent with other configuration migrations.


244-244: LGTM! Profile settings access correctly migrated.

The flame profiler settings are now accessed through the new config structure.

crates/vm/src/vm/interpreter.rs (2)

1-2: LGTM! Imports correctly updated for new configuration system.

The imports properly bring in PyConfig from the parent module and getpath from the crate for path configuration initialization.


50-57: LGTM! Core integration of path configuration into VM initialization.

The initialization flow correctly:

  1. Computes paths from settings via getpath::init_path_config
  2. Wraps settings and paths into PyConfig
  3. Passes the unified config to VirtualMachine::new

This cleanly separates path computation from VM construction while maintaining a single configuration object.

crates/vm/src/vm/setting.rs (1)

4-35: LGTM! Clean introduction of PyConfig and Paths.

The new Paths and PyConfig structs cleanly separate computed runtime paths from user-configurable settings. The design maintains good ownership discipline by keeping them as separate structs within a combined configuration container.

crates/vm/src/vm/mod.rs (4)

53-53: LGTM! Public API updated to expose PyConfig and Paths.

The export list correctly includes the new Paths and PyConfig types alongside the existing Settings export.


230-232: LGTM! Path accesses updated to use module_search_paths.

All path-related logic correctly uses config.paths.module_search_paths instead of the deprecated settings.path_list. Error messages have also been updated to reference the new structure.

Also applies to: 241-241, 378-378, 392-393


306-306: LGTM! Settings accesses updated consistently.

All settings accesses correctly use config.settings.* for buffered_stdio, allow_external_library, and optimize.

Also applies to: 367-367, 508-508


90-90: LGTM! VirtualMachine refactored to use PyConfig consistently.

The refactoring correctly updates the configuration approach:

  • PyGlobalState now uses config: PyConfig (line 90)
  • VirtualMachine::new signature updated to accept PyConfig (line 117)
  • All internal accesses properly use config.settings to retrieve values (lines 144, 154, 174)
  • External callsite in Interpreter::with_init correctly constructs PyConfig from Settings before passing it to VirtualMachine::new (interpreter.rs:53-57)

The pattern is clean and consistent throughout.

crates/vm/src/stdlib/sys.rs (4)

98-112: LGTM! Prefix functions updated to use PyConfig paths.

The prefix, base_prefix, exec_prefix, and base_exec_prefix functions correctly return String values from vm.state.config.paths.* instead of static strings. The cloning is appropriate for these configuration getters.


160-162: LGTM! Executable paths correctly sourced from PyConfig.

Both _base_executable and executable now return String values from vm.state.config.paths.*, consistent with the path configuration refactoring.

Also applies to: 170-172


121-129: LGTM! argv and path correctly use PyConfig.

  • argv (lines 121-129) correctly accesses vm.state.config.settings.argv
  • path (lines 209-217) correctly accesses vm.state.config.paths.module_search_paths

The refactoring properly separates user-provided arguments from computed search paths.

Also applies to: 209-217


165-167: LGTM! Remaining sys attributes updated consistently.

All remaining functions (dont_write_bytecode, _xoptions, warnoptions, flags) correctly access configuration through vm.state.config.settings.*. The refactoring is complete and consistent.

Also applies to: 247-258, 261-269, 407-409

@youknowone youknowone merged commit 8b3bf55 into RustPython:main Dec 20, 2025
11 of 12 checks passed
@youknowone youknowone deleted the getpath branch December 20, 2025 23:25
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