Repository navigation
Strange import errors with Python 3.12 on Windows #104820
Description
Activity
- addedtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on May 23, 2023 This is due to a bug in
os.stat()for filesystems that lack support forFileIdInfo. The same bug is also the cause of the problem withpathlib.Path.is_dir()that's reported in gh-104806.pathlib.Path.is_dir()usesos.stat(), whilentpath.isdir()usesnt._path_isdir(). For example, volume "G:" on my system contains an exFAT filesystem, which doesn't supportFileIdInfo.>>> nt._path_isdir('G:\\') True >>> stat.S_ISDIR(os.stat('G:\\').st_mode) False >>> stat.S_ISBLK(os.stat('G:\\').st_mode) True
>>> nt._path_isfile('G:\\spam.txt') True >>> stat.S_ISREG(os.stat('G:\\spam.txt').st_mode) False >>> stat.S_ISBLK(os.stat('G:\\spam.txt').st_mode) True
As shown above,
os.stat()is mistakenly reporting files and directories on this volume as block devices.@zooba, in
win32_xstat_slow_impl()in "Modules/posixmodule.c", theFileIdInforequest isn't universally supported by filesystem drivers. For example, it's not supported by FAT32/exFAT and, as demonstrated by this issue, it's not supported by the VirtualBox shared-folder filesystem.if (!GetFileInformationByHandle(hFile, &fileInfo) || !GetFileInformationByHandleEx(hFile, FileBasicInfo, &basicInfo, sizeof(basicInfo)) || !GetFileInformationByHandleEx(hFile, FileIdInfo, &idInfo, sizeof(idInfo))) { switch (GetLastError()) { case ERROR_INVALID_PARAMETER: case ERROR_INVALID_FUNCTION: case ERROR_NOT_SUPPORTED: /* Volumes and physical disks are block devices, e.g. \\.\C: and \\.\PhysicalDrive0. */ memset(result, 0, sizeof(*result)); result->st_mode = 0x6000; /* S_IFBLK */ goto cleanup; } retval = -1; goto cleanup; }
I'd add a new pointer variable,
p_idInfo. If the request fails, setp_idInfo = NULL. Otherwise setp_idInfo = &idInfo._Py_attribute_data_to_stat()in "Python/fileutils.c" falls back on the 64-bit file ID from theBY_HANDLE_FILE_INFORMATIONif theid_infoparameter is aNULLpointer.Also, to err on the side of caution,
_Py_attribute_data_to_stat()should fall back on the 64-bit file ID if the 128-bit file ID is 0 (i.e. both the low and high 64-bit parts are 0). The latter is the required value specified in [MS-FSCC] if a filesystem doesn't support a 128-bit file ID (even with the high 64-bit part set to 0) but for some reason the driver implements theFileIdInformationinformation class. I don't have an example of this. Usually it's either supported or requestingFileIdInformationfails, but the specification says we should be prepared to handle a zero value.Also, when
id_infois available, I'd prefer to use its 64-bitVolumeSerialNumberfield forst_dev, which is consistent with the new by-name fast path. Else fall back on the 32-bitdwVolumeSerialNumberfrom theBY_HANDLE_FILE_INFORMATION. NTFS and ReFS have always supported a 64-bit volume serial number.Reacted by Pekka Klärck, Barney Gale, sunmy2019, Steve Dower, Jason Bowen and An Long- added3.12only security fixesonly security fixes3.13only security fixesonly security fixes
on May 23, 2023 Also, when
id_infois available, I'd prefer to use its 64-bitVolumeSerialNumberfield forst_devSorry, Steve. I missed that you had already implemented this when I scanned over the code yesterday. I should have read it more carefully.
- added a commit that references this issue
on May 24, 2023 - moved this from Todo to Done in Release and Deferred blockers 🚫
on May 24, 2023 - added a commit that references this issue
on May 29, 2023
Metadata
Metadata
Assignees
Labels
Projects
- StatusShow more project fieldsDone
I tried to test our project with Python 3.12 beta 1 on Windows but everything failed. After some debugging I noticed that module imports seem to fail when modules aren't on my C-drive:
No problems with earlier Python versions:
Not sure does it matter, but I'm running Windows on VirtualBox and that E-drive is mapped to a directory on the Linux host.
Linked PRs