On Sun, Jul 1, 2018 at 8:50 AM, Steven D'Aprano <steve+comp.lang.pyt...@pearwood.info> wrote: > On Sun, 01 Jul 2018 03:18:23 +0000, eryk sun wrote: > >> The Windows API handles this, but not for a path that begins with \\?\. > > But what about the *Python* API? The Python open() function, and all the > high-level os.* and os.path.* functions which take paths as strings are > supposed to automatically convert forward slashes to backslashes. Aren't > they?
Python's I/O functions don't modify file paths, except to decode bytes paths in 3.6+. os.path.normpath uses backslash in Windows, without involving the OS, as does pathlib in Python 3. os.path.abspath calls WinAPI GetFullPathName to get a canonical, fully-qualified path, including transforming reserved paths, e.g. >>> os.path.abspath('C:/Temp/conout$.txt') '\\\\.\\conout$' >>> os.path.abspath('C:/Temp/spam. . .') 'C:\\Temp\\spam' (Note that the above "conout$" example is for Windows 8 and 10. In prior versions, "conin$" and "conout$" aren't reserved in qualified-relative or absolute paths, only when passed to CreateFile as unqualified names.) The \\?\ prefix allows using otherwise reserved names such as "con" and "spam...". For versions of Windows prior to 10 or Python prior to 3.6, the \\?\ prefix is also the only way to get past the 260 character limit of legacy DOS paths to work with paths with up to 32K characters. Python 3.6+ is manifested to support long paths in Windows 10 without requiring the \\?\ prefix. This can be enabled by setting the LongPathsEnabled value in "HKLM\System\CurrentControlSet\Control\FileSystem". Maybe in a future version this registry setting will be enabled by default. >> Bear in mind that forward slash is just a name character in NT. > > Interesting... > > That's rather like on HFS Plus, where / is an ordinary character allowed > in file names (although Mac OS goes to extraordinary effort to ensure > that tools that expect / as a path separator see it, and those which > expect : as the path separator see it instead). Many characters are reserved in Windows file systems that aren't generally reserved in NT, including forward slash. What happens here is that the Object Manager hands off parsing the rest of a path as soon as it reaches an object that has a parse procedure. This allows object types such as Key and Device objects to implement custom namespaces. The Configuration Manager's (registry) Key parse procedure limits names to 256 characters and the tree depth to 512 keys. (Note that HKCU is a pseudo-handle for "\Registry\User\<sid>", so subtract 3 from the depth.) However it doesn't reserve characters, except for the native backslash path separator. IIRC it allows NUL in key names, but that would render them impossible to access in the Windows API, which uses null-terminated strings. The I/O Manager's Device parse procedure sends an IRP_MJ_CREATE I/O request packet either to the first device in the stack (including lower/upper filter drivers), or to the file-system device stack that's managing it. The I/O manager doesn't reserve additional characters or limit name length, but most file systems limit names to 255 characters (127 for UDF) and reserve backslash (path separator), slash, colon, pipe, wildcards (*?<>"), and ASCII controls. In contrast, the named pipe file system (i.e. WinAPI \\.\PIPE or native \Device\NamedPipe) is extremely lenient. Pipe names can be up to 259 characters and can include any character except NUL. This file system doesn't support directories, so pipe names can even include backslash, which is a common practice. Except for disk volumes, most devices aren't file systems or managed by one. However, sometimes they do implement a simple namespace of hard-coded names. For example, the console device "\Device\ConDrv" implements a few names such as "Connect", "Input", "Output", "Console" (con), "CurrentIn" (conin$), and "CurrentOut" (conout$). -- https://mail.python.org/mailman/listinfo/python-list