Mercurial > hgrepos > Python > libs > ConfigMix
diff configmix/_speedups.c @ 610:764d4185c76a
C-implementations of Configuration.getvarl_s() and Configuration.getvar()
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Wed, 12 Jan 2022 00:44:02 +0100 |
| parents | 9ad860d6ddc9 |
| children | db5a20f18030 |
line wrap: on
line diff
--- a/configmix/_speedups.c Tue Jan 11 21:17:06 2022 +0100 +++ b/configmix/_speedups.c Wed Jan 12 00:44:02 2022 +0100 @@ -1257,6 +1257,61 @@ } +static +PyObject * +fast_getvarl_s(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"config", "path", "namespace", "default", NULL}; + + PyObject *config; + PyObject *path; + PyObject *namespace = NULL; + PyObject *default_ = NULL; + + PyObject *res = NULL; + PyObject *tmp; + + struct speedups_state *sstate; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO!|$OO", kwlist, &config, &PyTuple_Type, &path, &namespace, &default_)) { + + return NULL; + } + sstate = PyModule_GetState(self); + if (sstate == NULL) { + PyErr_SetString(PyExc_RuntimeError, "no module state available"); + return NULL; + } + + tmp = _fast_getvarl(config, path, namespace, NULL, sstate); + if (tmp == NULL) { + goto handle_possible_keyerror; + } + res = PyObject_CallMethod(config, "substitute_variables_in_obj", "O", tmp); + if (res == NULL) { + py_clear_ref(&tmp); + goto handle_possible_keyerror; + } + py_clear_ref(&tmp); + return res; + +handle_possible_keyerror: + if (PyErr_ExceptionMatches(PyExc_KeyError)) { + if ((default_ == NULL) || py_object_is(default_, sstate->MARKER)) { + /* fall through */ + } + else { + PyErr_Clear(); + return Py_NewRef(default_); + } + } + /* fall through */ + +error: + return NULL; +} + + /** * Combination of py_getvar_s and _py_getvar_s_with_cache_info */ @@ -1267,7 +1322,7 @@ PyObject *varname_b; /* always borrowed */ PyObject *namespace_b; /* always borrowed */ PyObject *splitted = NULL; - PyObject *res = NULL; + PyObject *res; PyObject *tmp1; PyObject *tmp2; @@ -1331,15 +1386,82 @@ } else { PyErr_Clear(); - Py_XDECREF(res); Py_XDECREF(splitted); return Py_NewRef(default_); } } - /* fall through */ - + /* fall through */ + error: - Py_XDECREF(res); + Py_XDECREF(splitted); + return NULL; +} + + +static +PyObject * +fast_getvar(PyObject *self, PyObject *args) +{ + PyObject *config; + PyObject *varname; + PyObject *default_; + + PyObject *varname_b; /* always borrowed */ + PyObject *namespace_b; /* always borrowed */ + PyObject *splitted = NULL; + PyObject *res; + PyObject *tmp1; + struct speedups_state *sstate; + + if (!PyArg_UnpackTuple(args, "config", 3, 3, &config, &varname, &default_)) { + return NULL; + } + + splitted = fast_split_ns(self, varname); + if (splitted == NULL) { + goto error; + } + namespace_b = PyTuple_GetItem(splitted, 0); /* borrowed */ + varname_b = PyTuple_GetItem(splitted, 1); /* borrowed */ + + sstate = PyModule_GetState(self); + if (sstate == NULL) { + PyErr_SetString(PyExc_RuntimeError, "no module state available"); + goto error; + } + + if (PyObject_Not(namespace_b)) { + tmp1 = _fast_pathstr2path(varname_b, NULL, sstate); + if (tmp1 == NULL) { + goto error; + } + res = _fast_getvarl(config, tmp1, NULL, default_, sstate); + if (res == NULL) { + py_clear_ref(&tmp1); + goto error; + } + py_clear_ref(&tmp1); + } + else { + tmp1 = PyTuple_New(1); + if (tmp1 == NULL) { + goto error; + } + PyTuple_SetItem(tmp1, 0, Py_NewRef(varname_b)); + res = _fast_getvarl(config, tmp1, namespace_b, default_, sstate); + if (res == NULL) {tmp1 = _fast_pathstr2path(varname_b, NULL, sstate); + if (tmp1 == NULL) { + goto error; + } + py_clear_ref(&tmp1); + goto error; + } + py_clear_ref(&tmp1); + } + Py_DECREF(splitted); + return res; + +error: Py_XDECREF(splitted); return NULL; } @@ -1416,7 +1538,9 @@ {"_fast_split_ns", fast_split_ns, METH_O, PyDoc_STR("C-implementation of configmix.config._split_ns")}, {"_fast_interpolate_variables", fast_interpolate_variables, METH_VARARGS, PyDoc_STR("C-implementation of configmix.config.Configuration.interpolate_variables")}, {"_fast_getvarl", (PyCFunction)fast_getvarl, METH_VARARGS | METH_KEYWORDS, PyDoc_STR("C-Implementation of configmix.config.Configuration.getvarl")}, - {"_fast_getvar_s", fast_getvar_s, METH_VARARGS, PyDoc_STR("C-Implementation of configmix.config.Configuration.getvar_s")}, + {"_fast_getvarl_s", (PyCFunction)fast_getvarl_s, METH_VARARGS | METH_KEYWORDS, PyDoc_STR("C-Implementation of configmix.config.Configuration.getvarl_s")}, + {"_fast_getvar", fast_getvar, METH_VARARGS, PyDoc_STR("C-Implementation of configmix.config.Configuration.getvar")}, + {"_fast_getvar_s", fast_getvar_s, METH_VARARGS, PyDoc_STR("C-Implementation of configmix.config.Configuration.getvar_s")}, {"_sync_MISSING", sync_MISSING, METH_O, PyDoc_STR("Internal function to easily sync the _MISSING object with configmix.config")}, {"_sync_MARKER", sync_MARKER, METH_O, PyDoc_STR("Internal function to easily sync the _MARKER object with configmix.config")}, {NULL, NULL, 0, NULL}
