Returning Windows file attribute information via os.stat() #65918
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
assignee = 'https://github.com/zware' closed_at = <Date 2014-06-19.15:02:20.309> created_at = <Date 2014-06-11.13:22:41.541> labels = ['type-feature', 'library'] title = 'Returning Windows file attribute information via os.stat()' updated_at = <Date 2014-06-20.09:18:58.030> user = 'https://github.com/benhoyt'
activity = <Date 2014-06-20.09:18:58.030> actor = 'vstinner' assignee = 'zach.ware' closed = True closed_date = <Date 2014-06-19.15:02:20.309> closer = 'zach.ware' components = ['Library (Lib)'] creation = <Date 2014-06-11.13:22:41.541> creator = 'benhoyt' dependencies =  files = ['35615', '35621', '35622', '35632'] hgrepos =  issue_num = 21719 keywords = ['patch'] message_count = 17.0 messages = ['220266', '220272', '220274', '220275', '220416', '220439', '220464', '220467', '220497', '220498', '220499', '220563', '220989', '220990', '221062', '221064', '221081'] nosy_count = 6.0 nosy_names = ['loewis', 'vstinner', 'benhoyt', 'ethan.furman', 'Jim.Jewett', 'zach.ware'] pr_nums =  priority = 'normal' resolution = 'fixed' stage = 'resolved' status = 'closed' superseder = None type = 'enhancement' url = 'https://bugs.python.org/issue21719' versions = ['Python 3.5']
The text was updated successfully, but these errors were encountered:
I asked recently on python-dev  about adding a "st_winattrs" attribute to stat result objects on Windows, to return the full set of Windows file attribute bits, such as "hidden" or "compressed" status. Copying from that thread for a bit more context here:
Python's os.stat() simply discards most of the file attribute
Given that os.stat() returns extended, platform-specific file
There are several questions on StackOverflow about how to get this
To solve this problem, I think we should add a "st_winattrs" attribute to the object returned by os.stat() on
Then, similarly to existing code like hasattr(st, 'st_blocks') on
def is_hidden(path): if startswith(os.path.basename(path), '.'): return True st = os.stat(path) return getattr(st, 'st_winattrs', 0) & FILE_ATTRIBUTE_HIDDEN != 0
There was general support for this idea on python-dev (see   ), so I'd love to see this in Python 3.5.
Basically we need to add a "st_winattrs" integer attribute to the win32_stat struct in posixmodule.c and add the FILE_ATTRIBUTE_* constants to _stat.c, as well as adding Windows-specific tests and documentation.
I've never compiled CPython on Windows, but I aim to provide a patch for this at some stage soonish. Feedback and other patches welcome in the meantime. :-)
Instead of the somewhat cryptic name "winattrs", I suggest to call it st_file_attributes, as it is called in the Windows API (actually, GetFileAttributesEx calls it dwFileAttributes, but st_file_attributes could be considered a Pythonic spelling of that).
On Windows, os.stat() calls GetFileInformationByHandle() which fills a BY_HANDLE_FILE_INFORMATION structure, and this structure has a dwFileAttributes attribute. The os.stat() calls also GetFileType().
So I agree that os.stat().st_file_attributes is less surprising for Windows developers and it is more homogenous with FILE_ATTRIBUTE_xxx constants.
Updated patch attached based on code reviews.
I'm replying to the code review here as when I tried to reply on bugs.python.org/review I got a Python exception, "AttributeError: NoneType has no attribute something or other". FYI, it seems Django is set up in debug mode, because it was the full colourful traceback with local vars etc. I didn't save this file, sorry!
I don't think so -- I thought the purpose of moving them to _stat.c was so you could use the windows.h constants rather than hard-coded integers? But if they're in stat.py, why do they need to be in _stat.c as well?
Fixed in latest patch.
I disagree. I realize FILE_ATTRIBUTE_* is longish, but it's what it's called in the Windows API, so will make these constants much more findable and obvious to Windows programmers (consistent with the Win32 documentation).
No, it won't be present at all (like the other non-cross-platform attributes).
Correct -- see the Win32 API documentation and loewis's comment.
I don't think we should duplicate the Win32 documentation. Ours will just be less thorough and potentially get out of date. I agree we should add a link to the Win32 docs though.
Could, but I don't like this when I'm doing bit/integer comparisons. Explicit is better.
Agreed. See above.
That's a good way of doing it. I'll use this approach.
I don't think so. None of the other values in win32_stat (e.g., st_dev) are defined using DWORD or Win32-style types. See also loewis's comment.
Agreed. I'll make this change.
Ben Hoyt wrote:
Generally when you get that you can just hit back and try again, it will work by the 4th try ;)
The idea is that _stat.c will use system-provided values wherever possible, but stat.py should be as accurate as we can make it to provide a backup for when _stat isn't around (either when it's just not built, which isn't an issue on Windows, or in another Python implementation).
Fair call. I've added the constants to stat.py as well. Updated patch attached.
BTW, thanks for the mention in "What's New in Python 3.5": https://docs.python.org/3.5/whatsnew/3.5.html#os
Can I make one small suggestion for a tweak there? A link to the docs for os.stat() would be good. So maybe instead of mentioning "os.stat_result" -- which isn't really a documented class -- say "The return value of :func:`os.stat` now has..." where os.stat is a link to https://docs.python.org/3.5/library/os.html#os.stat with the documentation for that.