Improve C API guidelines for return values#1129
Improve C API guidelines for return values#1129erlend-aasland wants to merge 6 commits intopython:mainfrom
Conversation
Clarify that returning an error indicator should be done iff an exception is raised. For functions returning an int, a _negative value_ should be returned. Suggest -1 unless there is a need to distinguish between error types.
|
@encukou, are you ok with this change? |
Co-authored-by: Adam Turner <[email protected]>
|
Thanks, Victor and Adam. |
|
Sadly, the newly added PyLong_AsInt() doesn't respect new guidelines, but it was a deliberate choice. I like the new PyDict_GetItemRef() API, it's pleasant to use it. |
|
Well, I've thought about this, and realized I haven't seen an actual use case for distinguishing between error types. Is there one? I'd love to see a counterexample :)
Well, it doesn't respect the old guidelines either, so that's unrelated to this PR :) |
It's not common to report different error cases, but it happens, especially if the API does not raise an exception. On error, Py_DecodeLocale() sets size to _Py_DecodeLocaleEx() has 3 error cases:
For the caller, it's important to be able to distinguish the different errors. Extract of int res = _Py_DecodeLocaleEx(str, &wstr, &wlen, &reason,
current_locale, errors);
if (res != 0) {
if (res == -2) {
PyObject *exc;
exc = PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns",
"locale", str, len,
(Py_ssize_t)wlen,
(Py_ssize_t)(wlen + 1),
reason);
if (exc != NULL) {
PyCodec_StrictErrors(exc);
Py_DECREF(exc);
}
}
else if (res == -3) {
PyErr_SetString(PyExc_ValueError, "unsupported error handler");
}
else {
PyErr_NoMemory();
}
return NULL;
} |
Co-authored-by: Petr Viktorin <[email protected]>
I'd prefer if the guideline simply said "return -1 on error"; after all a guideline is meant for the general case, not the special case. For the extraordinary cases, it is ok to not follow the general guideline (after a discussion, of course). |
Well, if an exception isn't raised, then the function should not return a negative value (or NULL) at all. There are two parts of the question of “Does a negative value other than -1 signal that an exception was raised?”
|
I would prefer callers to check for |
|
Yeah, But perhaps this shouldn't be decided in an issue, especially since there'll be lots of API discussions at the sprint in about a month. |
Well, this PR has been up for two months already; there's no harm in waiting another month :) |
|
Even when I'm 100% sure that a function can only return -1 on error, I prefer to write In the C library, it's unclear if a function returns 0 or 1 on success. It depends. But in the Python C API, it's likely that a function returns "a negative number" on error. |
Yeah, that's the C idiom, so that would be my preferred style. |
|
If a function can raise an exeeption, I don't see the point of having more than one negative value. The exception should contain the details: exception type and exception message. In the worst case, if a very important additonal information cannot be passed in the exception, i would prefer to add a separated argument, than break the rule: return 1, 0 or -1. |
|
My Py_DecodeLocale() example is unrelated: it doesn't raise an exception, and so uses a different API. I'm talking about public C API which raise exceptions. |
Co-authored-by: Victor Stinner <[email protected]>
|
I'll leave this for the C API workgroup. |
Clarify that returning an error indicator should be done iff an
exception is raised.
For functions returning an int, a negative value should be returned.
Suggest -1 unless there is a need to distinguish between error types.
📚 Documentation preview 📚: https://cpython-devguide--1129.org.readthedocs.build/