[PATCH 3 of 8] osutil: for listdir, implement a skeletal sequence protocol

Laurent Charignon lcharignon at fb.com
Thu Nov 19 07:46:21 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 149895bc5f08815a33b51237b9e2a987f47b69a9
# Parent  b419a4d54b009e5bed6c2bcdb6d8e9471ca724a0
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 @@
 	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 @@
 	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