8000 gh-99726: Adds os.statx function and associated constants by zooba · Pull Request #99755 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-99726: Adds os.statx function and associated constants #99755

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

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
6f7e9fa
gh-99726: Adds os.statx function and associated constants
zooba Nov 24, 2022
21b5f50
Update configure
zooba Nov 24, 2022
8fd982e
Fix POSIX build issues
zooba Nov 24, 2022
2b85372
Revert unrelated pyconfig.h.in changes
zooba Nov 24, 2022
a813f84
Revert generated files
zooba Nov 24, 2022
5a6ce8e
Update pyconfig.h.in
zooba Nov 24, 2022
6f54522
Fixup configure
zooba Nov 24, 2022
cda6886
Fix docs
zooba Nov 24, 2022
0db9341
Check for STATX_MNT_ID
zooba Nov 24, 2022
e278102
Properly exclude statx
zooba Nov 24, 2022
7844111
Add missing fields
zooba Nov 24, 2022
a787ae7
More field initialization
zooba Nov 24, 2022
b1182c3
More uninitialised fields
zooba Nov 24, 2022
cc5a159
endif
zooba Nov 24, 2022
ce24e79
Switch to less-confusing conditional attributes. Other fixes
zooba Nov 25, 2022
4a6e5ee
Few fixes
zooba Nov 25, 2022
7835bde
Make init config tests more reliable on Windows builds
zooba Nov 25, 2022
64111f4
Merge remote-tracking branch 'cpython/main' into gh-99726
zooba Nov 25, 2022
d53c013
Merge remote-tracking branch 'cpython/main' into gh-99726
zooba Nov 28, 2022
991876d
Update DeviceType check and rest of stdlib
zooba Nov 28, 2022
2d90f4d
Fix refleak and tests
zooba Nov 28, 2022
a6d3386
More test fixes
zooba Nov 28, 2022
ed5f370
Fix os.statx assumption
zooba Nov 28, 2022
4e95220
Documentation improvements
zooba Nov 29, 2022
3cc69aa
Missed one doc change
zooba Nov 29, 2022
025a4e6
Nope, it was applied fine
zooba Nov 29, 2022
8ee94aa
Handle block devices better
zooba Nov 29, 2022
bbcc6ee
Put statx in correct os sets, and include in pythoninfo
zooba Nov 29, 2022
768ba42
Merge remote-tracking branch 'cpython/main' into gh-99726
zooba Dec 5, 2022
cadeecb
Merge branch 'main' into gh-99726
carljm Dec 15, 2022
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
Prev Previous commit
Next Next commit
Few fixes
  • Loading branch information
zooba committed Nov 25, 2022
commit 4a6e5ee51c01106719e51a93c896ef337db74602
32 changes: 10 additions & 22 deletions Doc/library/os.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1841,6 +1841,16 @@ features:
function on your platform using :data:`os.supports_follow_symlinks`.
If it's unavailable, using it will raise a :exc:`NotImplementedError`.

On Windows, ``follow_symlinks`` applies to name-surrogate reparse points,
including symlinks and junctions. This type of reparse point is a symbolic
link to another path on the system. All other types of reparse point (e.g.
tiered storage) are always traversed, except that reparse points that are
not supported by the system are operated on directly.

If a path is either a symlink or a junction that cannot be traversed to the
final path, :func:`os.path.realpath` can be used to resolve as much of the
target path as possible.



.. function:: access(path, mode, *, dir_fd=None, effective_ids=False, follow_symlinks=True)
Expand Down Expand Up @@ -2795,17 +2805,6 @@ features:
This function can support :ref:`specifying a file descriptor <path_fd>` and
:ref:`not following symlinks <follow_symlinks>`.

On Windows, passing ``follow_symlinks=False`` will disable following all
name-surrogate reparse points, which includes symlinks and directory
junctions. Other types of reparse points that do not resemble links or that
the operating system is unable to follow will be opened directly. When
following a chain of multiple links, this may result in the original link
being returned instead of the non-link that prevented full traversal. To
obtain stat results for the final path in this case, use the
:func:`os.path.realpath` function to resolve the path name as far as
possible and call :func:`lstat` on the result. This does not apply to
dangling symlinks or junction points, which will raise the usual exceptions.

.. index:: module: stat

Example::
Expand Down Expand Up @@ -2859,17 +2858,6 @@ features:
This function can support :ref:`specifying a file descriptor <path_fd>` and
:ref:`not following symlinks <follow_symlinks>`.

On Windows, passing ``follow_symlinks=False`` will disable following all
name-surrogate reparse points, which includes symlinks and directory
junctions. Other types of reparse points that do not resemble links or that
the operating system is unable to follow will be opened directly. When
following a chain of multiple links, this may result in the original link
being returned instead of the non-link that prevented full traversal. To
obtain stat results for the final path in this case, use the
:func:`os.path.realpath` function to resolve the path name as far as
possible and call :func:`lstat` on the result. This does not apply to
dangling symlinks or junction points, which will raise the usual exceptions.

.. index:: module: stat

Example::
Expand Down
21 changes: 13 additions & 8 deletions Modules/posixmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -2189,7 +2189,7 @@ static PyStructSequence_Field stat_result_fields[] = {
#endif
/* the stx_mask attribute is always present to allow for fallbacks */
{"stx_mask", "mask of fields provided by the system"},
#ifdef HAVE_STATX
#if defined(HAVE_STATX) || defined(MS_WINDOWS)
/* Many of these are duplicates of the optional fields earlier.
*Presumably* they'll all be present together, but since people
test for the presence of the st_* fields by name at .py compile
Expand Down Expand Up @@ -2266,7 +2266,7 @@ static PyStructSequence_Field stat_result_fields[] = {

#define STX_MASK_IDX (ST_REPARSE_TAG_IDX+1)

#ifdef HAVE_STATX
#if defined(HAVE_STATX) || defined(MS_WINDOWS)
#define STX_BLKSIZE_IDX (STX_MASK_IDX+1)
#define STX_BLOCKS_IDX (STX_BLKSIZE_IDX+1)
#define STX_RDEV_IDX (STX_BLOCKS_IDX+1)
Expand Down Expand Up @@ -2466,12 +2466,11 @@ fill_time(PyObject *module, PyObject *v, int index, int index_f, int index_ns, t
}

if (index >= 0)
PyStructSequence_SET_ITEM(v, index, s);
PyStructSequence_SET_ITEM(v, index, Py_NewRef(s));
if (float_s)
PyStructSequence_SET_ITEM(v, index_f, float_s);
if (ns_total)
PyStructSequence_SET_ITEM(v, index_ns, ns_total);
s = NULL;
float_s = NULL;
ns_total = NULL;
exit:
Expand Down Expand Up @@ -2549,7 +2548,7 @@ _pystat_fromstructstat(PyObject *module, STRUCT_STAT *st, unsigned int stx_mask)
PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
PyLong_FromLong((long)st->st_gen));
#endif
#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIME) || defined(MS_WINDOWS)
{
time_t bsec;
unsigned long bnsec;
Expand All @@ -2564,8 +2563,10 @@ _pystat_fromstructstat(PyObject *module, STRUCT_STAT *st, unsigned int stx_mask)
bnsec = 0;
#endif /* HAVE_STAT_TV_NSEC2 */
#endif /* MS_WINDOWS */
#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
fill_time(module, v, -1, ST_BIRTHTIME_IDX, -1, bsec, bnsec);
#ifdef HAVE_STATX
#endif
#if defined(HAVE_STATX) || defined(MS_WINDOWS)
fill_time(module, v, -1, STX_BTIME_IDX, STX_BTIME_NS_IDX, bsec, bnsec);
#endif
}
Expand Down Expand Up @@ -2593,7 +2594,7 @@ _pystat_fromstructstat(PyObject *module, STRUCT_STAT *st, unsigned int stx_mask)
PyStructSequence_SET_ITEM(v, STX_MASK_IDX,
PyLong_FromUnsignedLong(stx_mask));

#ifdef HAVE_STATX
#if defined(HAVE_STATX) || defined(MS_WINDOWS)
/* ensure unused fields that are present for statx are initialized */
PyObject *zero = PyLong_FromLong(0);
if (!zero) {
Expand Down Expand Up @@ -2668,7 +2669,7 @@ _pystat_fromstructstatx(PyObject *module, struct statx *st)
fill_time(module, v, 7, 10, 13, st->stx_atime.tv_sec, st->stx_atime.tv_nsec);
fill_time(module, v, 8, 11, 14, st->stx_mtime.tv_sec, st->stx_mtime.tv_nsec);
fill_time(module, v, 9, 12, 15, st->stx_ctime.tv_sec, st->stx_ctime.tv_nsec);
fill_time(module, v, -1, ST_BTIME_IDX, ST_BTIME_NS_IDX,
fill_time(module, v, -1, STX_BTIME_IDX, STX_BTIME_NS_IDX,
st->stx_btime.tv_sec, st->stx_btime.tv_nsec);

PyStructSequence_SET_ITEM(v, STX_BLKSIZE_IDX,
Expand Down Expand Up @@ -16263,6 +16264,10 @@ static const struct have_function {
{ "HAVE_RENAMEAT", probe_renameat },
#endif

#if defined(HAVE_STATX) || defined(MS_WINDOWS)
{ "HAVE_STATX", NULL },
#endif

#ifdef HAVE_SYMLINKAT
{ "HAVE_SYMLINKAT", probe_symlinkat },
#endif
Expand Down
6 changes: 2 additions & 4 deletions Python/fileutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -1114,10 +1114,8 @@ _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag,
result->st_reparse_tag = reparse_tag;
if (info->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT &&
reparse_tag == IO_REPARSE_TAG_SYMLINK) {
/* first clear the S_IFMT bits */
result->st_mode ^= (result->st_mode & S_IFMT);
/* now set the bits that make this a symlink */
result->st_mode |= S_IFLNK;
/* set the bits that make this a symlink */
result->st_mode = (result->st_mode & ~S_IFMT) | S_IFLNK;
}
result->st_file_attributes = info->dwFileAttributes;
}
Expand Down
0