This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author eryksun
Recipients eric.smith, eryksun, mrabarnett, pacujo, r.david.murray
Date 2018-06-01.21:03:25
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1527887005.49.0.81473610881.issue33721@psf.upfronthosting.co.za>
In-reply-to
Content
It has to be a ValueError since the error is an invalid parameter at the Python level. Similarly, in 3.6+ when using bytes paths in Windows, for which Python uses UTF-8 as the file-system encoding, os.path.exists() may raise UnicodeDecodeError:

    >>> try:
    ...     os.path.exists(b'\xc8spam')
    ... except ValueError as e: err = e
    ...
    >>> err
    UnicodeDecodeError('utf-8', b'\xc8spam', 0, 1, 'invalid continuation byte')

There's no practical support for NUL in paths in any OS as far as I know. In principle, the native NT API of Windows allows NUL in device names since it uses counted strings. However, Python only supports the Windows API, which uses null-terminated strings. So, practically speaking, not supporting NUL in paths is not an issue.

Here's an example of using an NT device name that contains a NUL character. It creates a DOS 'device' named "A\x00B" that targets "C:\\Temp". It's like a SUBST drive, but with any device name instead of just a drive-letter name. I omitted the ctypes definitions for brevity.

    obja = OBJECT_ATTRIBUTES("\\??\\A\x00B")
    target = UNICODE_STRING("\\??\\C:\\Temp")
    handle = ctypes.c_void_p()
    NtCreateSymbolicLinkObject(ctypes.byref(handle), GENERIC_ALL,
        ctypes.byref(obja), ctypes.byref(target))

Query the timestamps of the "A\x00B" device: 

    info = (ctypes.c_ulonglong * 5)()
    NtQueryAttributesFile(ctypes.byref(obja), info)

    times = (ctypes.c_int * 4)()
    for i in range(4):
        RtlTimeToSecondsSince1970(ctypes.byref(info, i*8),
            ctypes.byref(times, i*4))
    
Verify that the creation, last access, and last write times are the same as "C:\\Temp":

    s = os.stat('C:\\Temp')
    times2 = [int(x) for x in (s.st_ctime, s.st_atime, s.st_mtime)]

    >>> times[:3] == times2
    True

(The fourth timestamp is the change time, which isn't supported in Windows Python for legacy reasons that also relate to the bizarre use of st_ctime for the creation time, instead of st_birthtime.)
History
Date User Action Args
2018-06-01 21:03:25eryksunsetrecipients: + eryksun, eric.smith, mrabarnett, r.david.murray, pacujo
2018-06-01 21:03:25eryksunsetmessageid: <1527887005.49.0.81473610881.issue33721@psf.upfronthosting.co.za>
2018-06-01 21:03:25eryksunlinkissue33721 messages
2018-06-01 21:03:25eryksuncreate