comparison configmix/_speedups.c @ 566:dc2e2384c8c7

fast_interpolate_variables(): allow omission of the cache variable. Allow also setting the cache variable to None. All these settings disable the interpolation cache.
author Franz Glasner <fzglas.hg@dom66.de>
date Fri, 07 Jan 2022 00:37:04 +0100
parents 5c617d870bb8
children f454889e41fa
comparison
equal deleted inserted replaced
565:5c617d870bb8 566:dc2e2384c8c7
949 PyObject * 949 PyObject *
950 fast_interpolate_variables(PyObject *self, PyObject *args) 950 fast_interpolate_variables(PyObject *self, PyObject *args)
951 { 951 {
952 PyObject *config; 952 PyObject *config;
953 PyObject *s; 953 PyObject *s;
954 PyObject *cache; 954 PyObject *cache = NULL;
955 955
956 Py_ssize_t s_len; 956 Py_ssize_t s_len;
957 Py_ssize_t start, rest, end; 957 Py_ssize_t start, rest, end;
958 PyObject *tmp; 958 PyObject *tmp;
959 PyObject *result = NULL; 959 PyObject *result = NULL;
964 PyObject *err_value; 964 PyObject *err_value;
965 PyObject *err_tb; 965 PyObject *err_tb;
966 int use_cache, cacheable; 966 int use_cache, cacheable;
967 struct speedups_state *sstate; 967 struct speedups_state *sstate;
968 968
969 if (!PyArg_UnpackTuple(args, "s", 3, 3, &config, &s, &cache)) { 969 if (!PyArg_UnpackTuple(args, "s", 2, 3, &config, &s, &cache)) {
970 return NULL; 970 return NULL;
971 }
972 /* Disable caching if the cache param is given as None */
973 if ((cache != NULL) && py_object_is(cache, Py_None)) {
974 cache = NULL;
971 } 975 }
972 s_len = PyUnicode_GetLength(s); /* also an implicit type check */ 976 s_len = PyUnicode_GetLength(s); /* also an implicit type check */
973 if (s_len < 0) { 977 if (s_len < 0) {
974 return NULL; 978 return NULL;
975 } 979 }
989 } 993 }
990 if (start == -1) { 994 if (start == -1) {
991 return Py_NewRef(s); 995 return Py_NewRef(s);
992 } 996 }
993 997
994 result = PyDict_GetItem(cache, s); /* borrowed */ 998 if (cache != NULL) {
995 if (result != NULL) { 999 result = PyDict_GetItem(cache, s); /* borrowed */
996 if (result == sstate->MISSING) { 1000 if (result != NULL) {
997 return PyErr_Format( 1001 if (result == sstate->MISSING) {
998 PyExc_KeyError, 1002 return PyErr_Format(
999 "Cannot interpolate variables in string %R (cached)", 1003 PyExc_KeyError,
1000 s); 1004 "Cannot interpolate variables in string %R (cached)",
1001 } 1005 s);
1002 else { 1006 }
1003 return Py_NewRef(result); 1007 else {
1008 return Py_NewRef(result);
1009 }
1004 } 1010 }
1005 } 1011 }
1006 1012
1007 result = PyList_New(0); 1013 result = PyList_New(0);
1008 if (result == 0) { 1014 if (result == 0) {
1068 if (PySequence_Contains(filters, sstate->EMPTY_FILTER) == 1) { 1074 if (PySequence_Contains(filters, sstate->EMPTY_FILTER) == 1) {
1069 PyErr_Clear(); 1075 PyErr_Clear();
1070 varvalue = Py_NewRef(sstate->EMPTY_STR); 1076 varvalue = Py_NewRef(sstate->EMPTY_STR);
1071 } 1077 }
1072 else { 1078 else {
1073 PyErr_Fetch(&err_type, &err_value, &err_tb); 1079 if (cache != NULL) {
1074 /* this does NOT steal */ 1080 PyErr_Fetch(&err_type, &err_value, &err_tb);
1075 PyDict_SetItem(cache, s, sstate->MISSING); 1081 /* this does NOT steal */
1076 PyErr_Restore(err_type, err_value, err_tb); 1082 PyDict_SetItem(cache, s, sstate->MISSING);
1083 PyErr_Restore(err_type, err_value, err_tb);
1084 }
1077 goto error; 1085 goto error;
1078 } 1086 }
1079 } 1087 }
1080 } 1088 }
1081 else { 1089 else {
1159 goto error; 1167 goto error;
1160 } 1168 }
1161 py_transfer_owned(&result, &tmp); 1169 py_transfer_owned(&result, &tmp);
1162 1170
1163 success: 1171 success:
1164 if (use_cache) { 1172 if (use_cache && (cache != NULL)) {
1165 if (PyDict_SetItem(cache, s, result) < 0) { 1173 if (PyDict_SetItem(cache, s, result) < 0) {
1166 PyErr_Clear(); /* clear any cache-related error */ 1174 PyErr_Clear(); /* clear any cache-related error */
1167 } 1175 }
1168 } 1176 }
1169 return result; 1177 return result;