public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/python-mplcairo] rawhide: Backport pybind11 patch to fix Python 3.15 build
@ 2026-07-27 3:49 Elliott Sales de Andrade
0 siblings, 0 replies; only message in thread
From: Elliott Sales de Andrade @ 2026-07-27 3:49 UTC (permalink / raw)
To: git-commits
A new commit has been pushed.
Repo : rpms/python-mplcairo
Branch : rawhide
Commit : 864ca8eb504b723eebef9ac44fba1a6147d6c919
Author : Elliott Sales de Andrade <quantum.analyst@gmail.com>
Date : 2026-07-26T23:48:42-04:00
Stats : +357/-3 in 3 file(s)
URL : https://src.fedoraproject.org/rpms/python-mplcairo/c/864ca8eb504b723eebef9ac44fba1a6147d6c919?branch=rawhide
Log:
Backport pybind11 patch to fix Python 3.15 build
---
diff --git a/0001-Don-t-error-on-all-warnings-in-tests.patch b/0001-Don-t-error-on-all-warnings-in-tests.patch
index c201e1b..06ca6c3 100644
--- a/0001-Don-t-error-on-all-warnings-in-tests.patch
+++ b/0001-Don-t-error-on-all-warnings-in-tests.patch
@@ -1,7 +1,7 @@
From 899226738c54e32461bbc1fe204c13d866012015 Mon Sep 17 00:00:00 2001
From: Elliott Sales de Andrade <quantum.analyst@gmail.com>
Date: Mon, 11 Nov 2024 19:57:43 -0500
-Subject: [PATCH] Don't error on all warnings in tests
+Subject: [PATCH 1/2] Don't error on all warnings in tests
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
@@ -21,5 +21,5 @@ index 53e8dfb..125c8b2 100644
"error::DeprecationWarning:mplcairo",
]
--
-2.47.0
+2.54.0
diff --git a/0002-Use-pybind11-3.0-native-enums.patch b/0002-Use-pybind11-3.0-native-enums.patch
new file mode 100644
index 0000000..fa10682
--- /dev/null
+++ b/0002-Use-pybind11-3.0-native-enums.patch
@@ -0,0 +1,350 @@
+From 092de16ea618e34d8650d84bdea3872dfe662323 Mon Sep 17 00:00:00 2001
+From: Antony Lee <anntzer.lee@gmail.com>
+Date: Fri, 11 Jul 2025 22:01:58 +0200
+Subject: [PATCH 2/2] Use pybind11 3.0 native enums.
+
+Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
+---
+ README.rst | 13 +---
+ ext/_macros.h | 74 -------------------
+ ext/_mplcairo.cpp | 179 +++++++++++++++++++++++-----------------------
+ pyproject.toml | 2 +-
+ 4 files changed, 93 insertions(+), 175 deletions(-)
+
+diff --git a/README.rst b/README.rst
+index a9450ce..6a6668a 100644
+--- a/README.rst
++++ b/README.rst
+@@ -58,18 +58,13 @@ Installation
+
+ mplcairo requires
+
+-- Python≥3.7,
+-- Matplotlib≥2.2 (declared as ``install_requires``),
+-- on Linux and macOS, pycairo≥1.16.0 [#]_ (declared as ``install_requires``),
++- Python≥3.8,
++- Matplotlib≥2.2,
++- on Linux and macOS, pycairo≥1.16.0 [#]_,
+ - on Windows, cairo≥1.13.1 [#]_ (shipped with the wheel).
+
+ It is recommended to use cairo≥1.17.4.
+
+-Additionally, building mplcairo from source requires
+-
+-- pybind11≥2.6.0 [#]_ (declared as ``setup_requires``),
+-- pycairo≥1.16.0 (declared as ``setup_requires``).
+-
+ As usual, install using pip:
+
+ .. code-block:: sh
+@@ -120,8 +115,6 @@ path <add_dll_directory_>`_).
+ cairo 1.17.8 fixed a crash when outputting in the cairo-script format (in
+ 6a81bf8).
+
+-.. [#] pybind11 2.6.0 is needed to support Python 3.9.
+-
+ On Fedora, the package is available as `python-mplcairo <fedora-package_>`_.
+
+ Building/packaging
+diff --git a/ext/_macros.h b/ext/_macros.h
+index 243e667..38667a0 100644
+--- a/ext/_macros.h
++++ b/ext/_macros.h
+@@ -53,77 +53,3 @@
+ return value_; \
+ } \
+ }()
+-
+-// Extension for pybind11: Pythonic enums.
+-
+-// a1 includes the opening brace and a2 the closing brace.
+-// This definition is compatible with older compiler versions compared to
+-// #define P11X_ENUM_TYPE(...) decltype(std::map{std::pair __VA_ARGS__})::mapped_type
+-#define P11X_ENUM_TYPE(a1, a2, ...) decltype(std::pair a1, a2)::second_type
+-
+-#define P11X_CAT2(a, b) a##b
+-#define P11X_CAT(a, b) P11X_CAT2(a, b)
+-
+-namespace p11x {
+- namespace {
+- namespace py = pybind11;
+-
+- // Holder is (py_base_cls, [(name, value), ...]) before module init;
+- // converted to the Python class object after init.
+- auto enums = std::unordered_map<std::string, py::object>{};
+-
+- auto bind_enums(py::module mod) -> void
+- {
+- for (auto& [py_name, spec]: enums) {
+- auto const& [py_base_cls, pairs] =
+- spec.cast<std::pair<std::string, py::object>>();
+- mod.attr(py::cast(py_name)) = spec =
+- py::module::import("pydoc").attr("locate")(py_base_cls)(
+- py_name, pairs, py::arg("module") = mod.attr("__name__"));
+- }
+- }
+- }
+-}
+-
+-// Immediately converting the args to a vector outside of the lambda avoids
+-// name collisions.
+-#define P11X_DECLARE_ENUM(py_name, py_base_cls, ...) \
+- namespace p11x { \
+- namespace { \
+- [[maybe_unused]] auto const P11X_CAT(enum_placeholder_, __COUNTER__) = \
+- [](auto args) { \
+- py::gil_scoped_acquire gil; \
+- using int_t = std::underlying_type_t<decltype(args[0].second)>; \
+- auto pairs = std::vector<std::pair<std::string, int_t>>{}; \
+- for (auto& [k, v]: args) { \
+- pairs.emplace_back(k, int_t(v)); \
+- } \
+- p11x::enums[py_name] = pybind11::cast(std::pair{py_base_cls, pairs}); \
+- return 0; \
+- } (std::vector{std::pair __VA_ARGS__}); \
+- } \
+- } \
+- namespace pybind11::detail { \
+- template<> struct type_caster<P11X_ENUM_TYPE(__VA_ARGS__)> { \
+- using type = P11X_ENUM_TYPE(__VA_ARGS__); \
+- static_assert(std::is_enum_v<type>, "Not an enum"); \
+- PYBIND11_TYPE_CASTER(type, _(py_name)); \
+- bool load(handle src, bool) { \
+- auto cls = p11x::enums.at(py_name); \
+- PyObject* tmp = nullptr; \
+- if (pybind11::isinstance(src, cls) \
+- && (tmp = PyNumber_Index(src.attr("value").ptr()))) { \
+- auto ival = PyLong_AsLong(tmp); \
+- value = decltype(value)(ival); \
+- Py_DECREF(tmp); \
+- return !(ival == -1 && !PyErr_Occurred()); \
+- } else { \
+- return false; \
+- } \
+- } \
+- static handle cast(decltype(value) obj, return_value_policy, handle) { \
+- auto cls = p11x::enums.at(py_name); \
+- return cls(std::underlying_type_t<type>(obj)).inc_ref(); \
+- } \
+- }; \
+- }
+diff --git a/ext/_mplcairo.cpp b/ext/_mplcairo.cpp
+index f23dc2d..cfdcdcf 100644
+--- a/ext/_mplcairo.cpp
++++ b/ext/_mplcairo.cpp
+@@ -8,6 +8,8 @@
+ #include <py3cairo.h>
+ #include <cairo-script.h>
+
++#include <pybind11/native_enum.h>
++
+ #include <stack>
+ #include <thread>
+
+@@ -16,95 +18,6 @@
+ using namespace pybind11::literals;
+ using namespace std::string_literals;
+
+-P11X_DECLARE_ENUM(
+- "antialias_t", "enum.Enum",
+- {"DEFAULT", CAIRO_ANTIALIAS_DEFAULT},
+- {"NONE", CAIRO_ANTIALIAS_NONE},
+- {"GRAY", CAIRO_ANTIALIAS_GRAY},
+- {"SUBPIXEL", CAIRO_ANTIALIAS_SUBPIXEL},
+- {"FAST", CAIRO_ANTIALIAS_FAST},
+- {"GOOD", CAIRO_ANTIALIAS_GOOD},
+- {"BEST", CAIRO_ANTIALIAS_BEST}
+-)
+-P11X_DECLARE_ENUM(
+- "operator_t", "enum.Enum",
+- {"CLEAR", CAIRO_OPERATOR_CLEAR},
+- {"SOURCE", CAIRO_OPERATOR_SOURCE},
+- {"OVER", CAIRO_OPERATOR_OVER},
+- {"IN", CAIRO_OPERATOR_IN},
+- {"OUT", CAIRO_OPERATOR_OUT},
+- {"ATOP", CAIRO_OPERATOR_ATOP},
+- {"DEST", CAIRO_OPERATOR_DEST},
+- {"DEST_OVER", CAIRO_OPERATOR_DEST_OVER},
+- {"DEST_IN", CAIRO_OPERATOR_DEST_IN},
+- {"DEST_OUT", CAIRO_OPERATOR_DEST_OUT},
+- {"DEST_ATOP", CAIRO_OPERATOR_DEST_ATOP},
+- {"XOR", CAIRO_OPERATOR_XOR},
+- {"ADD", CAIRO_OPERATOR_ADD},
+- {"SATURATE", CAIRO_OPERATOR_SATURATE},
+- {"MULTIPLY", CAIRO_OPERATOR_MULTIPLY},
+- {"SCREEN", CAIRO_OPERATOR_SCREEN},
+- {"OVERLAY", CAIRO_OPERATOR_OVERLAY},
+- {"DARKEN", CAIRO_OPERATOR_DARKEN},
+- {"LIGHTEN", CAIRO_OPERATOR_LIGHTEN},
+- {"COLOR_DODGE", CAIRO_OPERATOR_COLOR_DODGE},
+- {"COLOR_BURN", CAIRO_OPERATOR_COLOR_BURN},
+- {"HARD_LIGHT", CAIRO_OPERATOR_HARD_LIGHT},
+- {"SOFT_LIGHT", CAIRO_OPERATOR_SOFT_LIGHT},
+- {"DIFFERENCE", CAIRO_OPERATOR_DIFFERENCE},
+- {"EXCLUSION", CAIRO_OPERATOR_EXCLUSION},
+- {"HSL_HUE", CAIRO_OPERATOR_HSL_HUE},
+- {"HSL_SATURATION", CAIRO_OPERATOR_HSL_SATURATION},
+- {"HSL_COLOR", CAIRO_OPERATOR_HSL_COLOR},
+- {"HSL_LUMINOSITY", CAIRO_OPERATOR_HSL_LUMINOSITY}
+-)
+-P11X_DECLARE_ENUM( // Only for error messages.
+- "_format_t", "enum.Enum",
+- {"INVALID", CAIRO_FORMAT_INVALID},
+- {"ARGB32", CAIRO_FORMAT_ARGB32},
+- {"RGB24", CAIRO_FORMAT_RGB24},
+- {"A8", CAIRO_FORMAT_A8},
+- {"A1", CAIRO_FORMAT_A1},
+- {"RGB16_565", CAIRO_FORMAT_RGB16_565},
+- {"RGB30", CAIRO_FORMAT_RGB30}
+-)
+-P11X_DECLARE_ENUM( // Only for error messages.
+- "_surface_type_t", "enum.Enum",
+- {"IMAGE", CAIRO_SURFACE_TYPE_IMAGE},
+- {"PDF", CAIRO_SURFACE_TYPE_PDF},
+- {"PS", CAIRO_SURFACE_TYPE_PS},
+- {"XLIB", CAIRO_SURFACE_TYPE_XLIB},
+- {"XCB", CAIRO_SURFACE_TYPE_XCB},
+- {"GLITZ", CAIRO_SURFACE_TYPE_GLITZ},
+- {"QUARTZ", CAIRO_SURFACE_TYPE_QUARTZ},
+- {"WIN32", CAIRO_SURFACE_TYPE_WIN32},
+- {"BEOS", CAIRO_SURFACE_TYPE_BEOS},
+- {"DIRECTFB", CAIRO_SURFACE_TYPE_DIRECTFB},
+- {"SVG", CAIRO_SURFACE_TYPE_SVG},
+- {"OS2", CAIRO_SURFACE_TYPE_OS2},
+- {"WIN32_PRINTING", CAIRO_SURFACE_TYPE_WIN32_PRINTING},
+- {"QUARTZ_IMAGE", CAIRO_SURFACE_TYPE_QUARTZ_IMAGE},
+- {"SCRIPT", CAIRO_SURFACE_TYPE_SCRIPT},
+- {"QT", CAIRO_SURFACE_TYPE_QT},
+- {"RECORDING", CAIRO_SURFACE_TYPE_RECORDING},
+- {"VG", CAIRO_SURFACE_TYPE_VG},
+- {"GL", CAIRO_SURFACE_TYPE_GL},
+- {"DRM", CAIRO_SURFACE_TYPE_DRM},
+- {"TEE", CAIRO_SURFACE_TYPE_TEE},
+- {"XML", CAIRO_SURFACE_TYPE_XML},
+- {"SKIA", CAIRO_SURFACE_TYPE_SKIA},
+- {"SUBSURFACE", CAIRO_SURFACE_TYPE_SUBSURFACE},
+- {"COGL", CAIRO_SURFACE_TYPE_COGL}
+-)
+-P11X_DECLARE_ENUM(
+- "_StreamSurfaceType", "enum.Enum",
+- {"PDF", mplcairo::StreamSurfaceType::PDF},
+- {"PS", mplcairo::StreamSurfaceType::PS},
+- {"EPS", mplcairo::StreamSurfaceType::EPS},
+- {"SVG", mplcairo::StreamSurfaceType::SVG},
+- {"Script", mplcairo::StreamSurfaceType::Script}
+-)
+-
+ namespace mplcairo {
+
+ Region::Region(
+@@ -2118,7 +2031,93 @@ Only intended for debugging purposes.
+ )__doc__");
+
+ // Export classes.
+- p11x::bind_enums(m);
++ py::native_enum<cairo_antialias_t>(m, "antialias_t", "enum.Enum")
++ .value("DEFAULT", CAIRO_ANTIALIAS_DEFAULT)
++ .value("NONE", CAIRO_ANTIALIAS_NONE)
++ .value("GRAY", CAIRO_ANTIALIAS_GRAY)
++ .value("SUBPIXEL", CAIRO_ANTIALIAS_SUBPIXEL)
++ .value("FAST", CAIRO_ANTIALIAS_FAST)
++ .value("GOOD", CAIRO_ANTIALIAS_GOOD)
++ .value("BEST", CAIRO_ANTIALIAS_BEST)
++ .finalize();
++ py::native_enum<cairo_operator_t>(m, "operator_t", "enum.Enum")
++ .value("CLEAR", CAIRO_OPERATOR_CLEAR)
++ .value("SOURCE", CAIRO_OPERATOR_SOURCE)
++ .value("OVER", CAIRO_OPERATOR_OVER)
++ .value("IN", CAIRO_OPERATOR_IN)
++ .value("OUT", CAIRO_OPERATOR_OUT)
++ .value("ATOP", CAIRO_OPERATOR_ATOP)
++ .value("DEST", CAIRO_OPERATOR_DEST)
++ .value("DEST_OVER", CAIRO_OPERATOR_DEST_OVER)
++ .value("DEST_IN", CAIRO_OPERATOR_DEST_IN)
++ .value("DEST_OUT", CAIRO_OPERATOR_DEST_OUT)
++ .value("DEST_ATOP", CAIRO_OPERATOR_DEST_ATOP)
++ .value("XOR", CAIRO_OPERATOR_XOR)
++ .value("ADD", CAIRO_OPERATOR_ADD)
++ .value("SATURATE", CAIRO_OPERATOR_SATURATE)
++ .value("MULTIPLY", CAIRO_OPERATOR_MULTIPLY)
++ .value("SCREEN", CAIRO_OPERATOR_SCREEN)
++ .value("OVERLAY", CAIRO_OPERATOR_OVERLAY)
++ .value("DARKEN", CAIRO_OPERATOR_DARKEN)
++ .value("LIGHTEN", CAIRO_OPERATOR_LIGHTEN)
++ .value("COLOR_DODGE", CAIRO_OPERATOR_COLOR_DODGE)
++ .value("COLOR_BURN", CAIRO_OPERATOR_COLOR_BURN)
++ .value("HARD_LIGHT", CAIRO_OPERATOR_HARD_LIGHT)
++ .value("SOFT_LIGHT", CAIRO_OPERATOR_SOFT_LIGHT)
++ .value("DIFFERENCE", CAIRO_OPERATOR_DIFFERENCE)
++ .value("EXCLUSION", CAIRO_OPERATOR_EXCLUSION)
++ .value("HSL_HUE", CAIRO_OPERATOR_HSL_HUE)
++ .value("HSL_SATURATION", CAIRO_OPERATOR_HSL_SATURATION)
++ .value("HSL_COLOR", CAIRO_OPERATOR_HSL_COLOR)
++ .value("HSL_LUMINOSITY", CAIRO_OPERATOR_HSL_LUMINOSITY)
++ .finalize();
++ py::native_enum<cairo_format_t>(m, "_format_t", "enum.Enum")
++ // Only for error messages.
++ .value("INVALID", CAIRO_FORMAT_INVALID)
++ .value("ARGB32", CAIRO_FORMAT_ARGB32)
++ .value("RGB24", CAIRO_FORMAT_RGB24)
++ .value("A8", CAIRO_FORMAT_A8)
++ .value("A1", CAIRO_FORMAT_A1)
++ .value("RGB16_565", CAIRO_FORMAT_RGB16_565)
++ .value("RGB30", CAIRO_FORMAT_RGB30)
++ .value("RGB96F", static_cast<cairo_format_t>(6))
++ .value("RGBA128F", static_cast<cairo_format_t>(7))
++ .finalize();
++ py::native_enum<cairo_surface_type_t>(m, "_surface_type_t", "enum.Enum")
++ // Only for error messages.
++ .value("IMAGE", CAIRO_SURFACE_TYPE_IMAGE)
++ .value("PDF", CAIRO_SURFACE_TYPE_PDF)
++ .value("PS", CAIRO_SURFACE_TYPE_PS)
++ .value("XLIB", CAIRO_SURFACE_TYPE_XLIB)
++ .value("XCB", CAIRO_SURFACE_TYPE_XCB)
++ .value("GLITZ", CAIRO_SURFACE_TYPE_GLITZ)
++ .value("QUARTZ", CAIRO_SURFACE_TYPE_QUARTZ)
++ .value("WIN32", CAIRO_SURFACE_TYPE_WIN32)
++ .value("BEOS", CAIRO_SURFACE_TYPE_BEOS)
++ .value("DIRECTFB", CAIRO_SURFACE_TYPE_DIRECTFB)
++ .value("SVG", CAIRO_SURFACE_TYPE_SVG)
++ .value("OS2", CAIRO_SURFACE_TYPE_OS2)
++ .value("WIN32_PRINTING", CAIRO_SURFACE_TYPE_WIN32_PRINTING)
++ .value("QUARTZ_IMAGE", CAIRO_SURFACE_TYPE_QUARTZ_IMAGE)
++ .value("SCRIPT", CAIRO_SURFACE_TYPE_SCRIPT)
++ .value("QT", CAIRO_SURFACE_TYPE_QT)
++ .value("RECORDING", CAIRO_SURFACE_TYPE_RECORDING)
++ .value("VG", CAIRO_SURFACE_TYPE_VG)
++ .value("GL", CAIRO_SURFACE_TYPE_GL)
++ .value("DRM", CAIRO_SURFACE_TYPE_DRM)
++ .value("TEE", CAIRO_SURFACE_TYPE_TEE)
++ .value("XML", CAIRO_SURFACE_TYPE_XML)
++ .value("SKIA", CAIRO_SURFACE_TYPE_SKIA)
++ .value("SUBSURFACE", CAIRO_SURFACE_TYPE_SUBSURFACE)
++ .value("COGL", CAIRO_SURFACE_TYPE_COGL)
++ .finalize();
++ py::native_enum<StreamSurfaceType>(m, "_StreamSurfaceType", "enum.Enum")
++ .value("PDF", mplcairo::StreamSurfaceType::PDF)
++ .value("PS", mplcairo::StreamSurfaceType::PS)
++ .value("EPS", mplcairo::StreamSurfaceType::EPS)
++ .value("SVG", mplcairo::StreamSurfaceType::SVG)
++ .value("Script", mplcairo::StreamSurfaceType::Script)
++ .finalize();
+
+ py::class_<Region>(m, "_Region", py::buffer_protocol())
+ // Only for patching Agg...
+diff --git a/pyproject.toml b/pyproject.toml
+index 125c8b2..e2e2910 100644
+--- a/pyproject.toml
++++ b/pyproject.toml
+@@ -2,7 +2,7 @@
+ requires = [
+ "setuptools>=62",
+ "setuptools_scm[toml]>=6.2",
+- "pybind11>=2.8.0",
++ "pybind11>=3.0", # Native enum support.
+ "pycairo>=1.16.0; os_name == 'posix'", # Removed for manylinux build.
+ ]
+ build-backend = "setuptools.build_meta"
+--
+2.54.0
+
diff --git a/python-mplcairo.spec b/python-mplcairo.spec
index aabe3b2..f150b1f 100644
--- a/python-mplcairo.spec
+++ b/python-mplcairo.spec
@@ -10,6 +10,10 @@ URL: https://github.com/matplotlib/mplcairo
Source: %pypi_source %{srcname}
# Skip upstream's -Werror configuration.
Patch: 0001-Don-t-error-on-all-warnings-in-tests.patch
+# Backport https://github.com/matplotlib/mplcairo/commit/f0cd8536fe34935491e6a5e18bb682614a0272d9
+# which fixes: `pybind11::handle::dec_ref() is being called while the GIL is
+# either not held or invalid` error.
+Patch: 0002-Use-pybind11-3.0-native-enums.patch
# https://fedoraproject.org/wiki/Changes/EncourageI686LeafRemoval
ExcludeArch: %{ix86}
@@ -153,7 +157,7 @@ EOF
# 50 is upstream recommended tolerance since results won't match MPL exactly.
%{python3} run-mpl-test-suite.py --tolerance=50 -m 'not network' -v -n auto \
- -k 'not test_backends_interactive'
+ -k 'not test_backends_interactive and not test_rcupdate'
%files -n python3-%{srcname} -f %{pyproject_files}
%doc README.rst
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-07-27 3:49 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-27 3:49 [rpms/python-mplcairo] rawhide: Backport pybind11 patch to fix Python 3.15 build Elliott Sales de Andrade
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox