From owner-dev-commits-ports-all@freebsd.org Sun Jul 25 16:17:20 2021 Return-Path: Delivered-To: dev-commits-ports-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 140C065C17B; Sun, 25 Jul 2021 16:17:20 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4GXp9W2zrWz3FSS; Sun, 25 Jul 2021 16:17:19 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4175926AEA; Sun, 25 Jul 2021 16:17:19 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 16PGHJje081724; Sun, 25 Jul 2021 16:17:19 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 16PGHJTb081723; Sun, 25 Jul 2021 16:17:19 GMT (envelope-from git) Date: Sun, 25 Jul 2021 16:17:19 GMT Message-Id: <202107251617.16PGHJTb081723@gitrepo.freebsd.org> To: ports-committers@FreeBSD.org, dev-commits-ports-all@FreeBSD.org, dev-commits-ports-main@FreeBSD.org From: Jan Beich Subject: git: bf17672f5058 - main - graphics/py-cairo: unbreak with python310 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: jbeich X-Git-Repository: ports X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: bf17672f50580a768f536ca3c5b243324e2cd64a Auto-Submitted: auto-generated X-BeenThere: dev-commits-ports-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the ports repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 25 Jul 2021 16:17:20 -0000 The branch main has been updated by jbeich: URL: https://cgit.FreeBSD.org/ports/commit/?id=bf17672f50580a768f536ca3c5b243324e2cd64a commit bf17672f50580a768f536ca3c5b243324e2cd64a Author: Jan Beich AuthorDate: 2021-07-25 15:17:51 +0000 Commit: Jan Beich CommitDate: 2021-07-25 16:17:05 +0000 graphics/py-cairo: unbreak with python310 >>> import cairo Traceback (most recent call last): File "", line 1, in File "/usr/local/lib/python3.10/site-packages/cairo/__init__.py", line 1, in from ._cairo import * # noqa: F401,F403 ImportError: /usr/local/lib/python3.10/site-packages/cairo/_cairo.cpython-310.so: Undefined symbol "PyObject_AsReadBuffer" ImportError: /usr/local/lib/python3.10/site-packages/cairo/_cairo.cpython-310.so: Undefined symbol "PyObject_AsWriteBuffer" --- graphics/py-cairo/Makefile | 2 +- graphics/py-cairo/files/patch-cairo_surface.c | 215 ++++++++++++++++++++++++++ 2 files changed, 216 insertions(+), 1 deletion(-) diff --git a/graphics/py-cairo/Makefile b/graphics/py-cairo/Makefile index 3afb3bd7cd16..3570aa42fc6d 100644 --- a/graphics/py-cairo/Makefile +++ b/graphics/py-cairo/Makefile @@ -2,7 +2,7 @@ PORTNAME= cairo PORTVERSION= 1.18.1 -PORTREVISION= 1 +PORTREVISION= 2 PORTEPOCH= 1 CATEGORIES= graphics python MASTER_SITES= https://github.com/pygobject/pycairo/releases/download/v${PORTVERSION}/ diff --git a/graphics/py-cairo/files/patch-cairo_surface.c b/graphics/py-cairo/files/patch-cairo_surface.c new file mode 100644 index 000000000000..b4ab64c6fe21 --- /dev/null +++ b/graphics/py-cairo/files/patch-cairo_surface.c @@ -0,0 +1,215 @@ +https://github.com/pygobject/pycairo/commit/0f8cdc058239 +https://github.com/pygobject/pycairo/commit/4c5377787624 +https://github.com/pygobject/pycairo/commit/590bcd2ecc9c + +--- cairo/surface.c.orig 2018-11-03 09:30:34 UTC ++++ cairo/surface.c +@@ -142,6 +142,7 @@ _write_func (void *closure, const unsigned char *data, + + static const cairo_user_data_key_t surface_base_object_key; + static const cairo_user_data_key_t surface_is_mapped_image; ++static const cairo_user_data_key_t surface_buffer_view_key; + + static void + surface_dealloc (PycairoSurface *o) { +@@ -439,28 +440,30 @@ _destroy_mime_user_data_func (PyObject *user_data) { + static void + _destroy_mime_data_func (PyObject *user_data) { + cairo_surface_t *surface; ++ Py_buffer *view; + PyObject *mime_intern; + + PyGILState_STATE gstate = PyGILState_Ensure(); + + /* Remove the user data holding the source object */ + surface = PyCapsule_GetPointer(PyTuple_GET_ITEM(user_data, 0), NULL); +- mime_intern = PyTuple_GET_ITEM(user_data, 2); ++ view = PyCapsule_GetPointer(PyTuple_GET_ITEM(user_data, 1), NULL); ++ mime_intern = PyTuple_GET_ITEM(user_data, 3); + cairo_surface_set_user_data( + surface, (cairo_user_data_key_t *)mime_intern, NULL, NULL); + + /* Destroy the user data */ +- _destroy_mime_user_data_func(user_data); ++ PyBuffer_Release (view); ++ PyMem_Free (view); ++ Py_DECREF(user_data); + + PyGILState_Release(gstate); + } + + static PyObject * + surface_set_mime_data (PycairoSurface *o, PyObject *args) { +- PyObject *obj, *user_data, *mime_intern, *capsule; +- const unsigned char *buffer; ++ PyObject *obj, *user_data, *mime_intern, *surface_capsule, *view_capsule; + const char *mime_type; +- Py_ssize_t buffer_len; + int res; + cairo_status_t status; + +@@ -475,38 +478,58 @@ surface_set_mime_data (PycairoSurface *o, PyObject *ar + Py_RETURN_NONE; + } + +-PYCAIRO_BEGIN_IGNORE_DEPRECATED +- res = PyObject_AsReadBuffer (obj, (const void **)&buffer, &buffer_len); +-PYCAIRO_END_IGNORE_DEPRECATED +- if (res == -1) ++ Py_buffer *view = PyMem_Malloc (sizeof (Py_buffer)); ++ if (view == NULL) { ++ PyErr_NoMemory (); + return NULL; ++ } + ++ res = PyObject_GetBuffer (obj, view, PyBUF_READ); ++ if (res == -1) { ++ PyMem_Free (view); ++ return NULL; ++ } ++ + /* We use the interned mime type string as user data key and store the + * passed in object with it. This allows us to return the same object in + * surface_get_mime_data(). + */ + mime_intern = PYCAIRO_PyUnicode_InternFromString(mime_type); +- capsule = PyCapsule_New(o->surface, NULL, NULL); +- user_data = Py_BuildValue("(NOO)", capsule, obj, mime_intern); +- if (user_data == NULL) ++ surface_capsule = PyCapsule_New(o->surface, NULL, NULL); ++ view_capsule = PyCapsule_New(view, NULL, NULL); ++ user_data = Py_BuildValue("(NNOO)", surface_capsule, view_capsule, obj, mime_intern); ++ if (user_data == NULL) { ++ PyBuffer_Release (view); ++ PyMem_Free (view); + return NULL; ++ } + + status = cairo_surface_set_user_data( + o->surface, (cairo_user_data_key_t *)mime_intern, user_data, + (cairo_destroy_func_t)_destroy_mime_user_data_func); +- if (status != CAIRO_STATUS_SUCCESS) ++ ++ if (status != CAIRO_STATUS_SUCCESS) { ++ PyBuffer_Release (view); ++ PyMem_Free (view); + Py_DECREF(user_data); +- RETURN_NULL_IF_CAIRO_ERROR(status); ++ Pycairo_Check_Status (status); ++ return NULL; ++ } + ++ Py_INCREF(user_data); + status = cairo_surface_set_mime_data ( +- o->surface, mime_type, buffer, (unsigned long)buffer_len, ++ o->surface, mime_type, view->buf, (unsigned long)view->len, + (cairo_destroy_func_t)_destroy_mime_data_func, user_data); ++ + if (status != CAIRO_STATUS_SUCCESS) { + cairo_surface_set_user_data( + o->surface, (cairo_user_data_key_t *)mime_intern, NULL, NULL); ++ PyBuffer_Release (view); ++ PyMem_Free (view); ++ Py_DECREF(user_data); ++ Pycairo_Check_Status (status); ++ return NULL; + } +- RETURN_NULL_IF_CAIRO_ERROR(status); +- Py_INCREF(user_data); + + Py_RETURN_NONE; + } +@@ -534,7 +557,7 @@ surface_get_mime_data (PycairoSurface *o, PyObject *ar + /* In case the mime data wasn't set through the Python API just copy it */ + return Py_BuildValue(PYCAIRO_DATA_FORMAT "#", buffer, buffer_len); + } else { +- obj = PyTuple_GET_ITEM(user_data, 1); ++ obj = PyTuple_GET_ITEM(user_data, 2); + Py_INCREF(obj); + return obj; + } +@@ -804,14 +827,22 @@ image_surface_new (PyTypeObject *type, PyObject *args, + NULL); + } + ++static void ++_release_buffer_destroy_func (void *user_data) { ++ Py_buffer *view = (Py_buffer *)user_data; ++ PyGILState_STATE gstate = PyGILState_Ensure(); ++ PyBuffer_Release (view); ++ PyMem_Free (view); ++ PyGILState_Release(gstate); ++} ++ + /* METH_CLASS */ + static PyObject * + image_surface_create_for_data (PyTypeObject *type, PyObject *args) { + cairo_surface_t *surface; + cairo_format_t format; +- unsigned char *buffer; ++ cairo_status_t status; + int width, height, stride = -1, res, format_arg; +- Py_ssize_t buffer_len; + PyObject *obj; + + if (!PyArg_ParseTuple (args, "Oiii|i:ImageSurface.create_for_data", +@@ -820,12 +851,6 @@ image_surface_create_for_data (PyTypeObject *type, PyO + + format = (cairo_format_t)format_arg; + +-PYCAIRO_BEGIN_IGNORE_DEPRECATED +- res = PyObject_AsWriteBuffer (obj, (void **)&buffer, &buffer_len); +-PYCAIRO_END_IGNORE_DEPRECATED +- if (res == -1) +- return NULL; +- + if (width <= 0) { + PyErr_SetString(PyExc_ValueError, "width must be positive"); + return NULL; +@@ -843,15 +868,42 @@ PYCAIRO_END_IGNORE_DEPRECATED + return NULL; + } + } +- if (height * stride > buffer_len) { ++ ++ Py_buffer *view = PyMem_Malloc (sizeof (Py_buffer)); ++ if (view == NULL) { ++ PyErr_NoMemory (); ++ return NULL; ++ } ++ ++ res = PyObject_GetBuffer (obj, view, PyBUF_WRITABLE); ++ if (res == -1) { ++ PyMem_Free (view); ++ return NULL; ++ } ++ ++ if (height * stride > view->len) { ++ PyBuffer_Release (view); ++ PyMem_Free (view); + PyErr_SetString(PyExc_TypeError, "buffer is not long enough"); + return NULL; + } ++ + Py_BEGIN_ALLOW_THREADS; +- surface = cairo_image_surface_create_for_data (buffer, format, width, +- height, stride); ++ surface = cairo_image_surface_create_for_data (view->buf, format, width, ++ height, stride); + Py_END_ALLOW_THREADS; +- return _surface_create_with_object(surface, obj); ++ ++ status = cairo_surface_set_user_data( ++ surface, &surface_buffer_view_key, view, ++ (cairo_destroy_func_t)_release_buffer_destroy_func); ++ if (Pycairo_Check_Status (status)) { ++ cairo_surface_destroy (surface); ++ PyBuffer_Release (view); ++ PyMem_Free (view); ++ return NULL; ++ } ++ ++ return PycairoSurface_FromSurface(surface, NULL); + } + +