Skip to content

bpo-39533: Use statx on more recent Linux to expose st_flags and st_btime on all platforms #19125

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 68 additions & 16 deletions Doc/library/os.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1856,6 +1856,15 @@ features:
* :data:`stat.UF_OPAQUE`
* :data:`stat.UF_NOUNLINK`
* :data:`stat.UF_COMPRESSED`
* :data:`stat.UF_COMPRESSED`
* :data:`stat.UF_TRACKED`
* :data:`stat.UF_SYSTEM`
* :data:`stat.UF_SPARSE`
* :data:`stat.UF_OFFLINE`
* :data:`stat.UF_REPARSE`
* :data:`stat.UF_ARCHIVE`
* :data:`stat.UF_READONLY`
* :data:`stat.UF_ENCRYPTED`
* :data:`stat.UF_HIDDEN`
* :data:`stat.SF_ARCHIVED`
* :data:`stat.SF_IMMUTABLE`
Expand Down Expand Up @@ -2786,6 +2795,14 @@ features:
The size of a symbolic link is the length of the pathname it contains,
without a terminating null byte.

.. attribute:: st_flags

User defined flags for file. On some systems this will contain the
equivalent BSD flags for the more specific flags returned on the given
platforms: See the :attr:`st_attributes` and :attr:`st_file_attributes`
fields below for the original values. If the platform does not support
returning flags this will be set to ``0`` (no flags).

Timestamps:

.. attribute:: st_atime
Expand All @@ -2803,6 +2820,14 @@ features:
* the time of most recent metadata change on Unix,
* the time of creation on Windows, expressed in seconds.

.. attribute:: st_btime

Time of creation ("file birth") expressed in seconds.

Identical to :attr:`st_ctime` on Windows. Some platforms, particularily
builds for pre-4.11 Linux kernels do not support returning this value,
and will return ``None`` instead.

.. attribute:: st_atime_ns

Time of most recent access expressed in nanoseconds as an integer.
Expand All @@ -2820,27 +2845,43 @@ features:
* the time of creation on Windows, expressed in nanoseconds as an
integer.

.. attribute:: st_btime_ns

Time of creation ("file birth") expressed in nanoseconds.

Identical to :attr:`st_ctime_ns` on Windows. Some platforms,
particularily builds for pre-4.11 Linux kernels do not support returning
this value, and will return ``None`` instead.

.. note::

The exact meaning and resolution of the :attr:`st_atime`,
:attr:`st_mtime`, and :attr:`st_ctime` attributes depend on the operating
system and the file system. For example, on Windows systems using the FAT
or FAT32 file systems, :attr:`st_mtime` has 2-second resolution, and
:attr:`st_atime` has only 1-day resolution. See your operating system
documentation for details.
:attr:`st_mtime`, :attr:`st_ctime`, and :attr:`st_btime` attributes depend
on the operating system and the file system. For example, on Windows
systems using the FAT or FAT32 file systems, :attr:`st_mtime` has 2-second
resolution, and :attr:`st_atime` has only 1-day resolution. See your
operating system documentation for details.

Similarly, although :attr:`st_atime_ns`, :attr:`st_mtime_ns`,
and :attr:`st_ctime_ns` are always expressed in nanoseconds, many
systems do not provide nanosecond precision. On systems that do
provide nanosecond precision, the floating-point object used to
store :attr:`st_atime`, :attr:`st_mtime`, and :attr:`st_ctime`
cannot preserve all of it, and as such will be slightly inexact.
If you need the exact timestamps you should always use
:attr:`st_atime_ns`, :attr:`st_mtime_ns`, and :attr:`st_ctime_ns`.
:attr:`st_ctime_ns`, and :attr:`st_btime_ns` are always expressed in
nanoseconds, many systems do not provide nanosecond precision. On
systems that do provide nanosecond precision, the floating-point object
used to store :attr:`st_atime`, :attr:`st_mtime`, :attr:`st_ctime`,
and :attr:`st_btime` cannot preserve all of it, and as such will be
slightly inexact. If you need the exact timestamps you should always use
:attr:`st_atime_ns`, :attr:`st_mtime_ns`, :attr:`st_ctime_ns`, and
:attr:`st_btime_ns`.

On some Unix systems (such as Linux), the following attributes may also be
available:

.. attribute:: st_attributes
.. attribute:: st_attributes_mask

Linux file attributes: ``stx_attributes`` and ``stx_attributes_mask``
members of the :c:type:`statx` structure returned by :c:func:`statx`.
See the ``STATX_FLAG_*`` constants in the :mod:`stat` module.

.. attribute:: st_blocks

Number of 512-byte blocks allocated for file.
Expand All @@ -2853,11 +2894,14 @@ features:

.. attribute:: st_rdev

Type of device if an inode device.
Type of device (combined major and minor number) if the queried file
was an inode device.

.. attribute:: st_flags
.. attribute:: st_mnt_id

User defined flags for file.
Mount ID of the mountpoint the queried file resides on. Information on
the associated filesystem may be found by analysing
*/proc/self/mountinfo*.

On other Unix systems (such as FreeBSD), the following attributes may be
available (but may be only filled out if root tries to use them):
Expand All @@ -2868,7 +2912,8 @@ features:

.. attribute:: st_birthtime

Time of file creation.
Time of file creation. Identical to :attr:`st_btime`, but retained for
backward compatibility.

On Solaris and derivatives, the following attributes may also be
available:
Expand Down Expand Up @@ -2942,6 +2987,13 @@ features:
files as :const:`S_IFCHR`, :const:`S_IFIFO` or :const:`S_IFBLK`
as appropriate.

.. versionadded:: 3.9
Added the :attr:`st_attributes` and :attr:`st_attributes_mask` members
on modern Linux.

.. versionadded:: 3.9
Added the :attr:`st_btime` and :attr:`st_flags` members for all platforms.

.. function:: statvfs(path)

Perform a :c:func:`statvfs` system call on the given path. The return value is
Expand Down
16 changes: 16 additions & 0 deletions Doc/library/stat.rst
Original file line number Diff line number Diff line change
Expand Up @@ -435,3 +435,19 @@ constants, but are not an exhaustive list.
IO_REPARSE_TAG_APPEXECLINK

.. versionadded:: 3.8

On Linux, the following constants are available for comparing against the
``st_attributes`` and ``st_attributes_mask`` members returned by
:func:`os.stat`. See the relevant man-page on
`statx(2) <http://man7.org/linux/man-pages/man2/statx.2.html>`_ for the exact
meaning of these constants.

.. data:: STATX_ATTR_COMPRESSED
STATX_ATTR_IMMUTABLE
STATX_ATTR_APPEND
STATX_ATTR_NODUMP
STATX_ATTR_ENCRYPTED
STATX_ATTR_VERITY
STATX_ATTR_DAX

.. versionadded:: 3.12
26 changes: 24 additions & 2 deletions Lib/stat.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,24 @@ def S_ISWHT(mode):
S_IXOTH = 0o0001 # execute by others

# Names for file flags
#
# Source: https://github.com/freebsd/freebsd/blob/master/sys/sys/stat.h

UF_NODUMP = 0x00000001 # do not dump file
UF_IMMUTABLE = 0x00000002 # file may not be changed
UF_APPEND = 0x00000004 # file may only be appended to
UF_OPAQUE = 0x00000008 # directory is opaque when viewed through a union stack
UF_NOUNLINK = 0x00000010 # file may not be renamed or deleted
UF_COMPRESSED = 0x00000020 # OS X: file is hfs-compressed
UF_HIDDEN = 0x00008000 # OS X: file should not be displayed
UF_COMPRESSED = 0x00000020 # file is compressed
UF_TRACKED = 0x00000040 # OS X: renames and deletes are tracked
UF_SYSTEM = 0x00000080 # Windows: system file bit
UF_SPARSE = 0x00000100 # sparse file
UF_OFFLINE = 0x00000200 # Windows: file is offline (slow to access)
UF_REPARSE = 0x00000400 # Windows: reparse point file
UF_ARCHIVE = 0x00000800 # Windows: file should be archived
UF_READONLY = 0x00001000 # Windows: file is read-only
UF_ENCRYPTED = 0x00002000 # Windows / Linux: file is encrypted
UF_HIDDEN = 0x00008000 # OS X / Windows: file should not be displayed
SF_ARCHIVED = 0x00010000 # file may be archived
SF_IMMUTABLE = 0x00020000 # file may not be changed
SF_APPEND = 0x00040000 # file may only be appended to
Expand Down Expand Up @@ -188,6 +198,18 @@ def filemode(mode):
FILE_ATTRIBUTE_VIRTUAL = 65536


# Linux STATX_ATTR constants for interpreting os.stat()'s
# "st_attributes" and "st_attributes_mask" members

STATX_ATTR_COMPRESSED = 0x0004
STATX_ATTR_IMMUTABLE = 0x0010
STATX_ATTR_APPEND = 0x0020
STATX_ATTR_NODUMP = 0x0040
STATX_ATTR_ENCRYPTED = 0x0800
STATX_ATTR_VERITY = 0x100000
STATX_ATTR_DAX = 0x200000


# If available, use C implementation
try:
from _stat import *
Expand Down
1 change: 1 addition & 0 deletions Misc/ACKS
Original file line number Diff line number Diff line change
Expand Up @@ -1583,6 +1583,7 @@ Andreas Schawo
Neil Schemenauer
David Scherer
Wolfgang Scherer
Alexander Schlarb
Hynek Schlawack
Bob Schmertz
Gregor Schmid
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Use the ``statx(2)`` system call for :func:`os.stat` under Linux to provide
cross-platform support for btime (time of file creation) and file
attributes. On Windows btime is emulated using ctime and both Linux and
Windows file attributes are converted to their (Free)BSD equivalent were
reasonable.
66 changes: 64 additions & 2 deletions Modules/_stat.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,38 @@ typedef unsigned short mode_t;
# define UF_COMPRESSED 0x00000020
#endif

#ifndef UF_TRACKED
# define UF_TRACKED 0x00000040
#endif

#ifndef UF_SYSTEM
# define UF_SYSTEM 0x00000080
#endif

#ifndef UF_SPARSE
# define UF_SPARSE 0x00000100
#endif

#ifndef UF_OFFLINE
# define UF_OFFLINE 0x00000200
#endif

#ifndef UF_REPARSE
# define UF_REPARSE 0x00000400
#endif

#ifndef UF_ARCHIVE
# define UF_ARCHIVE 0x00000800
#endif

#ifndef UF_READONLY
# define UF_READONLY 0x00001000
#endif

#ifndef UF_ENCRYPTED
# define UF_ENCRYPTED 0x00002000
#endif

#ifndef UF_HIDDEN
# define UF_HIDDEN 0x00008000
#endif
Expand Down Expand Up @@ -470,7 +502,15 @@ UF_IMMUTABLE: file may not be changed\n\
UF_APPEND: file may only be appended to\n\
UF_OPAQUE: directory is opaque when viewed through a union stack\n\
UF_NOUNLINK: file may not be renamed or deleted\n\
UF_COMPRESSED: OS X: file is hfs-compressed\n\
UF_COMPRESSED: file is compressed\n\
UF_TRACKED: OS X: renames and deletes are tracked\n\
UF_SYSTEM: Windows: system file bit\n\
UF_SPARSE: sparse file\n\
UF_OFFLINE: Windows: file is offline (slow to access)\n\
UF_REPARSE: Windows: reparse point file\n\
UF_ARCHIVE: Windows: file should be archived\n\
UF_READONLY: Windows: file is read-only\n\
UF_ENCRYPTED: Windows / Linux: file is encrypted\n\
UF_HIDDEN: OS X: file should not be displayed\n\
SF_ARCHIVED: file may be archived\n\
SF_IMMUTABLE: file may not be changed\n\
Expand All @@ -493,6 +533,10 @@ ST_CTIME\n\

"FILE_ATTRIBUTE_*: Windows file attribute constants\n\
(only present on Windows)\n\
\n"

"STATX_ATTR_*: Linux statx(2) file attribute constants\n\
(only present on modern Linux)\n\
");


Expand Down Expand Up @@ -547,6 +591,14 @@ stat_exec(PyObject *module)
ADD_INT_MACRO(module, UF_OPAQUE);
ADD_INT_MACRO(module, UF_NOUNLINK);
ADD_INT_MACRO(module, UF_COMPRESSED);
ADD_INT_MACRO(module, UF_TRACKED);
ADD_INT_MACRO(module, UF_SYSTEM);
ADD_INT_MACRO(module, UF_SPARSE);
ADD_INT_MACRO(module, UF_OFFLINE);
ADD_INT_MACRO(module, UF_REPARSE);
ADD_INT_MACRO(module, UF_ARCHIVE);
ADD_INT_MACRO(module, UF_READONLY);
ADD_INT_MACRO(module, UF_ENCRYPTED);
ADD_INT_MACRO(module, UF_HIDDEN);
ADD_INT_MACRO(module, SF_ARCHIVED);
ADD_INT_MACRO(module, SF_IMMUTABLE);
Expand Down Expand Up @@ -604,7 +656,17 @@ stat_exec(PyObject *module)
PyLong_FromUnsignedLong(IO_REPARSE_TAG_APPEXECLINK)) < 0) {
return -1;
}
#endif
#endif /* MS_WINDOWS */

#ifdef HAVE_LINUX_STATX
ADD_INT_MACRO(module, STATX_ATTR_COMPRESSED);
ADD_INT_MACRO(module, STATX_ATTR_IMMUTABLE);
ADD_INT_MACRO(module, STATX_ATTR_APPEND);
ADD_INT_MACRO(module, STATX_ATTR_NODUMP);
ADD_INT_MACRO(module, STATX_ATTR_ENCRYPTED);
ADD_INT_MACRO(module, STATX_ATTR_VERITY);
ADD_INT_MACRO(module, STATX_ATTR_DAX);
#endif /* HAVE_LINUX_STATX */

return 0;
}
Expand Down
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy