comparison configmix/_speedups.c @ 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
comparison
equal deleted inserted replaced
558:7a3c311991d7 559:bb160a1e67d7
6 * :License: BSD-3-Clause. See LICENSE.txt for details. 6 * :License: BSD-3-Clause. See LICENSE.txt for details.
7 */ 7 */
8 8
9 #define PY_SSIZE_T_CLEAN 9 #define PY_SSIZE_T_CLEAN
10 #include "Python.h" 10 #include "Python.h"
11
12 #include "_py_helper.h"
11 13
12 14
13 const char _id[] = "@(#)configmix._speedups $Header$"; 15 const char _id[] = "@(#)configmix._speedups $Header$";
14 static const char release[] = "|VCSRevision|"; 16 static const char release[] = "|VCSRevision|";
15 static const char date[] = "|VCSJustDate|"; 17 static const char date[] = "|VCSJustDate|";
275 if (s_len < 0) { 277 if (s_len < 0) {
276 return NULL; 278 return NULL;
277 } 279 }
278 } 280 }
279 if (s_len == 0) { 281 if (s_len == 0) {
280 Py_INCREF(s); 282 return Py_NewRef(s);
281 return s;
282 } 283 }
283 find = PyUnicode_FindChar(s, '%', 0, s_len, 1); 284 find = PyUnicode_FindChar(s, '%', 0, s_len, 1);
284 if (find == -2) { 285 if (find == -2) {
285 return NULL; 286 return NULL;
286 } 287 }
287 if (find == -1) { 288 if (find == -1) {
288 Py_INCREF(s); 289 return Py_NewRef(s);
289 return s;
290 } 290 }
291 291
292 if (sstate == NULL) { 292 if (sstate == NULL) {
293 sstate = PyModule_GetState(self); 293 sstate = PyModule_GetState(self);
294 if (sstate == NULL) { 294 if (sstate == NULL) {
315 } 315 }
316 /* 316 /*
317 * The first item may be also the empty string if `s' starts with 317 * The first item may be also the empty string if `s' starts with
318 * a quoted character. 318 * a quoted character.
319 */ 319 */
320 Py_INCREF(o); /* because PyTuple_SetItem steals -- and o is borrowed */ 320 PyTuple_SetItem(res_parts, 0, Py_NewRef(o));
321 PyTuple_SetItem(res_parts, 0, o);
322 321
323 for (i=1; i<parts_len; i++) { 322 for (i=1; i<parts_len; i++) {
324 pb = PyList_GetItem(parts, i); /* borrowed */ 323 pb = PyList_GetItem(parts, i); /* borrowed */
325 pb_len = PyUnicode_GetLength(pb); 324 pb_len = PyUnicode_GetLength(pb);
326 if (pb_len < 1) { 325 if (pb_len < 1) {
420 s_len = PyUnicode_GetLength(s); 419 s_len = PyUnicode_GetLength(s);
421 if (s_len < 0) { 420 if (s_len < 0) {
422 return NULL; 421 return NULL;
423 } 422 }
424 if (s_len == 0) { 423 if (s_len == 0) {
425 Py_INCREF(s); 424 return Py_NewRef(s);
426 return s;
427 } 425 }
428 need_quoting = 0; 426 need_quoting = 0;
429 for (i=0; i<s_len; i++) { 427 for (i=0; i<s_len; i++) {
430 c = PyUnicode_ReadChar(s, i); /* type already checked */ 428 c = PyUnicode_ReadChar(s, i); /* type already checked */
431 switch (c) { 429 switch (c) {
447 /* VOID */ 445 /* VOID */
448 ; 446 ;
449 } 447 }
450 } 448 }
451 if (!need_quoting) { 449 if (!need_quoting) {
452 Py_INCREF(s); 450 return Py_NewRef(s);
453 return s;
454 } 451 }
455 sstate = PyModule_GetState(self); 452 sstate = PyModule_GetState(self);
456 if (sstate == NULL) { 453 if (sstate == NULL) {
457 PyErr_SetString(PyExc_RuntimeError, "no module state available"); 454 PyErr_SetString(PyExc_RuntimeError, "no module state available");
458 return NULL; 455 return NULL;
549 if (sep == -1) { 546 if (sep == -1) {
550 res = PyTuple_New(2); 547 res = PyTuple_New(2);
551 if (res == NULL) { 548 if (res == NULL) {
552 goto error; 549 goto error;
553 } 550 }
554 Py_INCREF(varname); /* because PyTuple_SetItem steals */ 551 PyTuple_SetItem(res, 0, Py_NewRef(varname)); /* steals */
555 PyTuple_SetItem(res, 0, varname); /* steals */
556 filters = PyList_New(0); 552 filters = PyList_New(0);
557 if (filters == NULL) { 553 if (filters == NULL) {
558 goto error; 554 goto error;
559 } 555 }
560 PyTuple_SetItem(res, 1, filters); /* steals */ 556 PyTuple_SetItem(res, 1, filters); /* steals */
572 tmp = PyObject_CallMethod(filters, "strip", NULL); 568 tmp = PyObject_CallMethod(filters, "strip", NULL);
573 if (tmp == NULL) { 569 if (tmp == NULL) {
574 goto error; 570 goto error;
575 } 571 }
576 Py_DECREF(filters); 572 Py_DECREF(filters);
577 filters = tmp; 573 filters = tmp; tmp = NULL;
578 574
579 if (PyObject_Not(filters)) { 575 if (PyObject_Not(filters)) {
580 Py_DECREF(filters); filters = NULL; 576 py_clear_ref(&filters);
581 577
582 res = PyTuple_New(2); 578 res = PyTuple_New(2);
583 if (res == NULL) { 579 if (res == NULL) {
584 goto error; 580 goto error;
585 } 581 }
604 tmp = PyUnicode_Split(filters, sstate->FILTER_SEPARATOR, -1); 600 tmp = PyUnicode_Split(filters, sstate->FILTER_SEPARATOR, -1);
605 if (tmp == NULL) { 601 if (tmp == NULL) {
606 goto error; 602 goto error;
607 } 603 }
608 Py_DECREF(filters); 604 Py_DECREF(filters);
609 filters = tmp; 605 filters = tmp; tmp = NULL;
610 606
611 res = PyTuple_New(2); 607 res = PyTuple_New(2);
612 if (res == NULL) { 608 if (res == NULL) {
613 goto error; 609 goto error;
614 } 610 }
653 if (ns_idx == -1) { 649 if (ns_idx == -1) {
654 res = PyTuple_New(2); 650 res = PyTuple_New(2);
655 if (res == NULL) { 651 if (res == NULL) {
656 return NULL; 652 return NULL;
657 } 653 }
658 Py_INCREF(Py_None); 654 PyTuple_SetItem(res, 0, Py_NewRef(Py_None)); /* steals */
659 PyTuple_SetItem(res, 0, Py_None); /* steals */ 655 PyTuple_SetItem(res, 1, Py_NewRef(varname)); /* steals */
660 Py_INCREF(varname);
661 PyTuple_SetItem(res, 1, varname); /* steals */
662 return res; 656 return res;
663 } 657 }
664 658
665 res = PyTuple_New(2); 659 res = PyTuple_New(2);
666 if (res == NULL) { 660 if (res == NULL) {
726 if (s_len < 0) { 720 if (s_len < 0) {
727 return NULL; 721 return NULL;
728 } 722 }
729 if (s_len < 4) { 723 if (s_len < 4) {
730 PyErr_Clear(); 724 PyErr_Clear();
731 Py_INCREF(s); 725 return Py_NewRef(s);
732 return s;
733 } 726 }
734 sstate = PyModule_GetState(self); 727 sstate = PyModule_GetState(self);
735 if (sstate == NULL) { 728 if (sstate == NULL) {
736 PyErr_SetString(PyExc_RuntimeError, "no module state available"); 729 PyErr_SetString(PyExc_RuntimeError, "no module state available");
737 return NULL; 730 return NULL;
738 } 731 }
739 732
740 idx = PyUnicode_Find(s, sstate->STARTTOK, 0, s_len, 1); 733 idx = PyUnicode_Find(s, sstate->STARTTOK, 0, s_len, 1);
741 if (idx < 0) { 734 if (idx < 0) {
742 PyErr_Clear(); 735 PyErr_Clear();
743 Py_INCREF(s); 736 return Py_NewRef(s);
744 return s;
745 } 737 }
746 738
747 res = PyDict_GetItem(cache, s); /* borrowed */ 739 res = PyDict_GetItem(cache, s); /* borrowed */
748 if (res != NULL) { 740 if (res != NULL) {
749 if (res == sstate->MISSING) { 741 if (res == sstate->MISSING) {
751 PyExc_KeyError, 743 PyExc_KeyError,
752 "Cannot interpolate variables in string %R (cached)", 744 "Cannot interpolate variables in string %R (cached)",
753 s); 745 s);
754 } 746 }
755 else { 747 else {
756 Py_INCREF(res); 748 return Py_NewRef(res);
757 return res;
758 } 749 }
759 } 750 }
760 751
761 parts = PyUnicode_Split(s, sstate->STARTTOK, -1); 752 parts = PyUnicode_Split(s, sstate->STARTTOK, -1);
762 if (parts == NULL) { 753 if (parts == NULL) {
778 /* 769 /*
779 * The first item may be also the empty string if `s' starts with 770 * The first item may be also the empty string if `s' starts with
780 * an interpolation token. 771 * an interpolation token.
781 */ 772 */
782 first_part_is_empty = PyObject_Not(tmp); 773 first_part_is_empty = PyObject_Not(tmp);
783 Py_INCREF(tmp); /* because PyList_SetItem steals -- and tmp is borrowed */ 774 /* steals -- cannot fail here -- NOTE: tmp is currently borrowed */
784 PyList_SetItem(res_parts, 0, tmp); /* steals -- cannot fail here */ 775 PyList_SetItem(res_parts, 0, Py_NewRef(tmp));
785 tmp = NULL; 776 tmp = NULL;
786 777
787 for (i=1; i<parts_len; i++) { 778 for (i=1; i<parts_len; i++) {
788 pb = PyList_GetItem(parts, i); /* borrowed */ 779 pb = PyList_GetItem(parts, i); /* borrowed */
789 pb_len = PyUnicode_GetLength(pb); 780 pb_len = PyUnicode_GetLength(pb);
823 if (tmp == NULL) { 814 if (tmp == NULL) {
824 goto error; 815 goto error;
825 } 816 }
826 if (PyTuple_Size(tmp) != 2) { 817 if (PyTuple_Size(tmp) != 2) {
827 PyErr_SetString(PyExc_TypeError, "tuple of size 2 expected"); 818 PyErr_SetString(PyExc_TypeError, "tuple of size 2 expected");
828 Py_DECREF(tmp); 819 py_clear_ref(&tmp);
829 goto error; 820 goto error;
830 } 821 }
831 /* Unpack the result tuple */ 822 /* Unpack the result tuple */
832 tmp2 = PyTuple_GetItem(tmp, 0); /* borrowed -- cannot fail */ 823 tmp2 = PyTuple_GetItem(tmp, 0); /* borrowed -- cannot fail */
833 Py_DECREF(varname); 824 Py_DECREF(varname);
834 Py_INCREF(tmp2); 825 varname = Py_NewRef(tmp2); tmp2 = NULL;
835 varname = tmp2; 826 /* borrowed -- cannot fail -- want own */
836 tmp2 = NULL; 827 filters = Py_NewRef(PyTuple_GetItem(tmp, 1));
837 filters = PyTuple_GetItem(tmp, 1); /* borrowed -- cannot fail */ 828 py_clear_ref(&tmp);
838 Py_INCREF(filters);
839 Py_DECREF(tmp);
840 tmp = NULL;
841 829
842 tmp = PyObject_CallMethod( 830 tmp = PyObject_CallMethod(
843 config, "_getvar_s_with_cache_info", "O", varname); 831 config, "_getvar_s_with_cache_info", "O", varname);
844 if (tmp == NULL) { 832 if (tmp == NULL) {
845 if (PyErr_ExceptionMatches(PyExc_KeyError)) { 833 if (PyErr_ExceptionMatches(PyExc_KeyError)) {
846 /* XXX TBD handle KeyError (None and Empty-filter) */ 834 /* XXX TBD handle KeyError (None and Empty-filter) */
847 cacheable = 1; 835 cacheable = 1;
848 if (PySequence_Contains(filters, sstate->NONE_FILTER) == 1) { 836 if (PySequence_Contains(filters, sstate->NONE_FILTER) == 1) {
849 PyErr_Clear(); 837 PyErr_Clear();
850 Py_INCREF(Py_None); 838 varvalue = Py_NewRef(Py_None);
851 varvalue = Py_None;
852 } 839 }
853 else { 840 else {
854 if (PySequence_Contains(filters, sstate->EMPTY_FILTER) == 1) { 841 if (PySequence_Contains(filters, sstate->EMPTY_FILTER) == 1) {
855 PyErr_Clear(); 842 PyErr_Clear();
856 Py_INCREF(sstate->EMPTY_STR); 843 varvalue = Py_NewRef(sstate->EMPTY_STR);
857 varvalue = sstate->EMPTY_STR;
858 } 844 }
859 else { 845 else {
860 PyErr_Fetch(&err_type, &err_value, &err_tb); 846 PyErr_Fetch(&err_type, &err_value, &err_tb);
861 /* this does NOT steal */ 847 /* this does NOT steal */
862 PyDict_SetItem(cache, s, sstate->MISSING); 848 PyDict_SetItem(cache, s, sstate->MISSING);
870 goto error; 856 goto error;
871 } 857 }
872 } 858 }
873 else { 859 else {
874 if (PyTuple_Size(tmp) != 2) { 860 if (PyTuple_Size(tmp) != 2) {
875 Py_DECREF(tmp); tmp = NULL; 861 py_clear_ref(&tmp);
876 PyErr_SetString(PyExc_TypeError, "tuple of size 2 expected"); 862 PyErr_SetString(PyExc_TypeError, "tuple of size 2 expected");
877 goto error; 863 goto error;
878 } 864 }
879 /* unpack the result */ 865 /* unpack the result */
880 varvalue = PyTuple_GetItem(tmp, 0); /* borrowed -- but want own */ 866 /* borrowed -- but want own */
881 Py_INCREF(varvalue); 867 varvalue = Py_NewRef(PyTuple_GetItem(tmp, 0));
882 cacheable = PyObject_IsTrue(PyTuple_GetItem(tmp, 1)); 868 cacheable = PyObject_IsTrue(PyTuple_GetItem(tmp, 1));
883 Py_DECREF(tmp); tmp = NULL; 869 py_clear_ref(&tmp);
884 } 870 }
885 871
886 if (!cacheable) { 872 if (!cacheable) {
887 use_cache = 0; 873 use_cache = 0;
888 } 874 }
889 875
890 Py_DECREF(varname); varname = NULL; 876 py_clear_ref(&varname);
891 877
892 tmp = PyObject_CallMethod( 878 tmp = PyObject_CallMethod(
893 config, "_apply_filters", "OO", filters, varvalue); 879 config, "_apply_filters", "OO", filters, varvalue);
894 if (tmp == NULL) { 880 if (tmp == NULL) {
895 goto error; 881 goto error;
896 } 882 }
897 Py_DECREF(varvalue); 883 py_clear_ref(&varvalue);
898 varvalue = tmp; 884
899 tmp = NULL; 885 py_clear_ref(&filters);
900
901 Py_DECREF(filters); filters = NULL;
902 886
903 /* 887 /*
904 * Dont apply and type conversions to the variable value if 888 * Dont apply and type conversions to the variable value if
905 * the whole `s` is just one expansion 889 * the whole `s` is just one expansion
906 */ 890 */
907 if (first_part_is_empty && (i == 1) && (pb_len == s_len - 2) && (idx == pb_len - 2)) { 891 if (first_part_is_empty && (i == 1) && (pb_len == s_len - 2) && (idx == pb_len - 2)) {
908 res = varvalue; varvalue = NULL; 892 res = varvalue; varvalue = NULL;
909 goto success; /* break out early */ 893 goto success; /* break out early */
910 } 894 }
911 if (varvalue != Py_None) { 895 if (py_object_isnot(varvalue, Py_None)) {
912 tmp = PyObject_Str(varvalue); 896 tmp = PyObject_Str(varvalue);
913 if (tmp == NULL) { 897 if (tmp == NULL) {
914 goto error; 898 goto error;
915 } 899 }
916 if (PyList_Append(res_parts, tmp) < 0) { 900 if (PyList_Append(res_parts, tmp) < 0) {
917 Py_DECREF(tmp); tmp = NULL; 901 py_clear_ref(&tmp);
918 goto error; 902 goto error;
919 } 903 }
920 Py_DECREF(tmp); 904 py_clear_ref(&tmp);
921 } 905 }
922 Py_DECREF(varvalue); varvalue = NULL; 906 py_clear_ref(&varvalue);
923 /* append the rest of the string */ 907 /* append the rest of the string */
924 tmp = PyUnicode_Substring(pb, idx+2, pb_len); 908 tmp = PyUnicode_Substring(pb, idx+2, pb_len);
925 if (tmp == NULL) { 909 if (tmp == NULL) {
926 goto error; 910 goto error;
927 } 911 }
928 if (PyList_Append(res_parts, tmp) < 0) { 912 if (PyList_Append(res_parts, tmp) < 0) {
929 Py_DECREF(tmp); tmp = NULL; 913 py_clear_ref(&tmp);
930 goto error; 914 goto error;
931 } 915 }
932 Py_DECREF(tmp); tmp = NULL; 916 py_clear_ref(&tmp);
933 } 917 }
934 918
935 res = PyUnicode_Join(sstate->EMPTY_STR, res_parts); 919 res = PyUnicode_Join(sstate->EMPTY_STR, res_parts);
936 if (res == NULL) { 920 if (res == NULL) {
937 goto error; 921 goto error;
948 return res; 932 return res;
949 933
950 error: 934 error:
951 Py_XDECREF(varname); 935 Py_XDECREF(varname);
952 Py_XDECREF(varvalue); 936 Py_XDECREF(varvalue);
937 Py_XDECREF(filters);
953 Py_XDECREF(parts); 938 Py_XDECREF(parts);
954 Py_XDECREF(res_parts); 939 Py_XDECREF(res_parts);
955 Py_XDECREF(res); 940 Py_XDECREF(res);
956 Py_XDECREF(filters);
957 return NULL; 941 return NULL;
958 } 942 }
959 943
960 944
961 static 945 static
986 s_len = PyUnicode_GetLength(s); /* also an implicit type check */ 970 s_len = PyUnicode_GetLength(s); /* also an implicit type check */
987 if (s_len < 0) { 971 if (s_len < 0) {
988 return NULL; 972 return NULL;
989 } 973 }
990 if (s_len < 4) { 974 if (s_len < 4) {
991 Py_INCREF(s); 975 return Py_NewRef(s);
992 return s;
993 } 976 }
994 977
995 sstate = PyModule_GetState(self); 978 sstate = PyModule_GetState(self);
996 if (sstate == NULL) { 979 if (sstate == NULL) {
997 PyErr_SetString(PyExc_RuntimeError, "no module state available"); 980 PyErr_SetString(PyExc_RuntimeError, "no module state available");
1001 start = PyUnicode_Find(s, sstate->STARTTOK, 0, s_len, 1); 984 start = PyUnicode_Find(s, sstate->STARTTOK, 0, s_len, 1);
1002 if (start == -2) { 985 if (start == -2) {
1003 return NULL; 986 return NULL;
1004 } 987 }
1005 if (start == -1) { 988 if (start == -1) {
1006 Py_INCREF(s); 989 return Py_NewRef(s);
1007 return s;
1008 } 990 }
1009 991
1010 result = PyDict_GetItem(cache, s); /* borrowed */ 992 result = PyDict_GetItem(cache, s); /* borrowed */
1011 if (result != NULL) { 993 if (result != NULL) {
1012 if (result == sstate->MISSING) { 994 if (result == sstate->MISSING) {
1014 PyExc_KeyError, 996 PyExc_KeyError,
1015 "Cannot interpolate variables in string %R (cached)", 997 "Cannot interpolate variables in string %R (cached)",
1016 s); 998 s);
1017 } 999 }
1018 else { 1000 else {
1019 Py_INCREF(result); /* need ownership */ 1001 return Py_NewRef(result);
1020 return result;
1021 } 1002 }
1022 } 1003 }
1023 1004
1024 result = PyList_New(0); 1005 result = PyList_New(0);
1025 if (result == 0) { 1006 if (result == 0) {
1034 tmp = PyUnicode_Substring(s, rest, start); 1015 tmp = PyUnicode_Substring(s, rest, start);
1035 if (tmp == NULL) { 1016 if (tmp == NULL) {
1036 goto error; 1017 goto error;
1037 } 1018 }
1038 if (PyList_Append(result, tmp) < 0) { 1019 if (PyList_Append(result, tmp) < 0) {
1039 Py_DECREF(tmp); 1020 py_clear_ref(&tmp);
1040 goto error; 1021 goto error;
1041 } 1022 }
1042 Py_DECREF(tmp); tmp = NULL; 1023 py_clear_ref(&tmp);
1043 } 1024 }
1044 end = PyUnicode_Find(s, sstate->ENDTOK, start+2, s_len, 1); 1025 end = PyUnicode_Find(s, sstate->ENDTOK, start+2, s_len, 1);
1045 if (end == -2) { 1026 if (end == -2) {
1046 goto error; 1027 goto error;
1047 } 1028 }
1059 if (tmp == NULL) { 1040 if (tmp == NULL) {
1060 goto error; 1041 goto error;
1061 } 1042 }
1062 if (PyTuple_Size(tmp) != 2) { 1043 if (PyTuple_Size(tmp) != 2) {
1063 PyErr_SetString(PyExc_TypeError, "tuple of size 2 expected"); 1044 PyErr_SetString(PyExc_TypeError, "tuple of size 2 expected");
1064 Py_DECREF(tmp); 1045 py_clear_ref(&tmp);
1065 goto error; 1046 goto error;
1066 } 1047 }
1067 /* Unpack the result tuple */ 1048 /* Unpack the result tuple */
1068 tmp2 = PyTuple_GetItem(tmp, 0); /* borrowed -- cannot fail */ 1049 tmp2 = PyTuple_GetItem(tmp, 0); /* borrowed -- cannot fail */
1069 Py_DECREF(varname); 1050 Py_DECREF(varname);
1070 Py_INCREF(tmp2); 1051 varname = Py_NewRef(tmp2); tmp2 = NULL;
1071 varname = tmp2; tmp2 = NULL; 1052 /* borrowed -- cannot fail -- need ownership */
1072 filters = PyTuple_GetItem(tmp, 1); /* borrowed -- cannot fail */ 1053 filters = Py_NewRef(PyTuple_GetItem(tmp, 1));
1073 Py_INCREF(filters); 1054 py_clear_ref(&tmp);
1074 Py_DECREF(tmp); tmp = NULL;
1075 1055
1076 tmp = PyObject_CallMethod( 1056 tmp = PyObject_CallMethod(
1077 config, "_getvar_s_with_cache_info", "O", varname); 1057 config, "_getvar_s_with_cache_info", "O", varname);
1078 if (tmp == NULL) { 1058 if (tmp == NULL) {
1079 if (PyErr_ExceptionMatches(PyExc_KeyError)) { 1059 if (PyErr_ExceptionMatches(PyExc_KeyError)) {
1080 cacheable = 1; 1060 cacheable = 1;
1081 if (PySequence_Contains(filters, sstate->NONE_FILTER) == 1) { 1061 if (PySequence_Contains(filters, sstate->NONE_FILTER) == 1) {
1082 PyErr_Clear(); 1062 PyErr_Clear();
1083 Py_INCREF(Py_None); 1063 varvalue = Py_NewRef(Py_None);
1084 varvalue = Py_None;
1085 } 1064 }
1086 else { 1065 else {
1087 if (PySequence_Contains(filters, sstate->EMPTY_FILTER) == 1) { 1066 if (PySequence_Contains(filters, sstate->EMPTY_FILTER) == 1) {
1088 PyErr_Clear(); 1067 PyErr_Clear();
1089 Py_INCREF(sstate->EMPTY_STR); 1068 varvalue = Py_NewRef(sstate->EMPTY_STR);
1090 varvalue = sstate->EMPTY_STR;
1091 } 1069 }
1092 else { 1070 else {
1093 PyErr_Fetch(&err_type, &err_value, &err_tb); 1071 PyErr_Fetch(&err_type, &err_value, &err_tb);
1094 /* this does NOT steal */ 1072 /* this does NOT steal */
1095 PyDict_SetItem(cache, s, sstate->MISSING); 1073 PyDict_SetItem(cache, s, sstate->MISSING);
1103 goto error; 1081 goto error;
1104 } 1082 }
1105 } 1083 }
1106 else { 1084 else {
1107 if (PyTuple_Size(tmp) != 2) { 1085 if (PyTuple_Size(tmp) != 2) {
1108 Py_DECREF(tmp); 1086 py_clear_ref(&tmp);
1109 PyErr_SetString(PyExc_TypeError, "tuple of size 2 expected"); 1087 PyErr_SetString(PyExc_TypeError, "tuple of size 2 expected");
1110 goto error; 1088 goto error;
1111 } 1089 }
1112 /* unpack the result */ 1090 /* unpack the result */
1113 varvalue = PyTuple_GetItem(tmp, 0); /* borrowed -- but want own */ 1091 /* borrowed -- but want own */
1114 Py_INCREF(varvalue); 1092 varvalue = Py_NewRef(PyTuple_GetItem(tmp, 0));
1115 cacheable = PyObject_IsTrue(PyTuple_GetItem(tmp, 1)); 1093 cacheable = PyObject_IsTrue(PyTuple_GetItem(tmp, 1));
1116 Py_DECREF(tmp); tmp = NULL; 1094 py_clear_ref(&tmp);
1117 } 1095 }
1118 1096
1119 if (!cacheable) { 1097 if (!cacheable) {
1120 use_cache = 0; 1098 use_cache = 0;
1121 } 1099 }
1122 1100
1123 Py_DECREF(varname); varname = NULL; 1101 py_clear_ref(&varname);
1124 1102
1125 tmp = PyObject_CallMethod( 1103 tmp = PyObject_CallMethod(
1126 config, "_apply_filters", "OO", filters, varvalue); 1104 config, "_apply_filters", "OO", filters, varvalue);
1127 if (tmp == NULL) { 1105 if (tmp == NULL) {
1128 goto error; 1106 goto error;
1129 } 1107 }
1130 Py_DECREF(varvalue); 1108 Py_DECREF(varvalue);
1131 varvalue = tmp; tmp = NULL; 1109 varvalue = tmp; tmp = NULL;
1132 1110
1133 Py_DECREF(filters); filters = NULL; 1111 py_clear_ref(&filters);
1134 1112
1135 rest = end + 2; /* 2 == len(ENDTOK) */ 1113 rest = end + 2; /* 2 == len(ENDTOK) */
1136 1114
1137 /* 1115 /*
1138 * Dont apply and type conversions to the variable value if 1116 * Dont apply and type conversions to the variable value if
1143 result = varvalue; varvalue = NULL; 1121 result = varvalue; varvalue = NULL;
1144 goto success; /* break out early */ 1122 goto success; /* break out early */
1145 } 1123 }
1146 1124
1147 /* Handle None like the empty string */ 1125 /* Handle None like the empty string */
1148 if (varvalue != Py_None) { 1126 if (py_object_isnot(varvalue, Py_None)) {
1149 tmp = PyObject_Str(varvalue); 1127 tmp = PyObject_Str(varvalue);
1150 if (tmp == NULL) { 1128 if (tmp == NULL) {
1151 goto error; 1129 goto error;
1152 } 1130 }
1153 if (PyList_Append(result, tmp) < 0) { 1131 if (PyList_Append(result, tmp) < 0) {
1154 Py_DECREF(tmp); 1132 py_clear_ref(&tmp);
1155 goto error; 1133 goto error;
1156 } 1134 }
1157 Py_DECREF(tmp); tmp = NULL; 1135 py_clear_ref(&tmp);
1158 } 1136 }
1159 1137
1160 /* don't re-evaluate because `self.getvar_s()` expands already */ 1138 /* don't re-evaluate because `self.getvar_s()` expands already */
1161 start = PyUnicode_Find(s, sstate->STARTTOK, rest, s_len, 1); 1139 start = PyUnicode_Find(s, sstate->STARTTOK, rest, s_len, 1);
1162 if (start == -2) { 1140 if (start == -2) {
1168 tmp = PyUnicode_Substring(s, rest, s_len); 1146 tmp = PyUnicode_Substring(s, rest, s_len);
1169 if (tmp == NULL) { 1147 if (tmp == NULL) {
1170 goto error; 1148 goto error;
1171 } 1149 }
1172 if (PyList_Append(result, tmp) < 0) { 1150 if (PyList_Append(result, tmp) < 0) {
1173 Py_DECREF(tmp); 1151 py_clear_ref(&tmp);
1174 goto error; 1152 goto error;
1175 } 1153 }
1176 Py_DECREF(tmp); tmp = NULL; 1154 py_clear_ref(&tmp);
1177 } 1155 }
1178 1156
1179 tmp = PyUnicode_Join(sstate->EMPTY_STR, result); 1157 tmp = PyUnicode_Join(sstate->EMPTY_STR, result);
1180 if (tmp == NULL) { 1158 if (tmp == NULL) {
1181 goto error; 1159 goto error;
1213 } 1191 }
1214 if (sstate->MISSING != NULL) { 1192 if (sstate->MISSING != NULL) {
1215 PyErr_SetString(PyExc_RuntimeError, "_MISSING already set"); 1193 PyErr_SetString(PyExc_RuntimeError, "_MISSING already set");
1216 return NULL; 1194 return NULL;
1217 } 1195 }
1218 Py_INCREF(missing); 1196 sstate->MISSING = Py_NewRef(missing);
1219 sstate->MISSING = missing;
1220 Py_RETURN_NONE; 1197 Py_RETURN_NONE;
1221 } 1198 }
1222 1199
1223 1200
1224 static struct PyMethodDef speedups_methods[] = { 1201 static struct PyMethodDef speedups_methods[] = {