@@ -22,6 +22,9 @@ For example `PyMemContext` is passed to destructor functions
22
22
which prevents them from doing much more than freeing ` PyRef ` s
23
23
and memory.
24
24
25
+ The exception to this rule is the set of funtions that get references
26
+ to per-process objects like ` int ` or ` type ` .
27
+
25
28
## Opaque, linear references
26
29
27
30
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.
48
51
The legacy API allows inplace mutation of tuples, strings and other
49
52
immutable object. These will not be allowed in the new API.
50
53
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.
52
68
53
- ### Functions that have results
69
+ ### Functions that return references
54
70
55
71
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.
58
75
59
- The error pointer should always be the final parameter .
76
+ ### Functions that return booleans .
60
77
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.
62
86
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
65
88
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.
68
93
69
94
For example, to get a value from a dictionary might have the following API:
70
95
71
96
``` 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 );
73
98
```
74
99
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.
77
103
78
104
### Functions without results
79
105
80
106
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 `.
82
108
```C
83
- PyExceptionRef PyApi_List_Append(PyContext ctx, PyListRef list, PyRef item);
109
+ int PyApi_List_Append(PyContext ctx, PyListRef list, PyRef item);
84
110
```
85
- Success is indicated by returning ` PyRef_NO_EXCEPTION ` .
111
+ Success is indicated by returning a negative value, usually -1 .
86
112
87
113
## Naming
88
114
0 commit comments