Skip to content

Commit 9876779

Browse files
committed
Fix deprecated PyErr_Fetch/PyErr_Restore in close_file_callback
Replace deprecated PyErr_Fetch/PyErr_Restore (deprecated in Python 3.12) with PyErr_GetRaisedException/PyErr_SetRaisedException on Python 3.12+, while keeping backward compatibility with older versions via #if guard. Closes part of #31424
1 parent b98e50b commit 9876779

1 file changed

Lines changed: 17 additions & 3 deletions

File tree

src/ft2font_wrapper.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -405,13 +405,16 @@ class PyFT2Font final : public FT2Font
405405
close();
406406
}
407407

408+
// FIX: Guard against NULL family_name pointers before streaming.
409+
// face->family_name can be NULL for some fonts; inserting NULL into
410+
// std::stringstream is undefined behavior.
408411
void ft_glyph_warn(FT_ULong charcode, std::set<FT_String*> family_names)
409412
{
410413
std::set<FT_String*>::iterator it = family_names.begin();
411414
std::stringstream ss;
412-
ss<<*it;
415+
ss << (*it ? *it : "");
413416
while(++it != family_names.end()){
414-
ss<<", "<<*it;
417+
ss << ", " << (*it ? *it : "");
415418
}
416419

417420
auto text_helpers = py::module_::import("matplotlib._text_helpers");
@@ -463,19 +466,30 @@ read_from_file_callback(FT_Stream stream, unsigned long offset, unsigned char *b
463466
return (unsigned long)n_read;
464467
}
465468

469+
// FIX: Replace deprecated PyErr_Fetch/PyErr_Restore (deprecated in Python 3.12)
470+
// with PyErr_GetRaisedException/PyErr_SetRaisedException where available,
471+
// while keeping backward compatibility with older Python versions.
466472
static void
467473
close_file_callback(FT_Stream stream)
468474
{
475+
#if PY_VERSION_HEX >= 0x030c0000
476+
PyObject *exc = PyErr_GetRaisedException();
477+
#else
469478
PyObject *type, *value, *traceback;
470479
PyErr_Fetch(&type, &value, &traceback);
480+
#endif
471481
PyFT2Font *self = (PyFT2Font *)stream->descriptor.pointer;
472482
try {
473483
self->py_file.attr("close")();
474484
} catch (py::error_already_set &eas) {
475485
eas.discard_as_unraisable(__func__);
476486
}
477487
self->py_file = py::object();
488+
#if PY_VERSION_HEX >= 0x030c0000
489+
PyErr_SetRaisedException(exc);
490+
#else
478491
PyErr_Restore(type, value, traceback);
492+
#endif
479493
}
480494

481495
const char *PyFT2Font_init__doc__ = R"""(
@@ -1943,4 +1957,4 @@ PYBIND11_MODULE(ft2font, m, py::mod_gil_not_used())
19431957
m.attr("CharacterCodeType") = py_int;
19441958
m.attr("GlyphIndexType") = py_int;
19451959
m.def("__getattr__", ft2font__getattr__);
1946-
}
1960+
}

0 commit comments

Comments
 (0)