[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