# HG changeset patch # User Gregory Szorc # Date 1538511183 25200 # Node ID 77492c10a35ba0242f474a4b6322844481328147 # Parent a91398dc73abe450ead380b285d97f6361289362 cext: use modern buffer protocol in patches() PyObject_AsCharBuffer() is part of the "Old Buffer Protocol," which has been deprecated for years. Let's port away from it. PyBuffer_GetBuffer() must be paired with PyBuffer_Release(), hence the added "goto cleanup" in a failure case. We don't bump the extension version because the API has not changed. Differential Revision: https://phab.mercurial-scm.org/D4840 diff -r a91398dc73ab -r 77492c10a35b mercurial/cext/mpatch.c --- a/mercurial/cext/mpatch.c Mon Oct 01 14:44:27 2018 -0400 +++ b/mercurial/cext/mpatch.c Tue Oct 02 13:13:03 2018 -0700 @@ -72,10 +72,10 @@ { PyObject *text, *bins, *result; struct mpatch_flist *patch; - const char *in; + Py_buffer buffer; int r = 0; char *out; - Py_ssize_t len, outlen, inlen; + Py_ssize_t len, outlen; if (!PyArg_ParseTuple(args, "OO:mpatch", &text, &bins)) return NULL; @@ -87,17 +87,19 @@ return text; } - if (PyObject_AsCharBuffer(text, &in, &inlen)) + if (PyObject_GetBuffer(text, &buffer, PyBUF_CONTIG_RO)) { return NULL; + } patch = mpatch_fold(bins, cpygetitem, 0, len); if (!patch) { /* error already set or memory error */ if (!PyErr_Occurred()) PyErr_NoMemory(); - return NULL; + result = NULL; + goto cleanup; } - outlen = mpatch_calcsize(inlen, patch); + outlen = mpatch_calcsize(buffer.len, patch); if (outlen < 0) { r = (int)outlen; result = NULL; @@ -112,7 +114,7 @@ /* clang-format off */ { Py_BEGIN_ALLOW_THREADS - r = mpatch_apply(out, in, inlen, patch); + r = mpatch_apply(out, buffer.buf, buffer.len, patch); Py_END_ALLOW_THREADS } /* clang-format on */ @@ -122,6 +124,7 @@ } cleanup: mpatch_lfree(patch); + PyBuffer_Release(&buffer); if (!result && !PyErr_Occurred()) setpyerr(r); return result;