Implement mapping protocol for the index file
It is possible to: len(index) # get the number of entries in the index '...' in index # check whether there is an entry with the given path index[1] # get entry by position index['...'] # get entry by path del index[...] # remove entry by position or path
This commit is contained in:
parent
bc1e00ae05
commit
54d944d0b6
186
pygit2.c
186
pygit2.c
@ -1340,14 +1340,6 @@ Index_clear(Index *self) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Index_entrycount(Index *self) {
|
||||
long count;
|
||||
|
||||
count = (long)git_index_entrycount(self->index);
|
||||
return PyInt_FromLong(count);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Index_find(Index *self, PyObject *py_path) {
|
||||
char *path;
|
||||
@ -1364,32 +1356,6 @@ Index_find(Index *self, PyObject *py_path) {
|
||||
return PyInt_FromLong(idx);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Index_get(Index *self, PyObject *py_idx) {
|
||||
int idx;
|
||||
git_index_entry *index_entry;
|
||||
IndexEntry *py_index_entry;
|
||||
|
||||
idx = (int)PyInt_AsLong(py_idx);
|
||||
if (idx == -1 && PyErr_Occurred())
|
||||
return NULL;
|
||||
|
||||
index_entry = git_index_get(self->index, idx);
|
||||
if (!index_entry) {
|
||||
PyErr_SetObject(PyExc_KeyError, py_idx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
py_index_entry = (IndexEntry*)IndexEntryType.tp_alloc(&IndexEntryType, 0);
|
||||
if (!py_index_entry)
|
||||
return PyErr_NoMemory();
|
||||
|
||||
py_index_entry->entry = index_entry;
|
||||
|
||||
Py_INCREF(py_index_entry);
|
||||
return (PyObject*)py_index_entry;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Index_read(Index *self) {
|
||||
int err;
|
||||
@ -1401,22 +1367,6 @@ Index_read(Index *self) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Index_remove(Index *self, PyObject *py_idx) {
|
||||
int err;
|
||||
int idx;
|
||||
|
||||
idx = (int)PyInt_AsLong(py_idx);
|
||||
if (idx == -1 && PyErr_Occurred())
|
||||
return NULL;
|
||||
|
||||
err = git_index_remove(self->index, idx);
|
||||
if (err < 0)
|
||||
return Error_set(err);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Index_write(Index *self) {
|
||||
int err;
|
||||
@ -1428,29 +1378,147 @@ Index_write(Index *self) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/* This is an internal function, used by Index_getitem and Index_setitem */
|
||||
static int
|
||||
Index_get_position(Index *self, PyObject *value) {
|
||||
char *path;
|
||||
int idx;
|
||||
|
||||
if (PyString_Check(value)) {
|
||||
path = PyString_AsString(value);
|
||||
if (!path)
|
||||
return -1;
|
||||
idx = git_index_find(self->index, path);
|
||||
if (idx < 0) {
|
||||
Error_set_str(idx, path);
|
||||
return -1;
|
||||
}
|
||||
} else if (PyInt_Check(value)) {
|
||||
idx = (int)PyInt_AsLong(value);
|
||||
if (idx == -1 && PyErr_Occurred())
|
||||
return -1;
|
||||
if (idx < 0) {
|
||||
PyErr_SetObject(PyExc_ValueError, value);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"Index entry key must be int or str, not %.200s",
|
||||
value->ob_type->tp_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
static int
|
||||
Index_contains(Index *self, PyObject *value) {
|
||||
char *path;
|
||||
int idx;
|
||||
|
||||
path = PyString_AsString(value);
|
||||
if (!path)
|
||||
return -1;
|
||||
idx = git_index_find(self->index, path);
|
||||
if (idx == GIT_ENOTFOUND)
|
||||
return 0;
|
||||
if (idx < 0) {
|
||||
Error_set_str(idx, path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static Py_ssize_t
|
||||
Index_len(Index *self) {
|
||||
return (Py_ssize_t)git_index_entrycount(self->index);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Index_getitem(Index *self, PyObject *value) {
|
||||
int idx;
|
||||
git_index_entry *index_entry;
|
||||
IndexEntry *py_index_entry;
|
||||
|
||||
idx = Index_get_position(self, value);
|
||||
if (idx == -1)
|
||||
return NULL;
|
||||
|
||||
index_entry = git_index_get(self->index, idx);
|
||||
if (!index_entry) {
|
||||
PyErr_SetObject(PyExc_KeyError, value);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
py_index_entry = (IndexEntry*)IndexEntryType.tp_alloc(&IndexEntryType, 0);
|
||||
if (!py_index_entry)
|
||||
return PyErr_NoMemory();
|
||||
|
||||
py_index_entry->entry = index_entry;
|
||||
|
||||
Py_INCREF(py_index_entry);
|
||||
return (PyObject*)py_index_entry;
|
||||
}
|
||||
|
||||
static int
|
||||
Index_setitem(Index *self, PyObject *key, PyObject *value) {
|
||||
int err;
|
||||
int idx;
|
||||
|
||||
if (value) {
|
||||
PyErr_SetString(PyExc_NotImplementedError,
|
||||
"set item on index not yet implemented");
|
||||
return -1;
|
||||
}
|
||||
|
||||
idx = Index_get_position(self, key);
|
||||
if (idx == -1)
|
||||
return -1;
|
||||
|
||||
err = git_index_remove(self->index, idx);
|
||||
if (err < 0) {
|
||||
Error_set(err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyMethodDef Index_methods[] = {
|
||||
{"add", (PyCFunction)Index_add, METH_VARARGS,
|
||||
"Add or update an index entry from a file in disk."},
|
||||
{"clear", (PyCFunction)Index_clear, METH_NOARGS,
|
||||
"Clear the contents (all the entries) of an index object."},
|
||||
{"entrycount", (PyCFunction)Index_entrycount, METH_NOARGS,
|
||||
"Get the count of entries currently in the index."},
|
||||
{"find", (PyCFunction)Index_find, METH_O,
|
||||
{"_find", (PyCFunction)Index_find, METH_O,
|
||||
"Find the first index of any entries which point to given path in the"
|
||||
" Git index."},
|
||||
{"get", (PyCFunction)Index_get, METH_O,
|
||||
"Get a pointer to one of the entries in the index."},
|
||||
{"read", (PyCFunction)Index_read, METH_NOARGS,
|
||||
"Update the contents of an existing index object in memory by reading"
|
||||
" from the hard disk."},
|
||||
{"remove", (PyCFunction)Index_remove, METH_O,
|
||||
"Remove an entry from the index."},
|
||||
{"write", (PyCFunction)Index_write, METH_NOARGS,
|
||||
"Write an existing index object from memory back to disk using an"
|
||||
" atomic file lock."},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
static PySequenceMethods Index_as_sequence = {
|
||||
0, /* sq_length */
|
||||
0, /* sq_concat */
|
||||
0, /* sq_repeat */
|
||||
0, /* sq_item */
|
||||
0, /* sq_slice */
|
||||
0, /* sq_ass_item */
|
||||
0, /* sq_ass_slice */
|
||||
(objobjproc)Index_contains, /* sq_contains */
|
||||
};
|
||||
|
||||
static PyMappingMethods Index_as_mapping = {
|
||||
(lenfunc)Index_len, /* mp_length */
|
||||
(binaryfunc)Index_getitem, /* mp_subscript */
|
||||
(objobjargproc)Index_setitem, /* mp_ass_subscript */
|
||||
};
|
||||
|
||||
static PyTypeObject IndexType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, /* ob_size */
|
||||
@ -1464,8 +1532,8 @@ static PyTypeObject IndexType = {
|
||||
0, /* tp_compare */
|
||||
0, /* tp_repr */
|
||||
0, /* tp_as_number */
|
||||
0, /* tp_as_sequence */
|
||||
0, /* tp_as_mapping */
|
||||
&Index_as_sequence, /* tp_as_sequence */
|
||||
&Index_as_mapping, /* tp_as_mapping */
|
||||
0, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
|
Loading…
x
Reference in New Issue
Block a user