Skip to content

Commit

Permalink
Fix #9: python2: configKeys returns dictionary
Browse files Browse the repository at this point in the history
  • Loading branch information
WojciechMula committed Apr 30, 2016
1 parent a2fcf00 commit 1223b14
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 138 deletions.
168 changes: 52 additions & 116 deletions aspell.2.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,34 +198,43 @@ static void speller_dealloc(PyObject* self) {
}

/* ConfigKeys *****************************************************************/
static PyObject* configkeys(PyObject* _) {

static PyObject* configkeys_helper(PyObject* self) {
AspellConfig* config;
AspellKeyInfoEnumeration *keys_enumeration;
AspellStringList* lst;
AspellMutableContainer* amc;
const AspellKeyInfo *key_info;

PyObject *key_list, *obj;
PyObject *dict = 0, *obj = 0, *value = 0;
const char* string;
unsigned int integer;
unsigned int boolean;

char *key_type = 0;

config = new_aspell_config();
if (self)
config = aspell_speller_config(Speller(self));
else
config = new_aspell_config();

if (config == NULL) {
PyErr_SetString(_AspellModuleException, "can't create config");
return NULL;
}

keys_enumeration = aspell_config_possible_elements(config, 1);
if (!keys_enumeration) {
if (!self) delete_aspell_config(config);
PyErr_SetString(_AspellConfigException, "can't get list of config keys");
return NULL;
}

key_list = PyList_New(0);
dict = PyDict_New();
if (dict == NULL) {
if (!self) delete_aspell_config(config);
return NULL;
}

while ((key_info = aspell_key_info_enumeration_next(keys_enumeration))) {

/* key type -> string */
Expand All @@ -234,13 +243,13 @@ static PyObject* configkeys(PyObject* _) {
key_type = "string";
string = aspell_config_retrieve(config, key_info->name);
if (aspell_config_error(config) != NULL) goto config_get_error;
obj = PyString_FromString( string );
obj = PyUnicode_FromString( string );
break;
case AspellKeyInfoInt:
key_type = "integer";
integer = aspell_config_retrieve_int(config, key_info->name);
if (aspell_config_error(config) != NULL) goto config_get_error;
obj = PyInt_FromLong( integer );
obj = PyLong_FromLong( integer );
break;
case AspellKeyInfoBool:
key_type = "boolean";
Expand All @@ -258,119 +267,47 @@ static PyObject* configkeys(PyObject* _) {
obj = AspellStringList2PythonList(lst);
delete_aspell_string_list(lst);
break;
default:
obj = NULL;
break;
}

if (obj == NULL) {
continue;
}
/* value */
value = Py_BuildValue("(sOs)",
key_type,
obj,
key_info->desc ? key_info->desc : "internal"
);

if (PyList_Append(key_list, Py_BuildValue("(ssOs)", key_info->name, key_type, obj, key_info->desc ? key_info->desc : "internal")) == -1) {
PyErr_SetString(PyExc_Exception, "It is almost impossible, but happend! Can't append element to the list.");
delete_aspell_key_info_enumeration(keys_enumeration);
Py_DECREF(key_list);
return NULL;
if (value) {
if (PyDict_SetItemString(dict, key_info->name, value)) {
goto python_error;
}
else
Py_DECREF(value);
}
else
goto python_error;
}

delete_aspell_key_info_enumeration(keys_enumeration);
delete_aspell_config(config);
return key_list;
if (!self) delete_aspell_config(config);
return dict;

config_get_error:
PyErr_SetString(_AspellConfigException, aspell_config_error_message(config));
python_error:
delete_aspell_key_info_enumeration(keys_enumeration);
delete_aspell_config(config);
Py_DECREF(key_list);
if (!self) delete_aspell_config(config);
Py_DECREF(dict);
return NULL;
}

/* method:ConfigKeys **********************************************************/
static PyObject* m_configkeys(PyObject* self, PyObject* args) {

AspellConfig* config;
AspellKeyInfoEnumeration *keys_enumeration;
AspellStringList* lst;
AspellMutableContainer* amc;
const AspellKeyInfo *key_info;

PyObject *key_list, *obj;
const char* string;
unsigned int integer;
unsigned int boolean;

char *key_type = 0;

config = aspell_speller_config(Speller(self));
if (config == NULL) {
PyErr_SetString(_AspellModuleException, "can't create config");
return NULL;
}

keys_enumeration = aspell_config_possible_elements(config, 1);
if (!keys_enumeration) {
PyErr_SetString(_AspellConfigException, "can't get list of config keys");
return NULL;
}

key_list = PyList_New(0);
while ((key_info = aspell_key_info_enumeration_next(keys_enumeration))) {

/* key type -> string */
switch (key_info->type) {
case AspellKeyInfoString:
key_type = "string";
string = aspell_config_retrieve(config, key_info->name);
if (aspell_config_error(config) != NULL) goto config_get_error;
obj = PyString_FromString( string );
break;
case AspellKeyInfoInt:
key_type = "integer";
integer = aspell_config_retrieve_int(config, key_info->name);
if (aspell_config_error(config) != NULL) goto config_get_error;
obj = PyInt_FromLong( integer );
break;
case AspellKeyInfoBool:
key_type = "boolean";
boolean = aspell_config_retrieve_bool(config, key_info->name);
if (aspell_config_error(config) != NULL) goto config_get_error;
obj = PyBool_FromLong( boolean );
break;
case AspellKeyInfoList:
key_type = "list";
lst = new_aspell_string_list();
amc = aspell_string_list_to_mutable_container(lst);
aspell_config_retrieve_list(config, key_info->name, amc);
if (aspell_config_error(config) != NULL) goto config_get_error;

obj = AspellStringList2PythonList(lst);
delete_aspell_string_list(lst);
break;
default:
obj = NULL;
break;
}

if (obj == NULL) {
continue;
}

if (PyList_Append(key_list, Py_BuildValue("(ssO)", key_info->name, key_type, obj)) == -1) {
PyErr_SetString(PyExc_Exception, "It is almost impossible, but happend! Can't append element to the list.");
delete_aspell_key_info_enumeration(keys_enumeration);
Py_DECREF(key_list);
return NULL;
}
}
delete_aspell_key_info_enumeration(keys_enumeration);
return key_list;
static PyObject* configkeys(PyObject* _) {
return configkeys_helper(NULL);
}

config_get_error:
PyErr_SetString(_AspellConfigException, aspell_config_error_message(config));
delete_aspell_key_info_enumeration(keys_enumeration);
Py_DECREF(key_list);
return NULL;
/* method:ConfigKeys **********************************************************/
static PyObject* m_configkeys(PyObject* self, PyObject* args) {
return configkeys_helper(self);
}

/* method:setConfigKey ********************************************************/
Expand Down Expand Up @@ -579,11 +516,11 @@ static PyMethodDef aspell_object_methods[] = {
"ConfigKeys",
(PyCFunction)m_configkeys,
METH_VARARGS,
"ConfigKeys() => list of config keys\n"
"The list's item is a 3-touple:\n"
"\t1. key name\n"
"\t2. key type={string|integer|boolean|list}\n"
"\t4. current value"
"ConfigKeys() => dictionary of config keys\n"
"Keys are string, values are 3-touple:\n"
"\t1. key type={string|integer|boolean|list}\n"
"\t2. current value\n"
"\t3. description (if 'internal' no description available)"
},
{
"setConfigKey",
Expand Down Expand Up @@ -696,12 +633,11 @@ static PyMethodDef aspell_methods[] = {
"ConfigKeys",
(PyCFunction)configkeys,
METH_VARARGS,
"ConfigKeys() => list of config keys\n"
"The list's item is a 4-touple:\n"
"\t1. key name\n"
"\t2. key type={string|integer|boolean|list}\n"
"\t3. default value\n"
"\t4. short description ('internal' for undocumented options)."
"ConfigKeys() => dictionary of config keys\n"
"Keys are string, values are 3-touple:\n"
"\t1. key type={string|integer|boolean|list}\n"
"\t2. current value\n"
"\t3. description (if 'internal' no description available)"
},
{NULL, NULL, 0, NULL}
};
Expand Down
21 changes: 10 additions & 11 deletions aspell.c
Original file line number Diff line number Diff line change
Expand Up @@ -663,11 +663,11 @@ static PyMethodDef aspell_object_methods[] = {
"ConfigKeys",
(PyCFunction)m_configkeys,
METH_VARARGS,
"ConfigKeys() => list of config keys\n"
"The list's item is a 3-touple:\n"
"\t1. key name\n"
"\t2. key type={string|integer|boolean|list}\n"
"\t4. current value"
"ConfigKeys() => dictionary of config keys\n"
"Keys are string, values are 3-touple:\n"
"\t1. key type={string|integer|boolean|list}\n"
"\t2. current value\n"
"\t3. description (if 'internal' no description available)"
},
{
"setConfigKey",
Expand Down Expand Up @@ -802,12 +802,11 @@ static PyMethodDef aspell_module_methods[] = {
"ConfigKeys",
(PyCFunction)configkeys,
METH_VARARGS,
"ConfigKeys() => list of config keys\n"
"The list's item is a 4-touple:\n"
"\t1. key name\n"
"\t2. key type={string|integer|boolean|list}\n"
"\t3. default value\n"
"\t4. short description ('internal' for undocumented options)."
"ConfigKeys() => dictionary of config keys\n"
"Keys are string, values are 3-touple:\n"
"\t1. key type={string|integer|boolean|list}\n"
"\t2. current value\n"
"\t3. description (if 'internal' no description available)"
},
{NULL, NULL, 0, NULL}
};
Expand Down
13 changes: 2 additions & 11 deletions test/unittests.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,7 @@ def setUp(self):
# get current speller configuration
config = self.speller.ConfigKeys()

# XXX: workaround for issue #3
if type(config) is dict:
self.config = dict((name, value) for name, (type, value, desc) in config.items())
else:
self.config = dict((name, value) for (name, type, value) in config)

self.config = dict((name, value) for name, (type, value, desc) in config.items())

# polish words (cat, tree, spring) not existing in english dict
self.polish_words = ['kot', 'drzewo', 'wiosna']
Expand Down Expand Up @@ -222,11 +217,7 @@ def setUp(self):

def get_config(self):
config = self.speller.ConfigKeys();
# XXX: workaround for issue #3
if type(config) is dict:
return dict((name, value) for name, (type, value, desc) in config.items())
else:
return dict((name, value) for (name, type, value) in config)
return dict((name, value) for name, (type, value, desc) in config.items())


def test_string_value(self):
Expand Down

0 comments on commit 1223b14

Please sign in to comment.