Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 93eaf6d

Browse filesBrowse 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
Copy full SHA for 93eaf6d

File tree

Expand file treeCollapse file tree

2 files changed

+26
-17
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+26
-17
lines changed

‎src/_path_wrapper.cpp

Copy file name to clipboardExpand all lines: src/_path_wrapper.cpp
+12-4Lines 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

Copy file name to clipboardExpand all lines: src/py_converters.cpp
+14-13Lines 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)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.