-
-
Notifications
You must be signed in to change notification settings - Fork 845
Document the preferred style for API functions with three, four or five-way returns #1121
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
Comments
While it's different, here is an example of API using different negative values for result. The private _Py_DecodeLocaleEx() function returns 0 on success, or a negative number on error:
|
Since Having said that, it is possible that an API function would want to distinguish between error types. Are there any other examples? |
AFAICS, the proposed guideline is:
I'm +1 for those two guidelines. Also, to avoid any potential confusion: when we're talking about returning, I interpret that as the C return statement; I do not interpret that as an "output parameter" (for example a pointer to an // This function _returns_ -1 in case of error, else 0.
int
func(void)
{
/* do stuff */
if (error) {
raise_exception();
return -1;
}
return 0;
} |
For functions that return (the C return statement) two different kinds of values, yes. I think we are all in agreement that in the case of failure, -1 should be returned. |
In PR #106005, adding PyDict_GetItemRef() function, @markshannon asks to return 1 if the key is present and 0 if the key is missing. Is it a bad practice? Is it better to return 0 in both cases (that was my first implementation)? |
Try reading the next line 😉
|
I made a PR: #1123 |
Sure; but I prefer to document it so there's even less chance of friction :) |
One other issue is whether the output parameter should be touched if there is no meaningful value. Take PyObject *value;
int err = PyDict_GetItemSuffixToBeDecided(op, key, &value); Should It is more efficient to not touch it, since the return value specifies that it has no meaning. |
Yeah... let's establish guidelines for the return values first; then we can follow up with guidelines for output parameters. |
In my PyDict_GetItemRef() PR, I chose to always initialized For the "return 0" case (missing key), I also prefer to set
Here the function result is not used for the second code path: I'm not comfortable to document that |
IMO, a negative value should be returned. Functions should return -1 unless they have a reason to use something else (like distinguish between error types), but callers should check with Also, IMO we should say that a negative value should be returned iff an exception is raised. I.e., make it very clear what counts as “failure”. |
Adding something like this would indeed make the guidelines clearer. I'll create PR with an amendment shortly. |
@erlend-aasland Should this issue be closed or is there remaining work? |
We will leave this to the C API Workgroup. If needed, they can create a new issue or reopen this. |
Most C API functions either succeed or fail. Those functions return
NULL
/not-NULL
or 0/-1. No problem there.However there are functions that can have three or more return kinds.
For example,
found/not-found/error
,yield/return/raise
, or evenless-than/equal/greater-than/unordered/error
in the case of comparisons.For those functions we want to return the kind as an
int
, setting anyPyObject *
results through an out pointer.The devguide should document the preferred way to do this, to avoid endless debate for each new C API function.
See python/cpython#105201 (comment) for my preferred approach for three-way return values.
Four and five way return values other than for comparisons are sufficiently uncommon that they can be dealt with on an individual basis.
For comparisons, a slightly strange enum based on powers-of-two is to be used for efficient selection of the desired result by masking.
The text was updated successfully, but these errors were encountered: