Skip to content

Commit 51ef6cc

Browse files
jbosboomvstinner
andcommitted
Apply suggestions from code review
Co-authored-by: Victor Stinner <[email protected]>
1 parent a1110f3 commit 51ef6cc

File tree

9 files changed

+147
-97
lines changed

9 files changed

+147
-97
lines changed

Doc/library/os.rst

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3383,7 +3383,7 @@ features:
33833383
Added the :attr:`st_birthtime` member on Windows.
33843384

33853385

3386-
.. function:: statx(path, mask, *, dir_fd=None, follow_symlinks=True, sync=None)
3386+
.. function:: statx(path, mask, flags=0, *, dir_fd=None, follow_symlinks=True)
33873387

33883388
Get the status of a file or file descriptor by performing a :c:func:`!statx`
33893389
system call on the given path.
@@ -3392,18 +3392,12 @@ features:
33923392
indirectly through the :class:`PathLike` interface -- or as an open file
33933393
descriptor. *mask* is a combination of the module-level
33943394
:const:`STATX_* <STATX_TYPE>` constants specifying the information to
3395-
retrieve. Returns a :class:`statx_result` object whose
3395+
retrieve. *flags* is a combination of the module-level
3396+
:const:`AT_STATX_* <AT_STATX_FORCE_SYNC>` constants and/or
3397+
:const:`AT_NO_AUTOMOUNT`. Returns a :class:`statx_result` object whose
33963398
:attr:`~os.statx_result.stx_mask` attribute specifies the information
33973399
actually retrieved (which may differ from *mask*).
33983400

3399-
The optional parameter *sync* controls the freshness of the returned
3400-
information. ``sync=True`` requests that the kernel return up-to-date
3401-
information, even when doing so is expensive (for example, requiring a
3402-
round trip to the server for a file on a network filesystem).
3403-
``sync=False`` requests that the kernel return cached information if
3404-
available. ``sync=None`` expresses no preference, in which case the kernel
3405-
will return information as fresh as :func:`~os.stat` does.
3406-
34073401
This function supports :ref:`specifying a file descriptor <path_fd>`,
34083402
:ref:`paths relative to directory descriptors <dir_fd>`, and
34093403
:ref:`not following symlinks <follow_symlinks>`.
@@ -3515,6 +3509,49 @@ features:
35153509

35163510
.. versionadded:: next
35173511

3512+
.. data:: AT_STATX_FORCE_SYNC
3513+
3514+
A flag for the :func:`os.statx` function. Requests that the kernel return
3515+
up-to-date information even when doing so is expensive (for example,
3516+
requiring a round trip to the server for a file on a network filesystem).
3517+
3518+
.. availability:: Linux >= 4.11 with glibc >= 2.28.
3519+
3520+
.. versionadded:: next
3521+
3522+
.. data:: AT_STATX_DONT_SYNC
3523+
3524+
A flag for the :func:`os.statx` function. Requests that the kernel return
3525+
cached information if possible.
3526+
3527+
.. availability:: Linux >= 4.11 with glibc >= 2.28.
3528+
3529+
.. versionadded:: next
3530+
3531+
.. data:: AT_STATX_SYNC_AS_STAT
3532+
3533+
A flag for the :func:`os.statx` function. This flag is defined as ``0``, so
3534+
it has no effect, but it can be used to explicitly indicate neither
3535+
:data:`AT_STATX_FORCE_SYNC` nor :data:`AT_STATX_DONT_SYNC` is being passed.
3536+
In the absence of the other two flags, the kernel will generally return
3537+
information as fresh as :func:`os.stat` would return.
3538+
3539+
.. availability:: Linux >= 4.11 with glibc >= 2.28.
3540+
3541+
.. versionadded:: next
3542+
3543+
3544+
.. data:: AT_NO_AUTOMOUNT
3545+
3546+
If the final component of a path is an automount point, operate on the
3547+
automount point instead of performing the automount. (On Linux,
3548+
:func:`os.stat`, :func:`os.fstat` and :func:`os.lstat` always behave this
3549+
way.)
3550+
3551+
.. availability:: Linux.
3552+
3553+
.. versionadded:: next
3554+
35183555

35193556
.. function:: statvfs(path)
35203557

Include/internal/pycore_global_objects_fini_generated.h

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_global_strings.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -785,7 +785,6 @@ struct _Py_global_strings {
785785
STRUCT_FOR_ID(sub_key)
786786
STRUCT_FOR_ID(subcalls)
787787
STRUCT_FOR_ID(symmetric_difference_update)
788-
STRUCT_FOR_ID(sync)
789788
STRUCT_FOR_ID(tabsize)
790789
STRUCT_FOR_ID(tag)
791790
STRUCT_FOR_ID(target)

Include/internal/pycore_runtime_init_generated.h

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_unicodeobject_generated.h

Lines changed: 0 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/test/test_os.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -812,14 +812,6 @@ def test_statx_attributes_bytes(self):
812812
def test_statx_attributes_pathlike(self):
813813
self.check_statx_attributes(FakePath(self.fname))
814814

815-
@unittest.skipUnless(hasattr(os, 'statx'), 'test needs os.statx()')
816-
def test_statx_sync(self):
817-
# Test sync= kwarg parsing. (We can't predict if or how the result
818-
# will change.)
819-
for sync in (False, True):
820-
with self.subTest(sync=sync):
821-
os.statx(self.fname, os.STATX_BASIC_STATS, sync=sync)
822-
823815
@unittest.skipUnless(hasattr(os, 'statvfs'), 'test needs os.statvfs()')
824816
def test_statvfs_attributes(self):
825817
result = os.statvfs(self.fname)

Lib/test/test_posix.py

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -668,22 +668,65 @@ def test_fstat(self):
668668
finally:
669669
fp.close()
670670

671-
def test_stat(self):
672-
self.assertTrue(posix.stat(os_helper.TESTFN))
673-
self.assertTrue(posix.stat(os.fsencode(os_helper.TESTFN)))
671+
def check_statlike_path(self, func):
672+
self.assertTrue(func(os_helper.TESTFN))
673+
self.assertTrue(func(os.fsencode(os_helper.TESTFN)))
674+
self.assertTrue(func(os_helper.FakePath(os_helper.TESTFN)))
674675

675676
self.assertRaisesRegex(TypeError,
676677
'should be string, bytes, os.PathLike or integer, not',
677-
posix.stat, bytearray(os.fsencode(os_helper.TESTFN)))
678+
func, bytearray(os.fsencode(os_helper.TESTFN)))
678679
self.assertRaisesRegex(TypeError,
679680
'should be string, bytes, os.PathLike or integer, not',
680-
posix.stat, None)
681+
func, None)
681682
self.assertRaisesRegex(TypeError,
682683
'should be string, bytes, os.PathLike or integer, not',
683-
posix.stat, list(os_helper.TESTFN))
684+
func, list(os_helper.TESTFN))
684685
self.assertRaisesRegex(TypeError,
685686
'should be string, bytes, os.PathLike or integer, not',
686-
posix.stat, list(os.fsencode(os_helper.TESTFN)))
687+
func, list(os.fsencode(os_helper.TESTFN)))
688+
689+
def test_stat(self):
690+
self.check_statlike_path(posix.stat)
691+
692+
@unittest.skipUnless(hasattr(posix, 'statx'), 'test needs posix.statx()')
693+
def test_statx(self):
694+
def func(path, **kwargs):
695+
return posix.statx(path, posix.STATX_BASIC_STATS, **kwargs)
696+
self.check_statlike_path(func)
697+
698+
@unittest.skipUnless(hasattr(posix, 'statx'), 'test needs posix.statx()')
699+
def test_statx_flags(self):
700+
# glibc's fallback implementation of statx via the stat family fails
701+
# with EINVAL on the (nonzero) sync flags. If you see this failure,
702+
# update your kernel and/or seccomp syscall filter.
703+
valid_flag_names = ('AT_NO_AUTOMOUNT', 'AT_STATX_SYNC_AS_STAT',
704+
'AT_STATX_FORCE_SYNC', 'AT_STATX_DONT_SYNC')
705+
for flag_name in valid_flag_names:
706+
flag = getattr(posix, flag_name)
707+
with self.subTest(msg=flag_name, flags=flag):
708+
posix.statx(os_helper.TESTFN, posix.STATX_BASIC_STATS,
709+
flags=flag)
710+
711+
# These flags are not exposed to Python because their functionality is
712+
# implemented via kwargs instead.
713+
kwarg_equivalent_flags = (
714+
(0x0100, 'AT_SYMLINK_NOFOLLOW', 'follow_symlinks'),
715+
(0x0400, 'AT_SYMLINK_FOLLOW', 'follow_symlinks'),
716+
(0x1000, 'AT_EMPTY_PATH', 'dir_fd'),
717+
)
718+
for flag, flag_name, kwarg_name in kwarg_equivalent_flags:
719+
with self.subTest(msg=flag_name, flags=flag):
720+
with self.assertRaisesRegex(ValueError, kwarg_name):
721+
posix.statx(os_helper.TESTFN, posix.STATX_BASIC_STATS,
722+
flags=flag)
723+
724+
with self.subTest(msg="AT_STATX_FORCE_SYNC | AT_STATX_DONT_SYNC"):
725+
with self.assertRaises(OSError) as ctx:
726+
flags = posix.AT_STATX_FORCE_SYNC | posix.AT_STATX_DONT_SYNC
727+
posix.statx(os_helper.TESTFN, posix.STATX_BASIC_STATS,
728+
flags=flags)
729+
self.assertEqual(ctx.exception.errno, errno.EINVAL)
687730

688731
@unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
689732
def test_mkfifo(self):

Modules/clinic/posixmodule.c.h

Lines changed: 23 additions & 20 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)