I checked the source code for pycurl.CurlMulti.info_read and it shows that:
/* When an error occurs */
else {
/* Create a result tuple that will get added to err_list. */
PyObject *v = Py_BuildValue("(Ois)", (PyObject *)co, (int)msg->data.result, co->error);
/* Append curl object to list of objects which failed */
if (v == NULL || PyList_Append(err_list, v) != 0) {
Py_XDECREF(v);
goto error;
}
Py_DECREF(v);
}
where co
is retrieved from L781:
/* Fetch the curl object that corresponds to the curl handle in the message */
res = curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, (char **) &co);
And CURLINFO_PRIVATE
and co->error
is set at src/easy.c#L52:
/* Set curl error buffer and zero it */
res = curl_easy_setopt(self->handle, CURLOPT_ERRORBUFFER, self->error);
if (res != CURLE_OK) {
return (-1);
}
memset(self->error, 0, sizeof(self->error));
/* Set backreference */
res = curl_easy_setopt(self->handle, CURLOPT_PRIVATE, (char *) self);
if (res != CURLE_OK) {
return (-1);
}
which means that given the pycurl.Curl
object is not reused for another connection or destroyed, it should be pretty safe to use the curl error message
in the return value of pycurl.CurlMulti.info_read()
.
This answer gives me another interesting fact:
It is not safe to set CURLOPT_PRIVATE
on the pycurl.Curl
object.