Mercurial > hgrepos > Python > libs > ConfigMix
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[] = { |
