Skip to content

Commit 22569fa

Browse files
committed
Add sys._stdlib_dir
1 parent d7a885c commit 22569fa

File tree

6 files changed

+35
-19
lines changed

6 files changed

+35
-19
lines changed

Lib/test/test_importlib/resources/test_files.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,6 @@ class OpenDiskTests(FilesTests, unittest.TestCase):
5252
def setUp(self):
5353
self.data = data01
5454

55-
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
56-
def test_read_bytes(self):
57-
super().test_read_bytes()
58-
5955

6056
class OpenZipTests(FilesTests, util.ZipSetup, unittest.TestCase):
6157
pass
@@ -67,10 +63,6 @@ def setUp(self):
6763

6864
self.data = namespacedata01
6965

70-
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
71-
def test_read_bytes(self):
72-
super().test_read_bytes()
73-
7466
class SiteDir:
7567
def setUp(self):
7668
self.fixtures = contextlib.ExitStack()

Lib/test/test_sys.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1310,7 +1310,6 @@ def test_module_names(self):
13101310
for name in sys.stdlib_module_names:
13111311
self.assertIsInstance(name, str)
13121312

1313-
@unittest.expectedFailure # TODO: RUSTPYTHON; AttributeError: module 'sys' has no attribute '_stdlib_dir'
13141313
def test_stdlib_dir(self):
13151314
os = import_helper.import_fresh_module('os')
13161315
marker = getattr(os, '__file__', None)

crates/vm/src/getpath.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,9 @@ pub fn init_path_config(settings: &Settings) -> Paths {
174174
paths.module_search_paths =
175175
build_module_search_paths(settings, &paths.prefix, &paths.exec_prefix);
176176

177+
// Step 9: Calculate stdlib_dir
178+
paths.stdlib_dir = calculate_stdlib_dir(&paths.prefix);
179+
177180
paths
178181
}
179182

@@ -301,6 +304,22 @@ fn calculate_base_executable(executable: Option<&PathBuf>, home_dir: &Option<Pat
301304
.unwrap_or_default()
302305
}
303306

307+
/// Calculate stdlib_dir (sys._stdlib_dir)
308+
/// Returns None if the stdlib directory doesn't exist
309+
fn calculate_stdlib_dir(prefix: &str) -> Option<String> {
310+
#[cfg(not(windows))]
311+
let stdlib_dir = PathBuf::from(prefix).join(platform::stdlib_subdir());
312+
313+
#[cfg(windows)]
314+
let stdlib_dir = PathBuf::from(prefix).join(platform::STDLIB_SUBDIR);
315+
316+
if stdlib_dir.is_dir() {
317+
Some(stdlib_dir.to_string_lossy().into_owned())
318+
} else {
319+
None
320+
}
321+
}
322+
304323
/// Build the complete module_search_paths (sys.path)
305324
fn build_module_search_paths(settings: &Settings, prefix: &str, exec_prefix: &str) -> Vec<String> {
306325
let mut paths = Vec::new();

crates/vm/src/stdlib/sys.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ mod sys {
148148
fn platlibdir(_vm: &VirtualMachine) -> &'static str {
149149
option_env!("RUSTPYTHON_PLATLIBDIR").unwrap_or("lib")
150150
}
151+
#[pyattr]
152+
fn _stdlib_dir(vm: &VirtualMachine) -> PyObjectRef {
153+
vm.state.config.paths.stdlib_dir.clone().to_pyobject(vm)
154+
}
151155

152156
// alphabetical order with segments of pyattr and others
153157

crates/vm/src/vm/setting.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ pub struct Paths {
1616
pub exec_prefix: String,
1717
/// sys.base_exec_prefix
1818
pub base_exec_prefix: String,
19+
/// sys._stdlib_dir
20+
pub stdlib_dir: Option<String>,
1921
/// Computed module_search_paths (complete sys.path)
2022
pub module_search_paths: Vec<String>,
2123
}

src/interpreter.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -113,18 +113,13 @@ pub fn init_stdlib(vm: &mut VirtualMachine) {
113113
/// Setup frozen standard library (compiled into the binary)
114114
#[cfg(all(feature = "stdlib", feature = "freeze-stdlib"))]
115115
fn setup_frozen_stdlib(vm: &mut VirtualMachine) {
116+
use rustpython_vm::common::rc::PyRc;
117+
116118
vm.add_frozen(rustpython_pylib::FROZEN_STDLIB);
117119

118-
// FIXME: Remove this hack once sys._stdlib_dir is properly implemented
119-
// or _frozen_importlib doesn't depend on it anymore.
120-
assert!(vm.sys_module.get_attr("_stdlib_dir", vm).is_err());
121-
vm.sys_module
122-
.set_attr(
123-
"_stdlib_dir",
124-
vm.new_pyobj(rustpython_pylib::LIB_PATH.to_owned()),
125-
vm,
126-
)
127-
.unwrap();
120+
// Set stdlib_dir to the frozen stdlib path
121+
let state = PyRc::get_mut(&mut vm.state).unwrap();
122+
state.config.paths.stdlib_dir = Some(rustpython_pylib::LIB_PATH.to_owned());
128123
}
129124

130125
/// Setup dynamic standard library loading from filesystem
@@ -135,6 +130,11 @@ fn setup_dynamic_stdlib(vm: &mut VirtualMachine) {
135130
let state = PyRc::get_mut(&mut vm.state).unwrap();
136131
let paths = collect_stdlib_paths();
137132

133+
// Set stdlib_dir to the first stdlib path if available
134+
if let Some(first_path) = paths.first() {
135+
state.config.paths.stdlib_dir = Some(first_path.clone());
136+
}
137+
138138
// Insert at the beginning so stdlib comes before user paths
139139
for path in paths.into_iter().rev() {
140140
state.config.paths.module_search_paths.insert(0, path);

0 commit comments

Comments
 (0)