gh-152433: Windows: modernize and refactor fileutils to allow build for Windows UWP#153700
gh-152433: Windows: modernize and refactor fileutils to allow build for Windows UWP#153700thexai wants to merge 8 commits into
Conversation
|
Updated with more simplified and less invasive changes. |
57f8125 to
f0f837b
Compare
|
This breaks CI, e.g.
Can you reproduce this on a local Windows installation and fix? Regarding tests I have another question: are you able to run the tests on XBOX in general? I'd be curious in how many of them fail ... |
Reproduced and now should be fixed in latest PR update. 🙂 It's important to note that some tests fail because they expect specific responses to unusual situations that may not have a single logical outcome. For example: If a file is inaccessible (due to permissions), the parent directory is read, and if it's no longer available, the original error is not restored (instead of return access violation error, return file no exist error).
Also on UWP, due security restrictions (every App runs isolated) is not possible to access to some information in the file system like |
chris-eibl
left a comment
There was a problem hiding this comment.
LGTM, but I'd appreciate a second pair of eyes @python/windows-team.
zooba
left a comment
There was a problem hiding this comment.
Only left two comments, but the guts of it is, I think we can switch to FileStandardInfo for everyone, and that should simplify this change down to basically not needing the separate UWP path at all.
|
Updated PR with one simplification: UWP not support Lines 2027 to 2043 in 202c4c8 This allows remove part of UWP only code and some ifdef. |
|
Simplification 2: Merges |
Use same code for UWP and Desktop.
|
I think I've finished this! Minimal changes and the same common code for UWP and Desktop. Tests should pass... |
zooba
left a comment
There was a problem hiding this comment.
Apologies for lots of suggestions, but I'm excited about this cleanup! We're so close to really streamlining this code, so it'd be great to go the whole way.
My main target is to fully remove the BY_HANDLE_FILE_INFORMATION usage entirely, and also to minimise the logic in the to_stat function (more overwriting, less checking). The comments I've left should lead you there, but feel free to ignore them if you see another way.
| if (info) { | ||
| result->st_size = (((__int64)info->nFileSizeHigh) << 32) + info->nFileSizeLow; | ||
| result->st_nlink = info->nNumberOfLinks; | ||
| if (!id_info) | ||
| result->st_dev = info->dwVolumeSerialNumber; | ||
| } | ||
| if (standard_info && !info) { | ||
| result->st_size = standard_info->EndOfFile.QuadPart; | ||
| result->st_nlink = standard_info->NumberOfLinks; | ||
| } |
There was a problem hiding this comment.
I think we can simplify even further by just letting later checks overwrite earlier ones, so if both info and standard_info are provided, the latter will overwrite.
e.g. (don't apply this directly):
| if (info) { | |
| result->st_size = (((__int64)info->nFileSizeHigh) << 32) + info->nFileSizeLow; | |
| result->st_nlink = info->nNumberOfLinks; | |
| if (!id_info) | |
| result->st_dev = info->dwVolumeSerialNumber; | |
| } | |
| if (standard_info && !info) { | |
| result->st_size = standard_info->EndOfFile.QuadPart; | |
| result->st_nlink = standard_info->NumberOfLinks; | |
| } | |
| if (info) { | |
| result->st_size = (((__int64)info->nFileSizeHigh) << 32) + info->nFileSizeLow; | |
| result->st_nlink = info->nNumberOfLinks; | |
| result->st_dev = info->dwVolumeSerialNumber; | |
| // add the st_ino = from info assignment | |
| } | |
| if (standard_info) { | |
| result->st_size = standard_info->EndOfFile.QuadPart; | |
| result->st_nlink = standard_info->NumberOfLinks; | |
| } |
| result->st_ino = file_id.st_ino; | ||
| result->st_ino_high = file_id.st_ino_high; |
There was a problem hiding this comment.
Put these under the st_ino != 0 && st_ino_high != 0 check from (original) line 1134
| index is likely to be zero anyway. */ | ||
| result->st_ino = (((uint64_t)info->nFileIndexHigh) << 32) + info->nFileIndexLow; | ||
| if (info) | ||
| result->st_ino = (((uint64_t)info->nFileIndexHigh) << 32) + info->nFileIndexLow; |
There was a problem hiding this comment.
Put this up under the if (info) block at the start of the function (that is, unconditionally [apart from info] assign the file index, and we'll overwrite with id_info later if it's non-zero)
| const DWORD fileAttributes = basic_info ? basic_info->FileAttributes : info->dwFileAttributes; | ||
|
|
||
| result->st_file_attributes = fileAttributes; | ||
| result->st_mode = attributes_to_mode(fileAttributes); |
There was a problem hiding this comment.
Put st_file_attributes under each original if block, and st_mode can stay here and reference st_file_attributes
| result->st_dev = 1; | ||
| result->st_ino = basic_info->CreationTime.QuadPart; |
There was a problem hiding this comment.
These can go right at the start and be our defaults. But they should really both be 0, which is a supported result for both fields (and indicates they can't be used for comparisons).
|
|
||
| find_data_to_file_info(dataW, &file_info, &reparse_tag); | ||
| _Py_attribute_data_to_stat(&file_info, reparse_tag, NULL, NULL, &entry->win32_lstat); | ||
| _Py_attribute_data_to_stat(&file_info, NULL, reparse_tag, NULL, NULL, &entry->win32_lstat); |
There was a problem hiding this comment.
This is the only place where file_info is still used, and I'm pretty sure we can make find_data_to_file_info fill out a different type (presumably FILE_STANDARD_INFO), which would then let us entirely remove the old info argument from _Py_attribute_data_to_stat
There was a problem hiding this comment.
I'd thought of that too: there's no reason to still use old BY_HANDLE_FILE_INFORMATION struct just for this.
But it'll take me a while because I won't be at a PC tomorrow 🙂
There was a problem hiding this comment.
That's fine, we're not in any hurry right now. Just glad to have you working on it
Windows: modernize and refactor fileutils to allow build for Windows UWP
This is probably the last relevant commit missing to allow compile all Python core for UWP.
GetFileInformationByHandleis not supported in UWP, then is replaced with more modernGetFileInformationByHandleExcalls.Also code refactored to avoid some duplicated code.Note that Xbox (all models) runs only on Windows 11 based OS. Then is guaranteed that "fast stat" code (based on
GetFileInformationByName) is supported:cpython/Modules/posixmodule.c
Line 2299 in 050a84b
"slow stat" code path is not much relevant for UWP but also works if replaced
CreateFileWwithCreateFile2(in other PR).