Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 755b8ff

Browse files
committed
TST: add type checking and tests for fallback list
1 parent 6f7b14c commit 755b8ff

2 files changed

Lines changed: 34 additions & 7 deletions

File tree

lib/matplotlib/tests/test_font_manager.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,3 +347,16 @@ def test_get_font_names():
347347
assert set(available_fonts) == set(mpl_font_names)
348348
assert len(available_fonts) == len(mpl_font_names)
349349
assert available_fonts == mpl_font_names
350+
351+
352+
def test_fallback_errors():
353+
file_name = findfont('DejaVu Sans')
354+
355+
with pytest.raises(TypeError, match="Fallback list must be a list"):
356+
# failing to be a list will fail before the 0
357+
ft2font.FT2Font(file_name, _fallback_list=(0,))
358+
359+
with pytest.raises(
360+
TypeError, match="Fallback fonts must be FT2Font objects."
361+
):
362+
ft2font.FT2Font(file_name, _fallback_list=[0])

src/ft2font_wrapper.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -372,19 +372,33 @@ static int PyFT2Font_init(PyFT2Font *self, PyObject *args, PyObject *kwds)
372372
open_args.flags = FT_OPEN_STREAM;
373373
open_args.stream = &self->stream;
374374

375-
if (fallback_list && PyList_Check(fallback_list)) {
376-
Py_ssize_t size = PyList_Size(fallback_list);
377-
375+
if (fallback_list) {
376+
if (!PyList_Check(fallback_list)) {
377+
PyErr_SetString(PyExc_TypeError, "Fallback list must be a list");
378+
goto exit;
379+
}
380+
Py_ssize_t size = PyList_Size(fallback_list);
381+
382+
// go through fallbacks once to make sure the types are right
383+
for (Py_ssize_t i = 0; i < size; ++i) {
384+
// this returns a borrowed reference
385+
PyObject* item = PyList_GetItem(fallback_list, i);
386+
if (!PyObject_IsInstance(item, PyObject_Type(reinterpret_cast<PyObject *>(self)))) {
387+
PyErr_SetString(PyExc_TypeError, "Fallback fonts must be FT2Font objects.");
388+
goto exit;
389+
}
390+
}
391+
// go through a second time to add them to our lists
378392
for (Py_ssize_t i = 0; i < size; ++i) {
379393
// this returns a borrowed reference
380394
PyObject* item = PyList_GetItem(fallback_list, i);
381-
// Increase the ref count, we will undo this in dealloc
382-
// this makes sure things do not get gc'd under us!
395+
// Increase the ref count, we will undo this in dealloc this makes
396+
// sure things do not get gc'd under us!
383397
Py_INCREF(item);
384398
self->fallbacks.push_back(item);
385-
// TODO: check whether item is actually an FT2Font
399+
// Also (locally) cache the underlying FT2Font objects. As long as
400+
// the Python objects are kept alive, these pointer are good.
386401
FT2Font *fback = reinterpret_cast<PyFT2Font *>(item)->x;
387-
// Also (locally) cache the underlying FT2Font objects
388402
fallback_fonts.push_back(fback);
389403
}
390404

0 commit comments

Comments
 (0)