Implement dictionary-like behaviour for Config

This commit is contained in:
Martin Lenders 2012-06-08 17:11:10 +02:00
parent e77d248713
commit e126b09380
5 changed files with 168 additions and 2 deletions
include/pygit2
src/pygit2
test

@ -8,5 +8,7 @@
PyObject* Config_get_global_config(void);
PyObject* Config_get_system_config(void);
PyObject* Config_add_file(Config *self, PyObject *args);
PyObject* Config_getitem(Config *self, PyObject *key);
int Config_setitem(Config *self, PyObject *key, PyObject *value);
#endif

@ -102,6 +102,90 @@ Config_get_system_config(void)
return Config_open(path);
}
int
Config_contains(Config *self, PyObject *py_key) {
int err;
const char *c_value;
const char *c_key;
if (!(c_key = py_str_to_c_str(py_key,NULL)))
return -1;
err = git_config_get_string(&c_value, self->config, c_key);
if (err == GIT_ENOTFOUND)
return 0;
if (err < 0) {
Error_set(err);
return -1;
}
return 1;
}
PyObject *
Config_getitem(Config *self, PyObject *py_key)
{
int err;
int64_t c_intvalue;
int c_boolvalue;
const char *c_charvalue;
const char *c_key;
if (!(c_key = py_str_to_c_str(py_key,NULL)))
return NULL;
err = git_config_get_int64(&c_intvalue, self->config, c_key);
if (err == GIT_OK) {
return PyInt_FromLong((long)c_intvalue);
}
err = git_config_get_bool(&c_boolvalue, self->config, c_key);
if (err == GIT_OK) {
return PyBool_FromLong((long)c_boolvalue);
}
err = git_config_get_string(&c_charvalue, self->config, c_key);
if (err < 0) {
if (err == GIT_ENOTFOUND) {
PyErr_SetObject(PyExc_KeyError, py_key);
return NULL;
}
return Error_set(err);
}
return PyUnicode_FromString(c_charvalue);
}
int
Config_setitem(Config *self, PyObject *py_key, PyObject *py_value)
{
int err;
const char *c_key;
if (!(c_key = py_str_to_c_str(py_key,NULL)))
return -1;
if (!py_value) {
err = git_config_delete(self->config, c_key);
} else if (PyBool_Check(py_value)) {
err = git_config_set_bool(self->config, c_key,
(int)PyObject_IsTrue(py_value));
} else if (PyInt_Check(py_value)) {
err = git_config_set_int64(self->config, c_key,
(int64_t)PyInt_AsLong(py_value));
} else {
py_value = PyObject_Str(py_value);
err = git_config_set_string(self->config, c_key,
py_str_to_c_str(py_value,NULL));
}
if (err < 0) {
Error_set(err);
return -1;
}
return 0;
}
PyObject *
Config_add_file(Config *self, PyObject *args)
{
@ -133,6 +217,23 @@ PyMethodDef Config_methods[] = {
{NULL}
};
PySequenceMethods Config_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)Config_contains,/* sq_contains */
};
PyMappingMethods Config_as_mapping = {
0, /* mp_length */
(binaryfunc)Config_getitem, /* mp_subscript */
(objobjargproc)Config_setitem, /* mp_ass_subscript */
};
PyTypeObject ConfigType = {
PyVarObject_HEAD_INIT(NULL, 0)
"_pygit2.Config", /* tp_name */
@ -145,8 +246,8 @@ PyTypeObject ConfigType = {
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
&Config_as_sequence, /* tp_as_sequence */
&Config_as_mapping, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */

@ -2,5 +2,6 @@
repositoryformatversion = 0
filemode = true
bare = true
editor = 'ed'
[gc]
auto = no

Binary file not shown.

@ -60,6 +60,17 @@ class ConfigTest(utils.RepoTestCase):
self.assertNotEqual(config_write, None)
config_write['core.bare'] = False
config_write['core.editor'] = 'ed'
config_read = pygit2.Config(config_filename)
self.assertTrue('core.bare' in config_write)
self.assertFalse(config_write['core.bare'])
self.assertTrue('core.editor' in config_write)
self.assertEqual(config_write['core.editor'], 'ed')
os.remove(config_filename)
def test_add(self):
config = pygit2.Config.get_global_config()
@ -69,9 +80,60 @@ class ConfigTest(utils.RepoTestCase):
new_file.close()
config.add_file(config_filename, 0)
self.assertTrue('this.that' in config)
self.assertTrue(config['this.that'])
self.assertTrue('something.other.here' in config)
self.assertFalse(config['something.other.here'])
os.remove(config_filename)
def test_read(self):
config = self.repo.config
self.assertRaises(TypeError, lambda: config[()])
self.assertRaises(TypeError, lambda: config[-4])
self.assertRaisesWithArg(pygit2.GitError,
"Invalid variable name: 'abc'", lambda: config['abc'])
self.assertRaisesWithArg(KeyError, 'abc.def', lambda: config['abc.def'])
self.assertTrue('core.bare' in config)
self.assertFalse(config['core.bare'])
self.assertTrue('core.editor' in config)
self.assertEqual(config['core.editor'], 'ed')
self.assertTrue('core.repositoryformatversion' in config)
self.assertEqual(config['core.repositoryformatversion'], 0)
new_file = open(config_filename, "w")
new_file.write("[this]\n\tthat = foobar\n\tthat = foobeer\n")
new_file.close()
def test_write(self):
config = self.repo.config
with self.assertRaises(TypeError):
config[()] = 'This should not work'
self.assertFalse('core.dummy1' in config)
config['core.dummy1'] = 42
self.assertTrue('core.dummy1' in config)
self.assertEqual(config['core.dummy1'], 42)
self.assertFalse('core.dummy2' in config)
config['core.dummy2'] = 'foobar'
self.assertTrue('core.dummy2' in config)
self.assertEqual(config['core.dummy2'], 'foobar')
self.assertFalse('core.dummy3' in config)
config['core.dummy3'] = True
self.assertTrue('core.dummy3' in config)
self.assertTrue(config['core.dummy3'])
del config['core.dummy1']
self.assertFalse('core.dummy1' in config)
del config['core.dummy2']
self.assertFalse('core.dummy2' in config)
del config['core.dummy3']
self.assertFalse('core.dummy3' in config)
if __name__ == '__main__':