-
-
Notifications
You must be signed in to change notification settings - Fork 794
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve C API guidelines for return values #1129
Improve C API guidelines for return values #1129
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? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
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 <encukou@gmail.com>
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 <vstinner@python.org>
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/