]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-83714: Use "stx_" prefix for all os.statx_result members (#140432)
authorVictor Stinner <vstinner@python.org>
Wed, 22 Oct 2025 09:48:37 +0000 (11:48 +0200)
committerGitHub <noreply@github.com>
Wed, 22 Oct 2025 09:48:37 +0000 (11:48 +0200)
Rename stx_birthtime to stx_btime, and rename stx_birthtime_ns to
stx_btime_ns.

Doc/library/os.rst
Doc/whatsnew/3.15.rst
Lib/test/test_os/test_os.py
Lib/test/test_os/test_posix.py
Misc/NEWS.d/next/Library/2025-09-18-21-25-41.gh-issue-83714.TQjDWZ.rst
Modules/posixmodule.c

index 50f6886c89df9e1a4ded5c20023fa098ce5035b6..8f7b9ac15a0d2212c78ea5d191df0c92cfd560ac 100644 (file)
@@ -3411,133 +3411,248 @@ features:
 
    Information about a file returned by :func:`os.statx`.
 
-   :class:`!statx_result` has all the attributes that :class:`~stat_result` has
-   on Linux, making it :term:`duck-typing` compatible, but
-   :class:`!statx_result` is not a subclass of :class:`~stat_result` and cannot
-   be used as a tuple.
-
-   :class:`!statx_result` has the following additional attributes:
+   :class:`!statx_result` has the following attributes:
 
    .. attribute:: stx_mask
 
       Bitmask of :const:`STATX_* <STATX_TYPE>` constants specifying the
       information retrieved, which may differ from what was requested.
 
-   .. attribute:: stx_attributes_mask
+   .. attribute:: stx_atime
 
-      Bitmask of :const:`STATX_ATTR_* <stat.STATX_ATTR_COMPRESSED>` constants
-      specifying the attributes bits supported for this file.
+      Time of most recent access expressed in seconds.
+
+      Equal to ``None`` if :data:`STATX_ATIME` is missing from
+      :attr:`~statx_result.stx_mask`.
+
+   .. attribute:: stx_atime_ns
+
+      Time of most recent access expressed in nanoseconds as an integer.
+
+      Equal to ``None`` if :data:`STATX_ATIME` is missing from
+      :attr:`~statx_result.stx_mask`.
+
+   .. attribute:: stx_atomic_write_segments_max
+
+      Maximum iovecs for direct I/O with torn-write protection.
+
+      Equal to ``None`` if :data:`STATX_WRITE_ATOMIC` is missing from
+      :attr:`~statx_result.stx_mask`.
+
+      .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
+         userspace API headers >= 6.11.
+
+   .. attribute:: stx_atomic_write_unit_min
+
+      Minimum size for direct I/O with torn-write protection.
+
+      Equal to ``None`` if :data:`STATX_WRITE_ATOMIC` is missing from
+      :attr:`~statx_result.stx_mask`.
+
+      .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
+         userspace API headers >= 6.11.
+
+   .. attribute:: stx_atomic_write_unit_max
+
+      Maximum size for direct I/O with torn-write protection.
+
+      Equal to ``None`` if :data:`STATX_WRITE_ATOMIC` is missing from
+      :attr:`~statx_result.stx_mask`.
+
+      .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
+         userspace API headers >= 6.11.
+
+   .. attribute:: stx_atomic_write_unit_max_opt
+
+      Maximum optimized size for direct I/O with torn-write protection.
+
+      Equal to ``None`` if :data:`STATX_WRITE_ATOMIC` is missing from
+      :attr:`~statx_result.stx_mask`.
+
+      .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
+         userspace API headers >= 6.16.
 
    .. attribute:: stx_attributes
 
       Bitmask of :const:`STATX_ATTR_* <stat.STATX_ATTR_COMPRESSED>` constants
       specifying the attributes of this file.
 
-   .. attribute:: stx_dev_major
+   .. attribute:: stx_attributes_mask
 
-      Major number of the device on which this file resides.
+      A mask indicating which bits in :attr:`stx_attributes` are supported by
+      the VFS and the filesystem.
 
-   .. attribute:: stx_dev_minor
+   .. attribute:: stx_blksize
 
-      Minor number of the device on which this file resides.
+      "Preferred" blocksize for efficient file system I/O. Writing to a file in
+      smaller chunks may cause an inefficient read-modify-rewrite.
 
-   .. attribute:: stx_rdev_major
+   .. attribute:: stx_blocks
 
-      Major number of the device this file represents.
+      Number of 512-byte blocks allocated for file.
+      This may be smaller than :attr:`stx_size`/512 when the file has holes.
 
-   .. attribute:: stx_rdev_minor
+      Equal to ``None`` if :data:`STATX_BLOCKS` is missing from
+      :attr:`~statx_result.stx_mask`.
 
-      Minor number of the device this file represents.
+   .. attribute:: stx_btime
 
-   .. attribute:: stx_mnt_id
+      Time of file creation expressed in seconds.
 
-      Mount identifier.
+      Equal to ``None`` if :data:`STATX_BTIME` is missing from
+      :attr:`~statx_result.stx_mask`.
 
-      Equal to ``None`` if :data:`STATX_MNT_ID` is missing from
-      :attr:`~os.statx_result.stx_mask`.
+   .. attribute:: stx_btime_ns
 
-      .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
-         userspace API headers >= 5.8.
+      Time of file creation expressed in nanoseconds as an integer.
 
-   .. attribute:: stx_dio_mem_align
+      Equal to ``None`` if :data:`STATX_BTIME` is missing from
+      :attr:`~statx_result.stx_mask`.
 
-      Direct I/O memory buffer alignment requirement.
+   .. attribute:: stx_ctime
 
-      Equal to ``None`` if :data:`STATX_DIOALIGN` is missing from
-      :attr:`~os.statx_result.stx_mask`.
+      Time of most recent metadata change expressed in seconds.
 
-      .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
-         userspace API headers >= 6.1.
+      Equal to ``None`` if :data:`STATX_CTIME` is missing from
+      :attr:`~statx_result.stx_mask`.
+
+   .. attribute:: stx_ctime_ns
+
+      Time of most recent metadata change expressed in nanoseconds as an
+      integer.
+
+      Equal to ``None`` if :data:`STATX_CTIME` is missing from
+      :attr:`~statx_result.stx_mask`.
+
+   .. attribute:: stx_dev
+
+      Identifier of the device on which this file resides.
+
+   .. attribute:: stx_dev_major
+
+      Major number of the device on which this file resides.
+
+   .. attribute:: stx_dev_minor
+
+      Minor number of the device on which this file resides.
 
    .. attribute:: stx_dio_offset_align
 
       Direct I/O file offset alignment requirement.
 
       Equal to ``None`` if :data:`STATX_DIOALIGN` is missing from
-      :attr:`~os.statx_result.stx_mask`.
+      :attr:`~statx_result.stx_mask`.
 
       .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
          userspace API headers >= 6.1.
 
-   .. attribute:: stx_subvol
+   .. attribute:: stx_dio_mem_align
 
-      Subvolume identifier.
+      Direct I/O memory buffer alignment requirement.
 
-      Equal to ``None`` if :data:`STATX_SUBVOL` is missing from
-      :attr:`~os.statx_result.stx_mask`.
+      Equal to ``None`` if :data:`STATX_DIOALIGN` is missing from
+      :attr:`~statx_result.stx_mask`.
 
       .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
-         userspace API headers >= 6.10.
+         userspace API headers >= 6.1.
 
-   .. attribute:: stx_atomic_write_unit_min
+   .. attribute:: stx_dio_read_offset_align
 
-      Minimum size for direct I/O with torn-write protection.
+      Direct I/O file offset alignment requirement for reads.
 
-      Equal to ``None`` if :data:`STATX_WRITE_ATOMIC` is missing from
-      :attr:`~os.statx_result.stx_mask`.
+      Equal to ``None`` if :data:`STATX_DIO_READ_ALIGN` is missing from
+      :attr:`~statx_result.stx_mask`.
 
       .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
-         userspace API headers >= 6.11.
+         userspace API headers >= 6.14.
 
-   .. attribute:: stx_atomic_write_unit_max
+   .. attribute:: stx_gid
 
-      Maximum size for direct I/O with torn-write protection.
+      Group identifier of the file owner.
 
-      Equal to ``None`` if :data:`STATX_WRITE_ATOMIC` is missing from
-      :attr:`~os.statx_result.stx_mask`.
+      Equal to ``None`` if :data:`STATX_GID` is missing from
+      :attr:`~statx_result.stx_mask`.
 
-      .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
-         userspace API headers >= 6.11.
+   .. attribute:: stx_ino
 
-   .. attribute:: stx_atomic_write_unit_max_opt
+      Inode number.
 
-      Maximum optimized size for direct I/O with torn-write protection.
+      Equal to ``None`` if :data:`STATX_INO` is missing from
+      :attr:`~statx_result.stx_mask`.
 
-      Equal to ``None`` if :data:`STATX_WRITE_ATOMIC` is missing from
-      :attr:`~os.statx_result.stx_mask`.
+   .. attribute:: stx_mnt_id
+
+      Mount identifier.
+
+      Equal to ``None`` if :data:`STATX_MNT_ID` is missing from
+      :attr:`~statx_result.stx_mask`.
 
       .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
-         userspace API headers >= 6.16.
+         userspace API headers >= 5.8.
 
-   .. attribute:: stx_atomic_write_segments_max
+   .. attribute:: stx_mode
 
-      Maximum iovecs for direct I/O with torn-write protection.
+      File mode: file type and file mode bits (permissions).
 
-      Equal to ``None`` if :data:`STATX_WRITE_ATOMIC` is missing from
-      :attr:`~os.statx_result.stx_mask`.
+   .. attribute:: stx_mtime
 
-      .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
-         userspace API headers >= 6.11.
+      Time of most recent content modification expressed in seconds.
 
-   .. attribute:: stx_dio_read_offset_align
+      Equal to ``None`` if :data:`STATX_MTIME` is missing from
+      :attr:`~statx_result.stx_mask`.
 
-      Direct I/O file offset alignment requirement for reads.
+   .. attribute:: stx_mtime_ns
 
-      Equal to ``None`` if :data:`STATX_DIO_READ_ALIGN` is missing from
-      :attr:`~os.statx_result.stx_mask`.
+      Time of most recent content modification expressed in nanoseconds as an
+      integer.
+
+      Equal to ``None`` if :data:`STATX_MTIME` is missing from
+      :attr:`~statx_result.stx_mask`.
+
+   .. attribute:: stx_nlink
+
+      Number of hard links.
+
+      Equal to ``None`` if :data:`STATX_NLINK` is missing from
+      :attr:`~statx_result.stx_mask`.
+
+   .. attribute:: stx_rdev
+
+      Type of device if an inode device.
+
+   .. attribute:: stx_rdev_major
+
+      Major number of the device this file represents.
+
+   .. attribute:: stx_rdev_minor
+
+      Minor number of the device this file represents.
+
+   .. attribute:: stx_size
+
+      Size of the file in bytes, if it is a regular file or a symbolic link.
+      The size of a symbolic link is the length of the pathname it contains,
+      without a terminating null byte.
+
+      Equal to ``None`` if :data:`STATX_SIZE` is missing from
+      :attr:`~statx_result.stx_mask`.
+
+   .. attribute:: stx_subvol
+
+      Subvolume identifier.
+
+      Equal to ``None`` if :data:`STATX_SUBVOL` is missing from
+      :attr:`~statx_result.stx_mask`.
 
       .. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
-         userspace API headers >= 6.14.
+         userspace API headers >= 6.10.
+
+   .. attribute:: stx_uid
+
+      User identifier of the file owner.
+
+      Equal to ``None`` if :data:`STATX_UID` is missing from
+      :attr:`~statx_result.stx_mask`.
 
    .. seealso:: The :manpage:`statx(2)` man page.
 
index 8503a4c7f973fcf1ad171ac9fd2b8c079495ea9a..22e9cfde06f877511cb4dea56be8889726315a2a 100644 (file)
@@ -438,7 +438,7 @@ os
 
 * Add :func:`os.statx` on Linux kernel versions 4.11 and later with
   glibc versions 2.28 and later.
-  (Contributed by Jeffrey Bosboom in :gh:`83714`.)
+  (Contributed by Jeffrey Bosboom and Victor Stinner in :gh:`83714`.)
 
 
 os.path
index 67599537736c8f98f4043a7cae11ffc2361b8918..9a40c5c2a1f1f3b56e20f314b240ffa357de989f 100644 (file)
@@ -750,8 +750,8 @@ class StatAttributeTests(unittest.TestCase):
         result = os.statx(filename, maximal_mask)
         basic_result = os.stat(filename)
 
-        time_attributes = ('st_atime', 'st_mtime', 'st_ctime', 'st_birthtime')
-        # gh-83714: st_birthtime can be None on tmpfs even if STATX_BTIME mask
+        time_attributes = ('stx_atime', 'stx_btime', 'stx_ctime', 'stx_mtime')
+        # gh-83714: stx_btime can be None on tmpfs even if STATX_BTIME mask
         # is used
         time_attributes = [name for name in time_attributes
                            if getattr(result, name) is not None]
@@ -759,43 +759,44 @@ class StatAttributeTests(unittest.TestCase):
 
         # Check that valid attributes match os.stat.
         requirements = (
-            ('st_mode', os.STATX_TYPE | os.STATX_MODE),
-            ('st_nlink', os.STATX_NLINK),
-            ('st_uid', os.STATX_UID),
-            ('st_gid', os.STATX_GID),
-            ('st_atime', os.STATX_ATIME),
-            ('st_atime_ns', os.STATX_ATIME),
-            ('st_mtime', os.STATX_MTIME),
-            ('st_mtime_ns', os.STATX_MTIME),
-            ('st_ctime', os.STATX_CTIME),
-            ('st_ctime_ns', os.STATX_CTIME),
-            ('st_ino', os.STATX_INO),
-            ('st_size', os.STATX_SIZE),
-            ('st_blocks', os.STATX_BLOCKS),
-            ('st_birthtime', os.STATX_BTIME),
-            ('st_birthtime_ns', os.STATX_BTIME),
+            ('stx_mode', os.STATX_TYPE | os.STATX_MODE),
+            ('stx_nlink', os.STATX_NLINK),
+            ('stx_uid', os.STATX_UID),
+            ('stx_gid', os.STATX_GID),
+            ('stx_atime', os.STATX_ATIME),
+            ('stx_atime_ns', os.STATX_ATIME),
+            ('stx_mtime', os.STATX_MTIME),
+            ('stx_mtime_ns', os.STATX_MTIME),
+            ('stx_ctime', os.STATX_CTIME),
+            ('stx_ctime_ns', os.STATX_CTIME),
+            ('stx_ino', os.STATX_INO),
+            ('stx_size', os.STATX_SIZE),
+            ('stx_blocks', os.STATX_BLOCKS),
+            ('stx_birthtime', os.STATX_BTIME),
+            ('stx_birthtime_ns', os.STATX_BTIME),
             # unconditionally valid members
-            ('st_blksize', 0),
-            ('st_rdev', 0),
-            ('st_dev', 0),
+            ('stx_blksize', 0),
+            ('stx_rdev', 0),
+            ('stx_dev', 0),
         )
         for name, bits in requirements:
-            if result.stx_mask & bits == bits and hasattr(basic_result, name):
+            st_name = "st_" + name[4:]
+            if result.stx_mask & bits == bits and hasattr(basic_result, st_name):
                 x = getattr(result, name)
-                b = getattr(basic_result, name)
+                b = getattr(basic_result, st_name)
                 self.assertEqual(type(x), type(b))
                 if isinstance(x, float):
                     self.assertAlmostEqual(x, b, msg=name)
                 else:
                     self.assertEqual(x, b, msg=name)
 
-        self.assertEqual(result.stx_rdev_major, os.major(result.st_rdev))
-        self.assertEqual(result.stx_rdev_minor, os.minor(result.st_rdev))
-        self.assertEqual(result.stx_dev_major, os.major(result.st_dev))
-        self.assertEqual(result.stx_dev_minor, os.minor(result.st_dev))
+        self.assertEqual(result.stx_rdev_major, os.major(result.stx_rdev))
+        self.assertEqual(result.stx_rdev_minor, os.minor(result.stx_rdev))
+        self.assertEqual(result.stx_dev_major, os.major(result.stx_dev))
+        self.assertEqual(result.stx_dev_minor, os.minor(result.stx_dev))
 
         members = [name for name in dir(result)
-                   if name.startswith('st_') or name.startswith('stx_')]
+                   if name.startswith('stx_')]
         for name in members:
             try:
                 setattr(result, name, 1)
index 905f0201253951c740ec72cd7cca3d06f1279dc8..de24719a1ca455eee7b10577c7b6ee7dc7946e15 100644 (file)
@@ -1672,17 +1672,22 @@ class TestPosixDirFd(unittest.TestCase):
         with self.prepare_file() as (dir_fd, name, fullname):
             posix.chown(name, os.getuid(), os.getgid(), dir_fd=dir_fd)
 
-    def check_statlike_dir_fd(self, func):
+    def check_statlike_dir_fd(self, func, prefix):
         with self.prepare() as (dir_fd, name, fullname):
             with open(fullname, 'w') as outfile:
                 outfile.write("testline\n")
             self.addCleanup(posix.unlink, fullname)
 
+            def get(result, attr):
+                return getattr(result, prefix + attr)
+
             s1 = func(fullname)
             s2 = func(name, dir_fd=dir_fd)
-            self.assertEqual((s1.st_dev, s1.st_ino), (s2.st_dev, s2.st_ino))
+            self.assertEqual((get(s1, "dev"), get(s1, "ino")),
+                             (get(s2, "dev"), get(s2, "ino")))
             s2 = func(fullname, dir_fd=None)
-            self.assertEqual((s1.st_dev, s1.st_ino), (s2.st_dev, s2.st_ino))
+            self.assertEqual((get(s1, "dev"), get(s1, "ino")),
+                             (get(s2, "dev"), get(s2, "ino")))
 
             self.assertRaisesRegex(TypeError, 'should be integer or None, not',
                     func, name, dir_fd=posix.getcwd())
@@ -1700,13 +1705,13 @@ class TestPosixDirFd(unittest.TestCase):
 
     @unittest.skipUnless(os.stat in os.supports_dir_fd, "test needs dir_fd support in os.stat()")
     def test_stat_dir_fd(self):
-        self.check_statlike_dir_fd(posix.stat)
+        self.check_statlike_dir_fd(posix.stat, prefix="st_")
 
     @unittest.skipUnless(hasattr(posix, 'statx'), "test needs os.statx()")
     def test_statx_dir_fd(self):
         def func(path, **kwargs):
             return posix.statx(path, os.STATX_INO, **kwargs)
-        self.check_statlike_dir_fd(func)
+        self.check_statlike_dir_fd(func, prefix="stx_")
 
     @unittest.skipUnless(os.utime in os.supports_dir_fd, "test needs dir_fd support in os.utime()")
     def test_utime_dir_fd(self):
index 7229a361147ee2e6f4f8682227911a049134e482..3653eb9a114a35be4d60f45b736232ca6d3648cb 100644 (file)
@@ -1,2 +1,2 @@
-Implement :func:`os.statx` on Linux kernel versions 4.11 and later with
-glibc versions 2.28 and later.  Contributed by Jeffrey Bosboom.
+Implement :func:`os.statx` on Linux kernel versions 4.11 and later with glibc
+versions 2.28 and later.  Contributed by Jeffrey Bosboom and Victor Stinner.
index d0b9eed8c8208b76e6620630a149e0206b121444..433acdcb538f11ef1bc267687afb8dc096af75af 100644 (file)
@@ -3330,17 +3330,17 @@ typedef struct {
 
 static PyMemberDef pystatx_result_members[] = {
     MM(stx_mask, Py_T_UINT, mask, "member validity mask"),
-    MM(st_blksize, Py_T_UINT, blksize, "blocksize for filesystem I/O"),
+    MM(stx_blksize, Py_T_UINT, blksize, "blocksize for filesystem I/O"),
     MM(stx_attributes, Py_T_ULONGLONG, attributes, "Linux inode attribute bits"),
-    MM(st_mode, Py_T_USHORT, mode, "protection bits"),
+    MM(stx_mode, Py_T_USHORT, mode, "protection bits"),
     MM(stx_attributes_mask, Py_T_ULONGLONG, attributes_mask,
         "Mask of supported bits in stx_attributes"),
     MM(stx_rdev_major, Py_T_UINT, rdev_major, "represented device major number"),
     MM(stx_rdev_minor, Py_T_UINT, rdev_minor, "represented device minor number"),
-    MX(st_rdev, Py_T_ULONGLONG, rdev, "device type (if inode device)"),
+    MX(stx_rdev, Py_T_ULONGLONG, rdev, "device type (if inode device)"),
     MM(stx_dev_major, Py_T_UINT, dev_major, "containing device major number"),
     MM(stx_dev_minor, Py_T_UINT, dev_minor, "containing device minor number"),
-    MX(st_dev, Py_T_ULONGLONG, dev, "device"),
+    MX(stx_dev, Py_T_ULONGLONG, dev, "device"),
     {NULL},
 };
 
@@ -3349,7 +3349,7 @@ static PyMemberDef pystatx_result_members[] = {
 #undef M
 
 
-#define STATX_GET_UINT(ATTR, MEMBER, MASK) \
+#define STATX_GET_UINT(ATTR, MASK) \
     static PyObject* \
     pystatx_result_get_##ATTR(PyObject *op, void *Py_UNUSED(context)) \
     { \
@@ -3357,36 +3357,31 @@ static PyMemberDef pystatx_result_members[] = {
         if (!(self->stx.stx_mask & MASK)) { \
             Py_RETURN_NONE; \
         } \
-        unsigned long value = self->stx.MEMBER; \
+        unsigned long value = self->stx.ATTR; \
         return PyLong_FromUnsignedLong(value); \
     }
 
-STATX_GET_UINT(st_uid, stx_uid, STATX_UID)
-STATX_GET_UINT(st_gid, stx_gid, STATX_GID)
-STATX_GET_UINT(st_nlink, stx_nlink, STATX_NLINK)
+STATX_GET_UINT(stx_uid, STATX_UID)
+STATX_GET_UINT(stx_gid, STATX_GID)
+STATX_GET_UINT(stx_nlink, STATX_NLINK)
 #ifdef HAVE_STRUCT_STATX_STX_DIO_MEM_ALIGN
-STATX_GET_UINT(stx_dio_mem_align, stx_dio_mem_align, STATX_DIOALIGN)
-STATX_GET_UINT(stx_dio_offset_align, stx_dio_offset_align, STATX_DIOALIGN)
+STATX_GET_UINT(stx_dio_mem_align, STATX_DIOALIGN)
+STATX_GET_UINT(stx_dio_offset_align, STATX_DIOALIGN)
 #endif
 #ifdef HAVE_STRUCT_STATX_STX_DIO_READ_OFFSET_ALIGN
-STATX_GET_UINT(stx_dio_read_offset_align, stx_dio_read_offset_align,
-               STATX_DIO_READ_ALIGN)
+STATX_GET_UINT(stx_dio_read_offset_align, STATX_DIO_READ_ALIGN)
 #endif
 #ifdef HAVE_STRUCT_STATX_STX_ATOMIC_WRITE_UNIT_MIN
-STATX_GET_UINT(stx_atomic_write_unit_min, stx_atomic_write_unit_min,
-               STATX_WRITE_ATOMIC)
-STATX_GET_UINT(stx_atomic_write_unit_max, stx_atomic_write_unit_max,
-               STATX_WRITE_ATOMIC)
-STATX_GET_UINT(stx_atomic_write_segments_max, stx_atomic_write_segments_max,
-               STATX_WRITE_ATOMIC)
+STATX_GET_UINT(stx_atomic_write_unit_min, STATX_WRITE_ATOMIC)
+STATX_GET_UINT(stx_atomic_write_unit_max, STATX_WRITE_ATOMIC)
+STATX_GET_UINT(stx_atomic_write_segments_max, STATX_WRITE_ATOMIC)
 #endif
 #ifdef HAVE_STRUCT_STATX_STX_ATOMIC_WRITE_UNIT_MAX_OPT
-STATX_GET_UINT(stx_atomic_write_unit_max_opt, stx_atomic_write_unit_max_opt,
-               STATX_WRITE_ATOMIC)
+STATX_GET_UINT(stx_atomic_write_unit_max_opt, STATX_WRITE_ATOMIC)
 #endif
 
 
-#define STATX_GET_ULONGLONG(ATTR, MEMBER, MASK) \
+#define STATX_GET_ULONGLONG(ATTR, MASK) \
     static PyObject* \
     pystatx_result_get_##ATTR(PyObject *op, void *Py_UNUSED(context)) \
     { \
@@ -3394,18 +3389,18 @@ STATX_GET_UINT(stx_atomic_write_unit_max_opt, stx_atomic_write_unit_max_opt,
         if (!(self->stx.stx_mask & MASK)) { \
             Py_RETURN_NONE; \
         } \
-        unsigned long long value = self->stx.MEMBER; \
+        unsigned long long value = self->stx.ATTR; \
         return PyLong_FromUnsignedLongLong(value); \
     }
 
-STATX_GET_ULONGLONG(st_blocks, stx_blocks, STATX_BLOCKS)
-STATX_GET_ULONGLONG(st_ino, stx_ino, STATX_INO)
-STATX_GET_ULONGLONG(st_size, stx_size, STATX_SIZE)
+STATX_GET_ULONGLONG(stx_blocks, STATX_BLOCKS)
+STATX_GET_ULONGLONG(stx_ino, STATX_INO)
+STATX_GET_ULONGLONG(stx_size, STATX_SIZE)
 #ifdef HAVE_STRUCT_STATX_STX_MNT_ID
-STATX_GET_ULONGLONG(stx_mnt_id, stx_mnt_id, STATX_MNT_ID)
+STATX_GET_ULONGLONG(stx_mnt_id, STATX_MNT_ID)
 #endif
 #ifdef HAVE_STRUCT_STATX_STX_SUBVOL
-STATX_GET_ULONGLONG(stx_subvol, stx_subvol, STATX_SUBVOL)
+STATX_GET_ULONGLONG(stx_subvol, STATX_SUBVOL)
 #endif
 
 
@@ -3421,10 +3416,10 @@ STATX_GET_ULONGLONG(stx_subvol, stx_subvol, STATX_SUBVOL)
         return PyFloat_FromDouble(sec); \
     }
 
-STATX_GET_DOUBLE(st_atime, atime_sec, STATX_ATIME)
-STATX_GET_DOUBLE(st_birthtime, btime_sec, STATX_BTIME)
-STATX_GET_DOUBLE(st_ctime, ctime_sec, STATX_CTIME)
-STATX_GET_DOUBLE(st_mtime, mtime_sec, STATX_MTIME)
+STATX_GET_DOUBLE(stx_atime, atime_sec, STATX_ATIME)
+STATX_GET_DOUBLE(stx_btime, btime_sec, STATX_BTIME)
+STATX_GET_DOUBLE(stx_ctime, ctime_sec, STATX_CTIME)
+STATX_GET_DOUBLE(stx_mtime, mtime_sec, STATX_MTIME)
 
 #define STATX_GET_NSEC(ATTR, MEMBER, MASK) \
     static PyObject* \
@@ -3440,29 +3435,29 @@ STATX_GET_DOUBLE(st_mtime, mtime_sec, STATX_MTIME)
         return stat_nanosecond_timestamp(state, ts->tv_sec, ts->tv_nsec); \
     }
 
-STATX_GET_NSEC(st_atime_ns, stx_atime, STATX_ATIME)
-STATX_GET_NSEC(st_birthtime_ns, stx_btime, STATX_BTIME)
-STATX_GET_NSEC(st_ctime_ns, stx_ctime, STATX_CTIME)
-STATX_GET_NSEC(st_mtime_ns, stx_mtime, STATX_MTIME)
+STATX_GET_NSEC(stx_atime_ns, stx_atime, STATX_ATIME)
+STATX_GET_NSEC(stx_btime_ns, stx_btime, STATX_BTIME)
+STATX_GET_NSEC(stx_ctime_ns, stx_ctime, STATX_CTIME)
+STATX_GET_NSEC(stx_mtime_ns, stx_mtime, STATX_MTIME)
 
 #define G(attr, doc) \
     {#attr, pystatx_result_get_##attr, NULL, PyDoc_STR(doc), NULL}
 
 static PyGetSetDef pystatx_result_getset[] = {
-    G(st_nlink, "number of hard links"),
-    G(st_uid, "user ID of owner"),
-    G(st_gid, "group ID of owner"),
-    G(st_ino, "inode"),
-    G(st_size, "total size, in bytes"),
-    G(st_blocks, "number of blocks allocated"),
-    G(st_atime, "time of last access"),
-    G(st_atime_ns, "time of last access in nanoseconds"),
-    G(st_birthtime, "time of creation"),
-    G(st_birthtime_ns, "time of creation in nanoseconds"),
-    G(st_ctime, "time of last change"),
-    G(st_ctime_ns, "time of last change in nanoseconds"),
-    G(st_mtime, "time of last modification"),
-    G(st_mtime_ns, "time of last modification in nanoseconds"),
+    G(stx_nlink, "number of hard links"),
+    G(stx_uid, "user ID of owner"),
+    G(stx_gid, "group ID of owner"),
+    G(stx_ino, "inode"),
+    G(stx_size, "total size, in bytes"),
+    G(stx_blocks, "number of blocks allocated"),
+    G(stx_atime, "time of last access"),
+    G(stx_atime_ns, "time of last access in nanoseconds"),
+    G(stx_btime, "time of creation"),
+    G(stx_btime_ns, "time of creation in nanoseconds"),
+    G(stx_ctime, "time of last change"),
+    G(stx_ctime_ns, "time of last change in nanoseconds"),
+    G(stx_mtime, "time of last modification"),
+    G(stx_mtime_ns, "time of last modification in nanoseconds"),
 #ifdef HAVE_STRUCT_STATX_STX_MNT_ID
     G(stx_mnt_id, "mount ID"),
 #endif