Skip to content

Commit 93cdcb4

Browse files
jbosboomcmaloney
andcommitted
Apply suggestions from code review
Co-authored-by: Cody Maloney <cmaloney@users.noreply.github.com>
1 parent 08af0a1 commit 93cdcb4

File tree

3 files changed

+42
-24
lines changed

3 files changed

+42
-24
lines changed

Doc/library/os.rst

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3411,35 +3411,46 @@ features:
34113411

34123412
.. class:: statx_result
34133413

3414-
Object whose attributes correspond roughly to the members of the
3415-
:c:struct:`!statx` structure. It is used for the result of :func:`os.statx`.
3416-
:class:`!statx_result` has all of the attributes of :class:`stat_result`
3417-
available on Linux, but is not a subclass of :class:`stat_result` nor a
3418-
tuple. :class:`!statx_result` has the following additional attributes:
3414+
Information about a file returned by :func:`os.statx`.
3415+
3416+
:class:`!statx_result` has all the attributes that :class:`~stat_result` has
3417+
on Linux, making it :term:`duck-typing` compatible, but
3418+
:class:`!statx_result` is not a subclass of :class:`~stat_result` and cannot
3419+
be used as a tuple.
3420+
3421+
:class:`!statx_result` has the following additional attributes:
34193422

34203423
.. attribute:: stx_mask
34213424

34223425
Bitmask of :const:`STATX_* <STATX_TYPE>` constants specifying the
3423-
information retrieved, which may differ from what was requested depending
3424-
on the filesystem, filesystem type, and kernel version. All attributes
3425-
of this class are accessible regardless of the value of
3426-
:attr:`!stx_mask`, and they may have useful fictitious values. For
3427-
example, for a file on a network filesystem, :const:`STATX_UID` and
3428-
:const:`STATX_GID` may be unset because file ownership on the server is
3429-
based on an external user database, but :attr:`!st_uid` and
3430-
:attr:`!st_gid` may contain the IDs of the local user who controls the
3431-
mount.
3426+
information retrieved, which may differ from what was requested.
34323427

34333428
.. attribute:: stx_attributes_mask
34343429

3435-
Bitmask of :const:`!STATX_ATTR_* <stat.STATX_ATTR_COMPRESSED>` constants
3430+
Bitmask of :const:`STATX_ATTR_* <stat.STATX_ATTR_COMPRESSED>` constants
34363431
specifying the attributes bits supported for this file.
34373432

34383433
.. attribute:: stx_attributes
34393434

3440-
Bitmask of :const:`!STATX_ATTR_* <stat.STATX_ATTR_COMPRESSED>` constants
3435+
Bitmask of :const:`STATX_ATTR_* <stat.STATX_ATTR_COMPRESSED>` constants
34413436
specifying the attributes of this file.
34423437

3438+
.. attribute:: stx_dev_major
3439+
3440+
Major number of the device on which this file resides.
3441+
3442+
.. attribute:: stx_dev_minor
3443+
3444+
Minor number of the device on which this file resides.
3445+
3446+
.. attribute:: stx_rdev_major
3447+
3448+
Major number of the device this file represents.
3449+
3450+
.. attribute:: stx_rdev_minor
3451+
3452+
Minor number of the device this file represents.
3453+
34433454
.. attribute:: stx_mnt_id
34443455

34453456
Mount ID.

Lib/test/test_os/test_os.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,7 @@ def check_statx_attributes(self, fname):
764764
if result.stx_mask & bits == bits and hasattr(basic_result, name):
765765
x = getattr(result, name)
766766
b = getattr(basic_result, name)
767+
self.assertEqual(type(x), type(b))
767768
if isinstance(x, float):
768769
self.assertAlmostEqual(x, b, msg=name)
769770
else:
@@ -786,6 +787,12 @@ def check_statx_attributes(self, fname):
786787
self.assertEqual(result.stx_attributes & result.stx_attributes_mask,
787788
result.stx_attributes)
788789

790+
# statx_result is not a tuple or tuple-like object.
791+
with self.assertRaisesRegex(TypeError, 'not subscriptable'):
792+
result[0]
793+
with self.assertRaisesRegex(TypeError, 'cannot unpack'):
794+
_, _ = result
795+
789796
@unittest.skipUnless(hasattr(os, 'statx'), 'test needs os.statx()')
790797
def test_statx_attributes(self):
791798
self.check_statx_attributes(self.fname)

Modules/posixmodule.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2632,6 +2632,7 @@ stat_nanosecond_timestamp(_posixstate *state, time_t sec, unsigned long nsec)
26322632
return PyLong_FromLongLong(sec * SEC_TO_NS + nsec);
26332633
}
26342634
else {
2635+
PyObject *ns_total = NULL;
26352636
PyObject *s_in_ns = NULL;
26362637
PyObject *s = _PyLong_FromTime_t(sec);
26372638
PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
@@ -2644,17 +2645,13 @@ stat_nanosecond_timestamp(_posixstate *state, time_t sec, unsigned long nsec)
26442645
goto exit;
26452646
}
26462647

2647-
PyObject *ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2648-
if (ns_total == NULL) {
2649-
goto exit;
2650-
}
2651-
return ns_total;
2648+
ns_total = PyNumber_Add(s_in_ns, ns_fractional);
26522649

26532650
exit:
26542651
Py_XDECREF(s);
26552652
Py_XDECREF(ns_fractional);
26562653
Py_XDECREF(s_in_ns);
2657-
return NULL;
2654+
return ns_total;
26582655
}
26592656
}
26602657

@@ -3336,7 +3333,7 @@ static PyMemberDef pystatx_result_members[] = {
33363333
MM(st_size, Py_T_ULONGLONG, size, "total size, in bytes"),
33373334
MM(st_blocks, Py_T_ULONGLONG, blocks, "number of blocks allocated"),
33383335
MM(stx_attributes_mask, Py_T_ULONGLONG, attributes_mask,
3339-
"Linux inode attribute bits supported for this file"),
3336+
"Mask of supported bits in stx_attributes"),
33403337
MX(st_atime, Py_T_DOUBLE, atime_sec, "time of last access"),
33413338
MX(st_birthtime, Py_T_DOUBLE, btime_sec, "time of creation"),
33423339
MX(st_ctime, Py_T_DOUBLE, ctime_sec, "time of last change"),
@@ -3366,6 +3363,7 @@ pystatx_result_get_u32(PyObject *op, void *context) {
33663363
Py_statx_result *self = (Py_statx_result *) op;
33673364
uint16_t offset = (uintptr_t)context;
33683365
uint32_t val;
3366+
assert(offset + sizeof(val) <= sizeof(Py_statx_result));
33693367
memcpy(&val, (void *)self + offset, sizeof(val));
33703368
return PyLong_FromUInt32(val);
33713369
}
@@ -3376,6 +3374,7 @@ pystatx_result_get_nsec(PyObject *op, void *context)
33763374
Py_statx_result *self = (Py_statx_result *) op;
33773375
uint16_t offset = (uintptr_t)context;
33783376
struct statx_timestamp val;
3377+
assert(offset + sizeof(val) <= sizeof(Py_statx_result));
33793378
memcpy(&val, (void *)self + offset, sizeof(val));
33803379
_posixstate *state = PyType_GetModuleState(Py_TYPE(op));
33813380
assert(state != NULL);
@@ -3561,8 +3560,9 @@ os_statx_impl(PyObject *module, path_t *path, unsigned int mask, int flags,
35613560
{
35623561
if (path_and_dir_fd_invalid("statx", path, dir_fd) ||
35633562
dir_fd_and_fd_invalid("statx", dir_fd, path->fd) ||
3564-
fd_and_follow_symlinks_invalid("statx", path->fd, follow_symlinks))
3563+
fd_and_follow_symlinks_invalid("statx", path->fd, follow_symlinks)) {
35653564
return NULL;
3565+
}
35663566

35673567
/* reject flags covered by kwargs, but allow unknown flags that may be
35683568
future AT_STATX_* extensions */

0 commit comments

Comments
 (0)