Mercurial > hg
changeset 39991:77492c10a35b
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
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Tue, 02 Oct 2018 13:13:03 -0700 |
parents | a91398dc73ab |
children | ec3c06a1c554 |
files | mercurial/cext/mpatch.c |
diffstat | 1 files changed, 9 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- 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;