mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
gh-83714: Set os.statx() members to None if missing from stx_mask (#140216)
This commit is contained in:
parent
237dca52ba
commit
3222ea0f14
2 changed files with 176 additions and 71 deletions
|
|
@ -3451,7 +3451,10 @@ features:
|
||||||
|
|
||||||
.. attribute:: stx_mnt_id
|
.. attribute:: stx_mnt_id
|
||||||
|
|
||||||
Mount ID.
|
Mount identifier.
|
||||||
|
|
||||||
|
Equal to ``None`` if :data:`STATX_MNT_ID` is missing from
|
||||||
|
:attr:`~os.statx_result.stx_mask`.
|
||||||
|
|
||||||
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
|
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
|
||||||
userspace API headers >= 5.8.
|
userspace API headers >= 5.8.
|
||||||
|
|
@ -3460,6 +3463,9 @@ features:
|
||||||
|
|
||||||
Direct I/O memory buffer alignment requirement.
|
Direct I/O memory buffer alignment requirement.
|
||||||
|
|
||||||
|
Equal to ``None`` if :data:`STATX_DIOALIGN` is missing from
|
||||||
|
:attr:`~os.statx_result.stx_mask`.
|
||||||
|
|
||||||
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
|
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
|
||||||
userspace API headers >= 6.1.
|
userspace API headers >= 6.1.
|
||||||
|
|
||||||
|
|
@ -3467,12 +3473,18 @@ features:
|
||||||
|
|
||||||
Direct I/O file offset alignment requirement.
|
Direct I/O file offset alignment requirement.
|
||||||
|
|
||||||
|
Equal to ``None`` if :data:`STATX_DIOALIGN` is missing from
|
||||||
|
:attr:`~os.statx_result.stx_mask`.
|
||||||
|
|
||||||
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
|
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
|
||||||
userspace API headers >= 6.1.
|
userspace API headers >= 6.1.
|
||||||
|
|
||||||
.. attribute:: stx_subvol
|
.. attribute:: stx_subvol
|
||||||
|
|
||||||
Subvolume ID.
|
Subvolume identifier.
|
||||||
|
|
||||||
|
Equal to ``None`` if :data:`STATX_SUBVOL` is missing from
|
||||||
|
:attr:`~os.statx_result.stx_mask`.
|
||||||
|
|
||||||
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
|
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
|
||||||
userspace API headers >= 6.10.
|
userspace API headers >= 6.10.
|
||||||
|
|
@ -3481,6 +3493,9 @@ features:
|
||||||
|
|
||||||
Minimum size for direct I/O with torn-write protection.
|
Minimum size for direct I/O with torn-write protection.
|
||||||
|
|
||||||
|
Equal to ``None`` if :data:`STATX_WRITE_ATOMIC` is missing from
|
||||||
|
:attr:`~os.statx_result.stx_mask`.
|
||||||
|
|
||||||
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
|
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
|
||||||
userspace API headers >= 6.11.
|
userspace API headers >= 6.11.
|
||||||
|
|
||||||
|
|
@ -3488,6 +3503,9 @@ features:
|
||||||
|
|
||||||
Maximum size for direct I/O with torn-write protection.
|
Maximum size for direct I/O with torn-write protection.
|
||||||
|
|
||||||
|
Equal to ``None`` if :data:`STATX_WRITE_ATOMIC` is missing from
|
||||||
|
:attr:`~os.statx_result.stx_mask`.
|
||||||
|
|
||||||
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
|
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
|
||||||
userspace API headers >= 6.11.
|
userspace API headers >= 6.11.
|
||||||
|
|
||||||
|
|
@ -3495,6 +3513,9 @@ features:
|
||||||
|
|
||||||
Maximum optimized size for direct I/O with torn-write protection.
|
Maximum optimized size for direct I/O with torn-write protection.
|
||||||
|
|
||||||
|
Equal to ``None`` if :data:`STATX_WRITE_ATOMIC` is missing from
|
||||||
|
:attr:`~os.statx_result.stx_mask`.
|
||||||
|
|
||||||
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
|
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
|
||||||
userspace API headers >= 6.16.
|
userspace API headers >= 6.16.
|
||||||
|
|
||||||
|
|
@ -3502,6 +3523,9 @@ features:
|
||||||
|
|
||||||
Maximum iovecs for direct I/O with torn-write protection.
|
Maximum iovecs for direct I/O with torn-write protection.
|
||||||
|
|
||||||
|
Equal to ``None`` if :data:`STATX_WRITE_ATOMIC` is missing from
|
||||||
|
:attr:`~os.statx_result.stx_mask`.
|
||||||
|
|
||||||
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
|
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
|
||||||
userspace API headers >= 6.11.
|
userspace API headers >= 6.11.
|
||||||
|
|
||||||
|
|
@ -3509,6 +3533,9 @@ features:
|
||||||
|
|
||||||
Direct I/O file offset alignment requirement for reads.
|
Direct I/O file offset alignment requirement for reads.
|
||||||
|
|
||||||
|
Equal to ``None`` if :data:`STATX_DIO_READ_ALIGN` is missing from
|
||||||
|
:attr:`~os.statx_result.stx_mask`.
|
||||||
|
|
||||||
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
|
.. availability:: Linux >= 4.11 with glibc >= 2.28 and build-time kernel
|
||||||
userspace API headers >= 6.14.
|
userspace API headers >= 6.14.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3319,6 +3319,8 @@ typedef struct {
|
||||||
struct statx stx;
|
struct statx stx;
|
||||||
} Py_statx_result;
|
} Py_statx_result;
|
||||||
|
|
||||||
|
#define Py_statx_result_CAST(op) _Py_CAST(Py_statx_result*, (op))
|
||||||
|
|
||||||
#define M(attr, type, offset, doc) \
|
#define M(attr, type, offset, doc) \
|
||||||
{attr, type, offset, Py_READONLY, PyDoc_STR(doc)}
|
{attr, type, offset, Py_READONLY, PyDoc_STR(doc)}
|
||||||
#define MM(attr, type, member, doc) \
|
#define MM(attr, type, member, doc) \
|
||||||
|
|
@ -3330,53 +3332,15 @@ static PyMemberDef pystatx_result_members[] = {
|
||||||
MM(stx_mask, Py_T_UINT, mask, "member validity mask"),
|
MM(stx_mask, Py_T_UINT, mask, "member validity mask"),
|
||||||
MM(st_blksize, Py_T_UINT, blksize, "blocksize for filesystem I/O"),
|
MM(st_blksize, Py_T_UINT, blksize, "blocksize for filesystem I/O"),
|
||||||
MM(stx_attributes, Py_T_ULONGLONG, attributes, "Linux inode attribute bits"),
|
MM(stx_attributes, Py_T_ULONGLONG, attributes, "Linux inode attribute bits"),
|
||||||
MM(st_nlink, Py_T_UINT, nlink, "number of hard links"),
|
|
||||||
MM(st_uid, Py_T_UINT, uid, "user ID of owner"),
|
|
||||||
MM(st_gid, Py_T_UINT, gid, "group ID of owner"),
|
|
||||||
MM(st_mode, Py_T_USHORT, mode, "protection bits"),
|
MM(st_mode, Py_T_USHORT, mode, "protection bits"),
|
||||||
MM(st_ino, Py_T_ULONGLONG, ino, "inode"),
|
|
||||||
MM(st_size, Py_T_ULONGLONG, size, "total size, in bytes"),
|
|
||||||
MM(st_blocks, Py_T_ULONGLONG, blocks, "number of blocks allocated"),
|
|
||||||
MM(stx_attributes_mask, Py_T_ULONGLONG, attributes_mask,
|
MM(stx_attributes_mask, Py_T_ULONGLONG, attributes_mask,
|
||||||
"Mask of supported bits in stx_attributes"),
|
"Mask of supported bits in stx_attributes"),
|
||||||
MX(st_atime, Py_T_DOUBLE, atime_sec, "time of last access"),
|
|
||||||
MX(st_birthtime, Py_T_DOUBLE, btime_sec, "time of creation"),
|
|
||||||
MX(st_ctime, Py_T_DOUBLE, ctime_sec, "time of last change"),
|
|
||||||
MX(st_mtime, Py_T_DOUBLE, mtime_sec, "time of last modification"),
|
|
||||||
MM(stx_rdev_major, Py_T_UINT, rdev_major, "represented device major number"),
|
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"),
|
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(st_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_major, Py_T_UINT, dev_major, "containing device major number"),
|
||||||
MM(stx_dev_minor, Py_T_UINT, dev_minor, "containing device minor number"),
|
MM(stx_dev_minor, Py_T_UINT, dev_minor, "containing device minor number"),
|
||||||
MX(st_dev, Py_T_ULONGLONG, dev, "device"),
|
MX(st_dev, Py_T_ULONGLONG, dev, "device"),
|
||||||
#ifdef STATX_MNT_ID
|
|
||||||
MM(stx_mnt_id, Py_T_ULONGLONG, mnt_id, "mount ID"),
|
|
||||||
#endif
|
|
||||||
#ifdef STATX_DIOALIGN
|
|
||||||
MM(stx_dio_mem_align, Py_T_UINT, dio_mem_align,
|
|
||||||
"direct I/O memory buffer alignment"),
|
|
||||||
MM(stx_dio_offset_align, Py_T_UINT, dio_offset_align,
|
|
||||||
"direct I/O file offset alignment"),
|
|
||||||
#endif
|
|
||||||
#ifdef STATX_SUBVOL
|
|
||||||
MM(stx_subvol, Py_T_ULONGLONG, subvol, "subvolume ID"),
|
|
||||||
#endif
|
|
||||||
#ifdef STATX_WRITE_ATOMIC
|
|
||||||
MM(stx_atomic_write_unit_min, Py_T_UINT, atomic_write_unit_min,
|
|
||||||
"minimum size for direct I/O with torn-write protection"),
|
|
||||||
MM(stx_atomic_write_unit_max, Py_T_UINT, atomic_write_unit_max,
|
|
||||||
"maximum size for direct I/O with torn-write protection"),
|
|
||||||
MM(stx_atomic_write_segments_max, Py_T_UINT, atomic_write_segments_max,
|
|
||||||
"maximum iovecs for direct I/O with torn-write protection"),
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_STRUCT_STATX_STX_ATOMIC_WRITE_UNIT_MAX_OPT
|
|
||||||
MM(stx_atomic_write_unit_max_opt, Py_T_UINT, atomic_write_unit_max_opt,
|
|
||||||
"maximum optimized size for direct I/O with torn-write protection"),
|
|
||||||
#endif
|
|
||||||
#ifdef STATX_DIO_READ_ALIGN
|
|
||||||
MM(stx_dio_read_offset_align, Py_T_UINT, dio_read_offset_align,
|
|
||||||
"direct I/O file offset alignment for reads"),
|
|
||||||
#endif
|
|
||||||
{NULL},
|
{NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -3384,31 +3348,150 @@ static PyMemberDef pystatx_result_members[] = {
|
||||||
#undef MM
|
#undef MM
|
||||||
#undef M
|
#undef M
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
pystatx_result_get_nsec(PyObject *op, void *context)
|
|
||||||
{
|
|
||||||
uint16_t offset = (uintptr_t)context;
|
|
||||||
struct statx_timestamp *ts = (void*)op + offset;
|
|
||||||
_posixstate *state = PyType_GetModuleState(Py_TYPE(op));
|
|
||||||
assert(state != NULL);
|
|
||||||
return stat_nanosecond_timestamp(state, ts->tv_sec, ts->tv_nsec);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The low 16 bits of the context pointer are the offset from the start of
|
#define STATX_GET_UINT(ATTR, MEMBER, MASK) \
|
||||||
Py_statx_result to the struct statx member. */
|
static PyObject* \
|
||||||
#define GM(attr, type, member, doc) \
|
pystatx_result_get_##ATTR(PyObject *op, void *Py_UNUSED(context)) \
|
||||||
{#attr, pystatx_result_get_##type, NULL, PyDoc_STR(doc), \
|
{ \
|
||||||
(void *)(offsetof(Py_statx_result, stx.stx_##member))}
|
Py_statx_result *self = Py_statx_result_CAST(op); \
|
||||||
|
if (!(self->stx.stx_mask & MASK)) { \
|
||||||
|
Py_RETURN_NONE; \
|
||||||
|
} \
|
||||||
|
unsigned long value = self->stx.MEMBER; \
|
||||||
|
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)
|
||||||
|
#ifdef STATX_DIOALIGN
|
||||||
|
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)
|
||||||
|
#endif
|
||||||
|
#ifdef STATX_DIO_READ_ALIGN
|
||||||
|
STATX_GET_UINT(stx_dio_read_offset_align, stx_dio_read_offset_align,
|
||||||
|
STATX_DIO_READ_ALIGN)
|
||||||
|
#endif
|
||||||
|
#ifdef STATX_WRITE_ATOMIC
|
||||||
|
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)
|
||||||
|
#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)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define STATX_GET_ULONGLONG(ATTR, MEMBER, MASK) \
|
||||||
|
static PyObject* \
|
||||||
|
pystatx_result_get_##ATTR(PyObject *op, void *Py_UNUSED(context)) \
|
||||||
|
{ \
|
||||||
|
Py_statx_result *self = Py_statx_result_CAST(op); \
|
||||||
|
if (!(self->stx.stx_mask & MASK)) { \
|
||||||
|
Py_RETURN_NONE; \
|
||||||
|
} \
|
||||||
|
unsigned long long value = self->stx.MEMBER; \
|
||||||
|
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)
|
||||||
|
#ifdef STATX_MNT_ID
|
||||||
|
STATX_GET_ULONGLONG(stx_mnt_id, stx_mnt_id, STATX_MNT_ID)
|
||||||
|
#endif
|
||||||
|
#ifdef STATX_SUBVOL
|
||||||
|
STATX_GET_ULONGLONG(stx_subvol, stx_subvol, STATX_SUBVOL)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define STATX_GET_DOUBLE(ATTR, MEMBER, MASK) \
|
||||||
|
static PyObject* \
|
||||||
|
pystatx_result_get_##ATTR(PyObject *op, void *Py_UNUSED(context)) \
|
||||||
|
{ \
|
||||||
|
Py_statx_result *self = Py_statx_result_CAST(op); \
|
||||||
|
if (!(self->stx.stx_mask & MASK)) { \
|
||||||
|
Py_RETURN_NONE; \
|
||||||
|
} \
|
||||||
|
double sec = self->MEMBER; \
|
||||||
|
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)
|
||||||
|
|
||||||
|
#define STATX_GET_NSEC(ATTR, MEMBER, MASK) \
|
||||||
|
static PyObject* \
|
||||||
|
pystatx_result_get_##ATTR(PyObject *op, void *context) \
|
||||||
|
{ \
|
||||||
|
Py_statx_result *self = Py_statx_result_CAST(op); \
|
||||||
|
if (!(self->stx.stx_mask & MASK)) { \
|
||||||
|
Py_RETURN_NONE; \
|
||||||
|
} \
|
||||||
|
struct statx_timestamp *ts = &self->stx.MEMBER; \
|
||||||
|
_posixstate *state = PyType_GetModuleState(Py_TYPE(op)); \
|
||||||
|
assert(state != NULL); \
|
||||||
|
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)
|
||||||
|
|
||||||
|
#define G(attr, doc) \
|
||||||
|
{#attr, pystatx_result_get_##attr, NULL, PyDoc_STR(doc), NULL}
|
||||||
|
|
||||||
static PyGetSetDef pystatx_result_getset[] = {
|
static PyGetSetDef pystatx_result_getset[] = {
|
||||||
GM(st_atime_ns, nsec, atime, "time of last access in nanoseconds"),
|
G(st_nlink, "number of hard links"),
|
||||||
GM(st_birthtime_ns, nsec, btime, "time of creation in nanoseconds"),
|
G(st_uid, "user ID of owner"),
|
||||||
GM(st_ctime_ns, nsec, ctime, "time of last change in nanoseconds"),
|
G(st_gid, "group ID of owner"),
|
||||||
GM(st_mtime_ns, nsec, mtime, "time of last modification in nanoseconds"),
|
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"),
|
||||||
|
#ifdef STATX_MNT_ID
|
||||||
|
G(stx_mnt_id, "mount ID"),
|
||||||
|
#endif
|
||||||
|
#ifdef STATX_DIOALIGN
|
||||||
|
G(stx_dio_mem_align, "direct I/O memory buffer alignment"),
|
||||||
|
G(stx_dio_offset_align, "direct I/O file offset alignment"),
|
||||||
|
#endif
|
||||||
|
#ifdef STATX_SUBVOL
|
||||||
|
G(stx_subvol, "subvolume ID"),
|
||||||
|
#endif
|
||||||
|
#ifdef STATX_WRITE_ATOMIC
|
||||||
|
G(stx_atomic_write_unit_min,
|
||||||
|
"minimum size for direct I/O with torn-write protection"),
|
||||||
|
G(stx_atomic_write_unit_max,
|
||||||
|
"maximum size for direct I/O with torn-write protection"),
|
||||||
|
G(stx_atomic_write_segments_max,
|
||||||
|
"maximum iovecs for direct I/O with torn-write protection"),
|
||||||
|
#endif
|
||||||
|
#ifdef STATX_DIO_READ_ALIGN
|
||||||
|
G(stx_dio_read_offset_align, "direct I/O file offset alignment for reads"),
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_STRUCT_STATX_STX_ATOMIC_WRITE_UNIT_MAX_OPT
|
||||||
|
G(stx_atomic_write_unit_max_opt,
|
||||||
|
"maximum optimized size for direct I/O with torn-write protection"),
|
||||||
|
#endif
|
||||||
{NULL},
|
{NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef GM
|
#undef G
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
pystatx_result_repr(PyObject *op)
|
pystatx_result_repr(PyObject *op)
|
||||||
|
|
@ -3446,24 +3529,19 @@ pystatx_result_repr(PyObject *op)
|
||||||
Py_DECREF(o);
|
Py_DECREF(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Py_ARRAY_LENGTH(pystatx_result_members) > 1
|
|
||||||
&& Py_ARRAY_LENGTH(pystatx_result_getset) > 1) {
|
|
||||||
WRITE_ASCII(", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < Py_ARRAY_LENGTH(pystatx_result_getset) - 1; ++i) {
|
for (size_t i = 0; i < Py_ARRAY_LENGTH(pystatx_result_getset) - 1; ++i) {
|
||||||
if (i > 0) {
|
|
||||||
WRITE_ASCII(", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
PyGetSetDef *d = &pystatx_result_getset[i];
|
PyGetSetDef *d = &pystatx_result_getset[i];
|
||||||
WRITE_ASCII(d->name);
|
|
||||||
WRITE_ASCII("=");
|
|
||||||
|
|
||||||
PyObject *o = d->get(op, d->closure);
|
PyObject *o = d->get(op, d->closure);
|
||||||
if (o == NULL) {
|
if (o == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
if (o == Py_None) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE_ASCII(", ");
|
||||||
|
WRITE_ASCII(d->name);
|
||||||
|
WRITE_ASCII("=");
|
||||||
if (PyUnicodeWriter_WriteRepr(writer, o) < 0) {
|
if (PyUnicodeWriter_WriteRepr(writer, o) < 0) {
|
||||||
Py_DECREF(o);
|
Py_DECREF(o);
|
||||||
goto error;
|
goto error;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue