8000 Update design rules for new exception handling. · markshannon/New-C-API-for-Python@82849a3 · GitHub
[go: up one dir, main page]

Skip to content

Commit 82849a3

Browse files
committed
Update design rules for new exception handling.
1 parent 19d80f3 commit 82849a3

File tree

1 file changed

+42
-16
lines changed

1 file changed

+42
-16
lines changed

DesignRules.md

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ For example `PyMemContext` is passed to destructor functions
2222
which prevents them from doing much more than freeing `PyRef`s
2323
and memory.
2424

25+
The exception to this rule is the set of funtions that get references
26+
to per-process objects like `int` or `type`.
27+
2528
## Opaque, linear references
2629

2730
The C-API will refer to Python objects through opaque references
@@ -48,41 +51,64 @@ The is a consequence of the "No invalid states" design principle.
4851
The legacy API allows inplace mutation of tuples, strings and other
4952
immutable object. These will not be allowed in the new API.
5053

51-
## All functions have an error "out" parameter, or return the error
54+
## All functions must clearly show if an error has occurred.
55+
56+
Whether an API function has produced an error must be clear
57+
from the return value, and only from the return value.
58+
59+
API functions must obey the following rules:
60+
61+
* If no valid result can be returned, the the result value must be `PyRef_INVALID` or `-1`.
62+
* If the result is passed though a pointer, and the an error occurs, then the result value must be untouched.
63+
* If the result is valid, then an error must not have occured
64+
* If an error has occurred, then the result of immediately calling `PyApi_GetLatestException()` must be that error.
65+
66+
Note that if an API function does not produce a result, the result of calling `PyApi_GetLatestException()`
67+
is undefined. It will be a legal, safe to use value; it will just be meaningless.
5268

53-
### Functions that have results
69+
### Functions that return references
5470

5571
Many functions return a result, but may also raise an exception.
56-
To handle this, all such API functions should have an `error` out
57-
parameter, of the form `PyExceptionRef *error`.
72+
To handle this case, a special value is used to indicate an error,
73+
`PyRef_INVALID`. If an error occurs, `PyRef_INVALID` must be returned.
74+
Conversely, if `PyRef_INVALID` is returned an error must have occurred.
5875

59-
The error pointer should always be the final parameter.
76+
### Functions that return booleans.
6077

61-
API functions must obey the following rules:
78+
These functions will return `int`, with -1 indicating an error.
79+
0 and 1 indicate `False` and `True`, respectively.
80+
81+
### Functions that return ints
82+
83+
Functions that only return non-negative values can use -1 to indicate an error.
84+
Functions that can return negative values must return an error code,
85+
returning the real result via a pointer.
6286

63-
* If no valid result can be returned, the the result value should be `PyRef_INVALID`.
64-
* If the result is valid, then the memory pointer to by `error` should be untouched.
87+
### Fundtions that may fail without an error
6588

66-
Some functions can fail without an error. Failure should be represented by returning
67-
`PyRef_INVALID` and `*error = PyRef_NO_EXCEPTION`.
89+
Some functions can fail without an error. Those functions must return an `int`
90+
error code and pass the result through a pointer.
91+
92+
Success should be indicated by zero, and non-error failure stats by positive values.
6893

6994
For example, to get a value from a dictionary might have the following API:
7095

7196
```C
72-
PyRef PyAPi_Dict_Get(PyContext ctx, PyDictRef dict, PyRef key, PyExceptionRef *value);
97+
int PyAPi_Dict_Get(PyContext ctx, PyDictRef dict, PyRef key, PyRef *result);
7398
```
7499
75-
If the result is `PyRef_INVALID` then the failure and error cases can be differentiated
76-
by testing `*error == PyRef_NO_EXCEPTION`.
100+
If the result is zero then the function has succeeded.
101+
Otherwise the error and failure cases can be distinguished by whether
102+
the result is negative.
77103
78104
### Functions without results
79105
80106
Some functions, e.g. `PyApi_List_Append()` do not produce a result, but can raise.
81-
Those functions should return a `PyExceptionRef`.
107+
Those functions should return an `int`.
82108
```C
83-
PyExceptionRef PyApi_List_Append(PyContext ctx, PyListRef list, PyRef item);
109+
int PyApi_List_Append(PyContext ctx, PyListRef list, PyRef item);
84110
```
85-
Success is indicated by returning `PyRef_NO_EXCEPTION`.
111+
Success is indicated by returning a negative value, usually -1.
86112

87113
## Naming
88114

0 commit comments

Comments
 (0)
0