Mercurial > hgrepos > Python > libs > ConfigMix
changeset 559:bb160a1e67d7
A simple helper include file with some conveniente functions.
Also some "backports" from later Python versions.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Thu, 06 Jan 2022 18:50:09 +0100 |
| parents | 7a3c311991d7 |
| children | 81238ea2dbe3 |
| files | MANIFEST.in configmix/_py_helper.h configmix/_speedups.c |
| diffstat | 3 files changed, 134 insertions(+), 87 deletions(-) [+] |
line wrap: on
line diff
--- a/MANIFEST.in Wed Jan 05 16:02:07 2022 +0100 +++ b/MANIFEST.in Thu Jan 06 18:50:09 2022 +0100 @@ -1,5 +1,5 @@ include .hg* *.txt requirement* -include configmix/*.c +include configmix/*.c configmix/*.h graft docs graft tests prune docs/_build
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/configmix/_py_helper.h Thu Jan 06 18:50:09 2022 +0100 @@ -0,0 +1,70 @@ +/* -*- coding: utf-8 -*- */ +/* + * Some Python helper for C. + * + * Also contains some interesting backports from later Python versions. + * + * :Copyright: (c) 2021, Franz Glasner. All rights reserved. + * :License: BSD-3-Clause. See LICENSE.txt for details. + */ + +#if !defined(_PY_HELPER_H_d9df407295df4884a88e56699f6c6d8d) +#define _PY_HELPER_H_d9df407295df4884a88e56699f6c6d8d + +#if PY_VERSION_HEX < 0x030A0000 + +static inline +PyObject * +Py_NewRef(PyObject *obj) +{ + Py_INCREF(obj); + return obj; +} + + +static inline +PyObject * +Py_XNewRef(PyObject *obj) +{ + Py_XINCREF(obj); + return obj; +} + +#endif /* PY_VERSION_HEX < 0x030A0000 */ + + +static inline +void +py_clear_ref(PyObject **obj) +{ + PyObject *tmp; + + if ((tmp = *obj) != NULL) { + *obj = NULL; + Py_DECREF(tmp); + } +} + + +/* + * NOTE: This implementation is valid for CPython only! + */ +static inline +int +py_object_is(PyObject *obj1, PyObject *obj2) +{ + return (obj1 == obj2); +} + + +/* + * NOTE: This implementation is valid for CPython only! + */ +static inline +int +py_object_isnot(PyObject *obj1, PyObject *obj2) +{ + return (obj1 != obj2); +} + +#endif
--- a/configmix/_speedups.c Wed Jan 05 16:02:07 2022 +0100 +++ b/configmix/_speedups.c Thu Jan 06 18:50:09 2022 +0100 @@ -9,6 +9,8 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "_py_helper.h" + const char _id[] = "@(#)configmix._speedups $Header$"; static const char release[] = "|VCSRevision|"; @@ -277,16 +279,14 @@ } } if (s_len == 0) { - Py_INCREF(s); - return s; + return Py_NewRef(s); } find = PyUnicode_FindChar(s, '%', 0, s_len, 1); if (find == -2) { return NULL; } if (find == -1) { - Py_INCREF(s); - return s; + return Py_NewRef(s); } if (sstate == NULL) { @@ -317,8 +317,7 @@ * The first item may be also the empty string if `s' starts with * a quoted character. */ - Py_INCREF(o); /* because PyTuple_SetItem steals -- and o is borrowed */ - PyTuple_SetItem(res_parts, 0, o); + PyTuple_SetItem(res_parts, 0, Py_NewRef(o)); for (i=1; i<parts_len; i++) { pb = PyList_GetItem(parts, i); /* borrowed */ @@ -422,8 +421,7 @@ return NULL; } if (s_len == 0) { - Py_INCREF(s); - return s; + return Py_NewRef(s); } need_quoting = 0; for (i=0; i<s_len; i++) { @@ -449,8 +447,7 @@ } } if (!need_quoting) { - Py_INCREF(s); - return s; + return Py_NewRef(s); } sstate = PyModule_GetState(self); if (sstate == NULL) { @@ -551,8 +548,7 @@ if (res == NULL) { goto error; } - Py_INCREF(varname); /* because PyTuple_SetItem steals */ - PyTuple_SetItem(res, 0, varname); /* steals */ + PyTuple_SetItem(res, 0, Py_NewRef(varname)); /* steals */ filters = PyList_New(0); if (filters == NULL) { goto error; @@ -574,10 +570,10 @@ goto error; } Py_DECREF(filters); - filters = tmp; + filters = tmp; tmp = NULL; if (PyObject_Not(filters)) { - Py_DECREF(filters); filters = NULL; + py_clear_ref(&filters); res = PyTuple_New(2); if (res == NULL) { @@ -606,7 +602,7 @@ goto error; } Py_DECREF(filters); - filters = tmp; + filters = tmp; tmp = NULL; res = PyTuple_New(2); if (res == NULL) { @@ -655,10 +651,8 @@ if (res == NULL) { return NULL; } - Py_INCREF(Py_None); - PyTuple_SetItem(res, 0, Py_None); /* steals */ - Py_INCREF(varname); - PyTuple_SetItem(res, 1, varname); /* steals */ + PyTuple_SetItem(res, 0, Py_NewRef(Py_None)); /* steals */ + PyTuple_SetItem(res, 1, Py_NewRef(varname)); /* steals */ return res; } @@ -728,8 +722,7 @@ } if (s_len < 4) { PyErr_Clear(); - Py_INCREF(s); - return s; + return Py_NewRef(s); } sstate = PyModule_GetState(self); if (sstate == NULL) { @@ -740,8 +733,7 @@ idx = PyUnicode_Find(s, sstate->STARTTOK, 0, s_len, 1); if (idx < 0) { PyErr_Clear(); - Py_INCREF(s); - return s; + return Py_NewRef(s); } res = PyDict_GetItem(cache, s); /* borrowed */ @@ -753,8 +745,7 @@ s); } else { - Py_INCREF(res); - return res; + return Py_NewRef(res); } } @@ -780,8 +771,8 @@ * an interpolation token. */ first_part_is_empty = PyObject_Not(tmp); - Py_INCREF(tmp); /* because PyList_SetItem steals -- and tmp is borrowed */ - PyList_SetItem(res_parts, 0, tmp); /* steals -- cannot fail here */ + /* steals -- cannot fail here -- NOTE: tmp is currently borrowed */ + PyList_SetItem(res_parts, 0, Py_NewRef(tmp)); tmp = NULL; for (i=1; i<parts_len; i++) { @@ -825,19 +816,16 @@ } if (PyTuple_Size(tmp) != 2) { PyErr_SetString(PyExc_TypeError, "tuple of size 2 expected"); - Py_DECREF(tmp); + py_clear_ref(&tmp); goto error; } /* Unpack the result tuple */ tmp2 = PyTuple_GetItem(tmp, 0); /* borrowed -- cannot fail */ Py_DECREF(varname); - Py_INCREF(tmp2); - varname = tmp2; - tmp2 = NULL; - filters = PyTuple_GetItem(tmp, 1); /* borrowed -- cannot fail */ - Py_INCREF(filters); - Py_DECREF(tmp); - tmp = NULL; + varname = Py_NewRef(tmp2); tmp2 = NULL; + /* borrowed -- cannot fail -- want own */ + filters = Py_NewRef(PyTuple_GetItem(tmp, 1)); + py_clear_ref(&tmp); tmp = PyObject_CallMethod( config, "_getvar_s_with_cache_info", "O", varname); @@ -847,14 +835,12 @@ cacheable = 1; if (PySequence_Contains(filters, sstate->NONE_FILTER) == 1) { PyErr_Clear(); - Py_INCREF(Py_None); - varvalue = Py_None; + varvalue = Py_NewRef(Py_None); } else { if (PySequence_Contains(filters, sstate->EMPTY_FILTER) == 1) { PyErr_Clear(); - Py_INCREF(sstate->EMPTY_STR); - varvalue = sstate->EMPTY_STR; + varvalue = Py_NewRef(sstate->EMPTY_STR); } else { PyErr_Fetch(&err_type, &err_value, &err_tb); @@ -872,33 +858,31 @@ } else { if (PyTuple_Size(tmp) != 2) { - Py_DECREF(tmp); tmp = NULL; + py_clear_ref(&tmp); PyErr_SetString(PyExc_TypeError, "tuple of size 2 expected"); goto error; } /* unpack the result */ - varvalue = PyTuple_GetItem(tmp, 0); /* borrowed -- but want own */ - Py_INCREF(varvalue); + /* borrowed -- but want own */ + varvalue = Py_NewRef(PyTuple_GetItem(tmp, 0)); cacheable = PyObject_IsTrue(PyTuple_GetItem(tmp, 1)); - Py_DECREF(tmp); tmp = NULL; + py_clear_ref(&tmp); } if (!cacheable) { use_cache = 0; } - Py_DECREF(varname); varname = NULL; + py_clear_ref(&varname); tmp = PyObject_CallMethod( config, "_apply_filters", "OO", filters, varvalue); if (tmp == NULL) { goto error; } - Py_DECREF(varvalue); - varvalue = tmp; - tmp = NULL; + py_clear_ref(&varvalue); - Py_DECREF(filters); filters = NULL; + py_clear_ref(&filters); /* * Dont apply and type conversions to the variable value if @@ -908,28 +892,28 @@ res = varvalue; varvalue = NULL; goto success; /* break out early */ } - if (varvalue != Py_None) { + if (py_object_isnot(varvalue, Py_None)) { tmp = PyObject_Str(varvalue); if (tmp == NULL) { goto error; } if (PyList_Append(res_parts, tmp) < 0) { - Py_DECREF(tmp); tmp = NULL; + py_clear_ref(&tmp); goto error; } - Py_DECREF(tmp); + py_clear_ref(&tmp); } - Py_DECREF(varvalue); varvalue = NULL; + py_clear_ref(&varvalue); /* append the rest of the string */ tmp = PyUnicode_Substring(pb, idx+2, pb_len); if (tmp == NULL) { goto error; } if (PyList_Append(res_parts, tmp) < 0) { - Py_DECREF(tmp); tmp = NULL; + py_clear_ref(&tmp); goto error; } - Py_DECREF(tmp); tmp = NULL; + py_clear_ref(&tmp); } res = PyUnicode_Join(sstate->EMPTY_STR, res_parts); @@ -950,10 +934,10 @@ error: Py_XDECREF(varname); Py_XDECREF(varvalue); + Py_XDECREF(filters); Py_XDECREF(parts); Py_XDECREF(res_parts); Py_XDECREF(res); - Py_XDECREF(filters); return NULL; } @@ -988,8 +972,7 @@ return NULL; } if (s_len < 4) { - Py_INCREF(s); - return s; + return Py_NewRef(s); } sstate = PyModule_GetState(self); @@ -1003,8 +986,7 @@ return NULL; } if (start == -1) { - Py_INCREF(s); - return s; + return Py_NewRef(s); } result = PyDict_GetItem(cache, s); /* borrowed */ @@ -1016,8 +998,7 @@ s); } else { - Py_INCREF(result); /* need ownership */ - return result; + return Py_NewRef(result); } } @@ -1036,10 +1017,10 @@ goto error; } if (PyList_Append(result, tmp) < 0) { - Py_DECREF(tmp); + py_clear_ref(&tmp); goto error; } - Py_DECREF(tmp); tmp = NULL; + py_clear_ref(&tmp); } end = PyUnicode_Find(s, sstate->ENDTOK, start+2, s_len, 1); if (end == -2) { @@ -1061,17 +1042,16 @@ } if (PyTuple_Size(tmp) != 2) { PyErr_SetString(PyExc_TypeError, "tuple of size 2 expected"); - Py_DECREF(tmp); + py_clear_ref(&tmp); goto error; } /* Unpack the result tuple */ tmp2 = PyTuple_GetItem(tmp, 0); /* borrowed -- cannot fail */ Py_DECREF(varname); - Py_INCREF(tmp2); - varname = tmp2; tmp2 = NULL; - filters = PyTuple_GetItem(tmp, 1); /* borrowed -- cannot fail */ - Py_INCREF(filters); - Py_DECREF(tmp); tmp = NULL; + varname = Py_NewRef(tmp2); tmp2 = NULL; + /* borrowed -- cannot fail -- need ownership */ + filters = Py_NewRef(PyTuple_GetItem(tmp, 1)); + py_clear_ref(&tmp); tmp = PyObject_CallMethod( config, "_getvar_s_with_cache_info", "O", varname); @@ -1080,14 +1060,12 @@ cacheable = 1; if (PySequence_Contains(filters, sstate->NONE_FILTER) == 1) { PyErr_Clear(); - Py_INCREF(Py_None); - varvalue = Py_None; + varvalue = Py_NewRef(Py_None); } else { if (PySequence_Contains(filters, sstate->EMPTY_FILTER) == 1) { PyErr_Clear(); - Py_INCREF(sstate->EMPTY_STR); - varvalue = sstate->EMPTY_STR; + varvalue = Py_NewRef(sstate->EMPTY_STR); } else { PyErr_Fetch(&err_type, &err_value, &err_tb); @@ -1105,22 +1083,22 @@ } else { if (PyTuple_Size(tmp) != 2) { - Py_DECREF(tmp); + py_clear_ref(&tmp); PyErr_SetString(PyExc_TypeError, "tuple of size 2 expected"); goto error; } /* unpack the result */ - varvalue = PyTuple_GetItem(tmp, 0); /* borrowed -- but want own */ - Py_INCREF(varvalue); + /* borrowed -- but want own */ + varvalue = Py_NewRef(PyTuple_GetItem(tmp, 0)); cacheable = PyObject_IsTrue(PyTuple_GetItem(tmp, 1)); - Py_DECREF(tmp); tmp = NULL; + py_clear_ref(&tmp); } if (!cacheable) { use_cache = 0; } - Py_DECREF(varname); varname = NULL; + py_clear_ref(&varname); tmp = PyObject_CallMethod( config, "_apply_filters", "OO", filters, varvalue); @@ -1130,7 +1108,7 @@ Py_DECREF(varvalue); varvalue = tmp; tmp = NULL; - Py_DECREF(filters); filters = NULL; + py_clear_ref(&filters); rest = end + 2; /* 2 == len(ENDTOK) */ @@ -1145,16 +1123,16 @@ } /* Handle None like the empty string */ - if (varvalue != Py_None) { + if (py_object_isnot(varvalue, Py_None)) { tmp = PyObject_Str(varvalue); if (tmp == NULL) { goto error; } if (PyList_Append(result, tmp) < 0) { - Py_DECREF(tmp); + py_clear_ref(&tmp); goto error; } - Py_DECREF(tmp); tmp = NULL; + py_clear_ref(&tmp); } /* don't re-evaluate because `self.getvar_s()` expands already */ @@ -1170,10 +1148,10 @@ goto error; } if (PyList_Append(result, tmp) < 0) { - Py_DECREF(tmp); + py_clear_ref(&tmp); goto error; } - Py_DECREF(tmp); tmp = NULL; + py_clear_ref(&tmp); } tmp = PyUnicode_Join(sstate->EMPTY_STR, result); @@ -1215,8 +1193,7 @@ PyErr_SetString(PyExc_RuntimeError, "_MISSING already set"); return NULL; } - Py_INCREF(missing); - sstate->MISSING = missing; + sstate->MISSING = Py_NewRef(missing); Py_RETURN_NONE; }
