Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Add file_id
  • Loading branch information
youknowone committed Apr 21, 2024
commit 593b16402597e84d589aed83ac8f7b668a0d4682
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 0 additions & 26 deletions Lib/test/test_genericpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,6 @@ def _test_samefile_on_link_func(self, func):
create_file(test_fn2)
self.assertFalse(self.pathmodule.samefile(test_fn1, test_fn2))

@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; properly implement stat st_dev/st_ino")
@os_helper.skip_unless_symlink
def test_samefile_on_symlink(self):
self._test_samefile_on_link_func(os.symlink)
Expand Down Expand Up @@ -285,7 +284,6 @@ def _test_samestat_on_link_func(self, func):
self.assertFalse(self.pathmodule.samestat(os.stat(test_fn1),
os.stat(test_fn2)))

@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; properly implement stat st_dev/st_ino")
@os_helper.skip_unless_symlink
def test_samestat_on_symlink(self):
self._test_samestat_on_link_func(os.symlink)
Expand Down Expand Up @@ -314,30 +312,6 @@ class TestGenericTest(GenericTest, unittest.TestCase):
# and is only meant to be inherited by others.
pathmodule = genericpath

# TODO: RUSTPYTHON
if sys.platform == "win32":
@unittest.expectedFailure
def test_samefile(self):
super().test_samefile()

# TODO: RUSTPYTHON
if sys.platform == "win32":
@unittest.expectedFailure
def test_samefile_on_link(self):
super().test_samefile_on_link()

# TODO: RUSTPYTHON
if sys.platform == "win32":
@unittest.expectedFailure
def test_samestat(self):
super().test_samestat()

# TODO: RUSTPYTHON
if sys.platform == "win32":
@unittest.expectedFailure
def test_samestat_on_link(self):
super().test_samestat_on_link()

def test_invalid_paths(self):
for attr in GenericTest.common_attributes:
# os.path.commonprefix doesn't raise ValueError
Expand Down
20 changes: 0 additions & 20 deletions Lib/test/test_ntpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -912,26 +912,6 @@ def test_expandvars(self): # TODO: RUSTPYTHON; remove when done
def test_expandvars_nonascii(self): # TODO: RUSTPYTHON; remove when done
super().test_expandvars_nonascii()

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_samefile(self): # TODO: RUSTPYTHON; remove when done
super().test_samefile()

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_samefile_on_link(self): # TODO: RUSTPYTHON; remove when done
super().test_samefile_on_link()

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_samestat(self): # TODO: RUSTPYTHON; remove when done
super().test_samestat()

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_samestat_on_link(self): # TODO: RUSTPYTHON; remove when done
super().test_samestat_on_link()


class PathLikeTests(NtpathTestCase):

Expand Down
16 changes: 0 additions & 16 deletions Lib/test/test_shutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,6 @@ def test_copytree_simple(self):
actual = read_file((dst_dir, 'test_dir', 'test.txt'))
self.assertEqual(actual, '456')

@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
def test_copytree_dirs_exist_ok(self):
src_dir = self.mkdtemp()
dst_dir = self.mkdtemp()
Expand Down Expand Up @@ -1557,7 +1556,6 @@ def test_copyfile_nonexistent_dir(self):
write_file(src_file, 'foo')
self.assertRaises(FileNotFoundError, shutil.copyfile, src_file, dst)

@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
def test_copyfile_copy_dir(self):
# Issue 45234
# test copy() and copyfile() raising proper exceptions when src and/or
Expand Down Expand Up @@ -2498,18 +2496,15 @@ def test_move_file(self):
# Move a file to another location on the same filesystem.
self._check_move_file(self.src_file, self.dst_file, self.dst_file)

@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
def test_move_file_to_dir(self):
# Move a file inside an existing dir on the same filesystem.
self._check_move_file(self.src_file, self.dst_dir, self.dst_file)

@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
def test_move_file_to_dir_pathlike_src(self):
# Move a pathlike file to another location on the same filesystem.
src = pathlib.Path(self.src_file)
self._check_move_file(src, self.dst_dir, self.dst_file)

@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
def test_move_file_to_dir_pathlike_dst(self):
# Move a file to another pathlike location on the same filesystem.
dst = pathlib.Path(self.dst_dir)
Expand All @@ -2520,7 +2515,6 @@ def test_move_file_other_fs(self):
# Move a file to an existing dir on another filesystem.
self.test_move_file()

@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
@mock_rename
def test_move_file_to_dir_other_fs(self):
# Move a file to another location on another filesystem.
Expand All @@ -2539,30 +2533,25 @@ def test_move_dir_other_fs(self):
# Move a dir to another location on another filesystem.
self.test_move_dir()

@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
def test_move_dir_to_dir(self):
# Move a dir inside an existing dir on the same filesystem.
self._check_move_dir(self.src_dir, self.dst_dir,
os.path.join(self.dst_dir, os.path.basename(self.src_dir)))

@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
@mock_rename
def test_move_dir_to_dir_other_fs(self):
# Move a dir inside an existing dir on another filesystem.
self.test_move_dir_to_dir()

@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
def test_move_dir_sep_to_dir(self):
self._check_move_dir(self.src_dir + os.path.sep, self.dst_dir,
os.path.join(self.dst_dir, os.path.basename(self.src_dir)))

@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
@unittest.skipUnless(os.path.altsep, 'requires os.path.altsep')
def test_move_dir_altsep_to_dir(self):
self._check_move_dir(self.src_dir + os.path.altsep, self.dst_dir,
os.path.join(self.dst_dir, os.path.basename(self.src_dir)))

@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
def test_existing_file_inside_dest_dir(self):
# A file with the same name inside the destination dir already exists.
with open(self.dst_file, "wb"):
Expand Down Expand Up @@ -2645,7 +2634,6 @@ def test_move_dir_symlink(self):
self.assertTrue(os.path.islink(dst_link))
self.assertTrue(os.path.samefile(src, dst_link))

@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
def test_move_return_value(self):
rv = shutil.move(self.src_file, self.dst_dir)
self.assertEqual(rv,
Expand All @@ -2655,7 +2643,6 @@ def test_move_as_rename_return_value(self):
rv = shutil.move(self.src_file, os.path.join(self.dst_dir, 'bar'))
self.assertEqual(rv, os.path.join(self.dst_dir, 'bar'))

@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
@mock_rename
def test_move_file_special_function(self):
moved = []
Expand All @@ -2664,7 +2651,6 @@ def _copy(src, dst):
shutil.move(self.src_file, self.dst_dir, copy_function=_copy)
self.assertEqual(len(moved), 1)

@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
@mock_rename
def test_move_dir_special_function(self):
moved = []
Expand Down Expand Up @@ -2693,7 +2679,6 @@ def test_move_dir_caseinsensitive(self):

# bpo-26791: Check that a symlink to a directory can
# be moved into that directory.
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
@mock_rename
def _test_move_symlink_to_dir_into_dir(self, dst):
src = os.path.join(self.src_dir, 'linktodir')
Expand Down Expand Up @@ -2894,7 +2879,6 @@ def test_file_offset(self):
self.assertEqual(src.tell(), self.FILESIZE)
self.assertEqual(dst.tell(), self.FILESIZE)

@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
@unittest.skipIf(os.name != 'nt', "Windows only")
def test_win_impl(self):
# Make sure alternate Windows implementation is called.
Expand Down
8 changes: 1 addition & 7 deletions Lib/test/test_tarfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -1299,6 +1299,7 @@ def test_link_size(self):
os_helper.unlink(target)
os_helper.unlink(link)

@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
@os_helper.skip_unless_symlink
def test_symlink_size(self):
path = os.path.join(TEMPDIR, "symlink")
Expand Down Expand Up @@ -1496,13 +1497,6 @@ def expectedSuccess(test_item):
def test_cwd(self):
super().test_cwd()

# TODO: RUSTPYTHON
if sys.platform == "win32":
@expectedSuccess
def test_symlink_size(self):
super().test_symlink_size()
pass


class Bz2WriteTest(Bz2Test, WriteTest):
pass
Expand Down
4 changes: 1 addition & 3 deletions vm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,11 @@ which = "4.2.5"
num_cpus = "1.13.1"

[target.'cfg(windows)'.dependencies]
junction = { workspace = true }
schannel = { workspace = true }
widestring = { workspace = true }
winreg = "0.10.1"

[target.'cfg(windows)'.dependencies.junction]
workspace = true

[target.'cfg(windows)'.dependencies.windows]
version = "0.52.0"
features = [
Expand Down
41 changes: 36 additions & 5 deletions vm/src/windows.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::common::fileutils::{
StatStruct,
windows::{get_file_information_by_name, FILE_INFO_BY_NAME_CLASS},
StatStruct,
};
use crate::{
convert::{ToPyObject, ToPyResult},
Expand Down Expand Up @@ -124,11 +124,42 @@ fn win32_xstat_impl(path: &OsStr, traverse: bool) -> std::io::Result<StatStruct>
}
}

// TODO: replace it with win32_xstat_slow_impl(&path, result, traverse)
meta_to_stat(&crate::stdlib::os::fs_metadata(path, traverse)?)
// TODO: check if win32_xstat_slow_impl(&path, result, traverse) is required
meta_to_stat(
&crate::stdlib::os::fs_metadata(path, traverse)?,
file_id(path)?,
)
}

// Ported from zed: https://github.com/zed-industries/zed/blob/v0.131.6/crates/fs/src/fs.rs#L1532-L1562
// can we get file id not open the file twice?
// https://github.com/rust-lang/rust/issues/63010
fn file_id(path: &OsStr) -> std::io::Result<u64> {
use std::os::windows::{fs::OpenOptionsExt, io::AsRawHandle};
use windows_sys::Win32::{
Foundation::HANDLE,
Storage::FileSystem::{
GetFileInformationByHandle, BY_HANDLE_FILE_INFORMATION, FILE_FLAG_BACKUP_SEMANTICS,
},
};

let file = std::fs::OpenOptions::new()
.read(true)
.custom_flags(FILE_FLAG_BACKUP_SEMANTICS)
.open(path)?;

let mut info: BY_HANDLE_FILE_INFORMATION = unsafe { std::mem::zeroed() };
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfileinformationbyhandle
// This function supports Windows XP+
let ret = unsafe { GetFileInformationByHandle(file.as_raw_handle() as HANDLE, &mut info) };
if ret == 0 {
return Err(std::io::Error::last_os_error());
};

Ok(((info.nFileIndexHigh as u64) << 32) | (info.nFileIndexLow as u64))
}

fn meta_to_stat(meta: &std::fs::Metadata) -> std::io::Result<StatStruct> {
fn meta_to_stat(meta: &std::fs::Metadata, file_id: u64) -> std::io::Result<StatStruct> {
let st_mode = {
// Based on CPython fileutils.c' attributes_to_mode
let mut m = 0;
Expand All @@ -155,7 +186,7 @@ fn meta_to_stat(meta: &std::fs::Metadata) -> std::io::Result<StatStruct> {
};
Ok(StatStruct {
st_dev: 0,
st_ino: 0,
st_ino: file_id,
st_mode,
st_nlink: 0,
st_uid: 0,
Expand Down