8000 Fix uses of PyObject_IsTrue. · matplotlib/matplotlib@93eaf6d · GitHub
[go: up one dir, main page]

Skip to content

Commit 93eaf6d

Browse files
committed
Fix uses of PyObject_IsTrue.
PyObject_IsTrue can return -1 if an exception occurred when trying to convert a Python object to a bool (a typical case is for numpy arrays, which cannot be converted to bools). Failure to handle this correctly results e.g. in ``` l, = plt.plot([1, 2]); l.get_path().should_simplify = np.array([1, 2]) ``` ``` ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/usr/lib/python3.7/site-packages/matplotlib/backends/backend_qt5.py", line 501, in _draw_idle <elided> File "/usr/lib/python3.7/site-packages/matplotlib/backends/backend_agg.py", line 146, in draw_path self._renderer.draw_path(gc, path, transform, rgbFace) SystemError: PyEval_EvalFrameEx returned a result with an error set ``` whereas after this PR, the ValueError gets correctly propagated out. No tests, because one really needs to go out of their way to trigger the faulty cases anyways...
1 parent 666d3d0 commit 93eaf6d

File tree

2 files changed

+26
-17
lines changed

2 files changed

+26
-17
lines changed

src/_path_wrapper.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -631,8 +631,12 @@ static PyObject *Py_cleanup_path(PyObject *self, PyObject *args, PyObject *kwds)
631631

632632
if (simplifyobj == Py_None) {
633633
simplify = path.should_simplify();
634-
} else if (PyObject_IsTrue(simplifyobj)) {
635-
simplify = true;
634+
} else {
635+
switch (PyObject_IsTrue(simplifyobj)) {
636+
case 0: simplify = false; break;
637+
case 1: simplify = true; break;
638+
default: return NULL; // errored.
639+
}
636640
}
637641

638642
bool do_clip = (clip_rect.x1 < clip_rect.x2 && clip_rect.y1 < clip_rect.y2);
@@ -709,8 +713,12 @@ static PyObject *Py_convert_to_string(PyObject *self, PyObject *args, PyObject *
709713

710714
if (simplifyobj == Py_None) {
711715
simplify = path.should_simplify();
712-
} else if (PyObject_IsTrue(simplifyobj)) {
713-
simplify = true;
716+
} else {
717+
switch (PyObject_IsTrue(simplifyobj)) {
718+
case 0: simplify = false; break;
719+
case 1: simplify = true; break;
720+
default: return NULL; // errored.
721+
}
714722
}
715723

716724
CALL_CPP("convert_to_string",

src/py_converters.cpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,11 @@ int convert_double(PyObject *obj, void *p)
116116
int convert_bool(PyObject *obj, void *p)
117117
{
118118
bool *val = (bool *)p;
119-
int ret;
120-
121-
ret = PyObject_IsTrue(obj);
122-
if (ret == -1) {
123-
return 0;
119+
switch (PyObject_IsTrue(obj)) {
120+
case 0: *val = false; break;
121+
case 1: *val = true; break;
122+
default: return 0; // errored.
124123
}
125-
*val = ret != 0;
126-
127124
return 1;
128125
}
129126

@@ -389,7 +386,11 @@ int convert_path(PyObject *obj, void *pathp)
389386
if (should_simplify_obj == NULL) {
390387
goto exit;
391388
}
392-
should_simplify = PyObject_IsTrue(should_simplify_obj) != 0;
389+
switch (PyObject_IsTrue(should_simplify_obj)) {
390+
case 0: should_simplify = 0; break;
391+
case 1: should_simplify = 1; break;
392+
default: goto exit; // errored.
393+
}
393394

394395
simplify_threshold_obj = PyObject_GetAttrString(obj, "simplify_threshold");
395396
if (simplify_threshold_obj == NULL) {
@@ -438,15 +439,15 @@ int convert_clippath(PyObject *clippath_tuple, void *clippathp)
438439
int convert_snap(PyObject *obj, void *snapp)
439440
{
440441
e_snap_mode *snap = (e_snap_mode *)snapp;
441-
442442
if (obj == NULL || obj == Py_None) {
443443
*snap = SNAP_AUTO;
444-
} else if (PyObject_IsTrue(obj)) {
445-
*snap = SNAP_TRUE;
446444
} else {
447-
*snap = SNAP_FALSE;
445+
switch (PyObject_IsTrue(obj)) {
446+
case 0: *snap = SNAP_FALSE; break;
447+
case 1: *snap = SNAP_TRUE; break;
448+
default: return 0; // errored.
449+
}
448450
}
449-
450451
return 1;
451452
}
452453

0 commit comments

Comments
 (0)
0