[PATCH 2 of 3] osutil: for listdir, implement a skeletal sequence protocol
Bryan O'Sullivan
bos at serpentine.com
Wed Nov 18 10:18:55 CST 2015
# HG changeset patch
# User Bryan O'Sullivan <bos at serpentine.com>
# Date 1447862029 18000
# Wed Nov 18 10:53:49 2015 -0500
# Node ID d2569b9eab3d2cfa6cad3cafcec60a66634412af
# Parent a53055eb296a3676f7ce739905510f2e72a735ef
osutil: for listdir, implement a skeletal sequence protocol
This allows us to do away with the expensive hack that is
util.statmtimesec.
diff --git a/mercurial/osutil.c b/mercurial/osutil.c
--- a/mercurial/osutil.c
+++ b/mercurial/osutil.c
@@ -100,6 +100,52 @@ static void listdir_stat_dealloc(PyObjec
o->ob_type->tp_free(o);
}
+static PyObject *
+listdir_stat_item(PyObject *self, Py_ssize_t i)
+{
+ const hg_stat_t *st = &((struct listdir_stat *)self)->st;
+
+ switch (i) {
+ /* These field offsets are defined in Python's stat module. */
+ case 0: /* ST_MODE */
+ return PyInt_FromLong(st->st_mode);
+ case 2: /* ST_DEV */
+ return PyInt_FromLong(st->st_dev);
+ case 3: /* ST_NLINK */
+ return PyInt_FromLong(st->st_nlink);
+ case 6: /* ST_SIZE */
+#ifdef _WIN32
+ return PyLong_FromLongLong((PY_LONG_LONG)st->st_size);
+#else
+ return PyInt_FromLong(st->st_size);
+#endif
+ case 8: /* ST_MTIME */
+ return PyInt_FromLong(st->st_mtime);
+ case 9: /* ST_CTIME */
+ return PyInt_FromLong(st->st_ctime);
+ case 1: /* ST_INO */
+ case 4: /* ST_UID */
+ case 5: /* ST_GID */
+ case 7: /* ST_ATIME */
+ return PyErr_Format(PyExc_NotImplementedError,
+ "listdir index %d not implemented", (int)i);
+ default:
+ PyErr_SetString(PyExc_IndexError, "index out of range");
+ return NULL;
+ }
+}
+
+static PySequenceMethods listdir_stat_as_sequence = {
+ 0, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ (ssizeargfunc)listdir_stat_item, /*sq_item*/
+ 0, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ 0 /*sq_contains*/
+};
+
static PyTypeObject listdir_stat_type = {
PyVarObject_HEAD_INIT(NULL, 0)
"osutil.stat", /*tp_name*/
@@ -112,7 +158,7 @@ static PyTypeObject listdir_stat_type =
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
+ &listdir_stat_as_sequence, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
More information about the Mercurial-devel
mailing list