Mercurial > hgrepos > Python > libs > ConfigMix
changeset 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 |
| files | configmix/_speedups.c configmix/config.py |
| diffstat | 2 files changed, 158 insertions(+), 9 deletions(-) [+] |
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}
--- a/configmix/config.py Tue Jan 11 21:17:06 2022 +0100 +++ b/configmix/config.py Wed Jan 12 00:44:02 2022 +0100 @@ -33,7 +33,8 @@ try: from ._speedups import (fast_unquote, fast_quote, fast_pathstr2path, _fast_split_ns, _fast_split_filters, - _fast_getvarl, _fast_getvar_s, + _fast_getvarl, _fast_getvarl_s, + _fast_getvar, _fast_getvar_s, _fast_interpolate_variables, _sync_MISSING, _sync_MARKER) except ImportError: @@ -43,6 +44,8 @@ _fast_split_ns = None _fast_split_filters = None _fast_getvarl = None + _fast_getvarl_s = None + _fast_getvar = None _fast_getvar_s = None _fast_interpolate_variables = None _sync_MISSING = None @@ -607,7 +610,7 @@ else: return default - def getvar(self, varname, default=_MARKER): + def py_getvar(self, varname, default=_MARKER): """Get a variable of the form ``[ns:][[key1.]key2.]name`` - including variables from other namespaces. @@ -625,6 +628,17 @@ else: return self.getvarl(varname, namespace=varns, default=default) + if _fast_getvar: + + def fast_getvar(self, varname, default=_MARKER): + return _fast_getvar(self, varname, default); + + getvar = fast_getvar + + else: + + getvar = py_getvar + def getkeys(self, varname): """Yield all the keys of a variable value. @@ -656,7 +670,7 @@ else: return default - def getvarl_s(self, *path, **kwds): + def py_getvarl_s(self, *path, **kwds): """Get a variable - including variables from other namespaces. `path` and `namespace` are interpreted as in @@ -678,6 +692,17 @@ else: return default + if _fast_getvarl_s: + + def fast_getvarl_s(self, *path, **kwds): + return _fast_getvarl_s(self, path, **kwds) + + getvarl_s = fast_getvarl_s + + else: + + getvarl_s = py_getvarl_s + def getfirstvarl_s(self, *paths, **kwds): """A variant of :meth:`~.getfirstvarl` that does variable interpolation.
