No, unless there is a way to pass arguments by reference in C99.
Py_SETREF(x, y) is the safe equivalent of
x = y;
Py_DECREF(x, y);
If the problem is with naming, what names do you prefer? This already
was bikeshedded (I insisted on discussing names before introducing the
macros), but may now you have better ideas?
The current code contains 212 usages of Py_SETREF and Py_XSETREF. Maybe
10% of them correctly used temporary variables before introducing these
macros, and these macros just made the code shorter. But in the rest of
cases the refcount was decremented before setting new value. Not always
this caused a problem, but it is too hard to prove that using such code
is safe in every concrete case. Unrolling all these invocations will
make the code larger and more cumbersome, and it is hard to do
automatically.
> The other issue is that when there are multiple occurrences of these macros for multiple variables, it interferes with my best practice of deferring all decrefs until the data structures are in a fully consistent state. Any one of these can cause arbitrary code to run. I greatly prefer putting all the decrefs at the end to increase my confidence that it is okay to run other code that might reenter the current code. Pure python functions effectively have this built-in because the locals all get decreffed at the end of the function when a return-statement is encountered. That practice helps me avoid hard to spot re-entrancy issues.
I agree with you. If you need to set two or more attributes
synchronously, Py_SETREF will not help you. This should be clearly
explained in the documentation.
Several subsequent Py_SETREFs may be an error. When I created my patches
for using Py_SETREF I encountered several such cases and used different
code for them. Maybe still there is not completely correct code, but in
any case it is better now than before introducing Py_SETREF.
But in many case you need to set only one attribute or different
attributes are not tightly related.
> Lastly, I think we should have a preference to not grow the stable C API. Bigger APIs are harder to learn and remember, not so much for you and Victor who use these frequently, but for everyone else who has to lookup all the macros whose function isn't immediately self-evident.
I agree with you again. But these macros are pretty helpful. They allow
to write the safer code easy. And they are more used than any other C
API addition in 3.5, 3.6, and 3.7.
3.7:
Py_X?SETREF -- 216
Py_UNREACHABLE -- 65
Py_RETURN_RICHCOMPARE -- 15
PyImport_GetModule -- 28
PyTraceMalloc_(T|Unt)rack -- 9
PyOS_(BeforeFork|AfterFork_(Parent|Child)) -- 24
Py_tss_NEEDS_INIT -- 6
PyInterpreterState_GetID -- 3
3.6:
PySlice_Unpack -- 22
PySlice_AdjustIndices -- 22
PyErr_SetImportErrorSubclass -- 3
PyErr_ResourceWarning -- 6
PyOS_FSPath -- 9
Py_FinalizeEx -- 21
Py_MEMBER_SIZE -- 4
3.5:
PyCodec_NameReplaceErrors -- 3
PyErr_FormatV -- 6
PyCoro_New -- 3
PyCoro_CheckExact -- 14
PyModuleDef_Init -- 30
PyModule_FromDefAndSpec2? -- 10
PyModule_ExecDef -- 3
PyModule_SetDocString -- 4
PyModule_AddFunctions -- 3
PyNumber_MatrixMultiply -- 4
PyNumber_InPlaceMatrixMultiply -- 4
Py_DecodeLocale -- 25
Py_EncodeLocale -- 11
Some older macros:
Py_STRINGIFY -- 15
Py_ABS -- 54
Py_MIN -- 66
Py_MAX - 56
The above number include declaration and definition, hence remove 2 or 3
per name for getting the number of usages.
Only added in 3.4 Py_UNUSED beats them (291) because it is used in
generated Argument Clinic code.
If you have found an incorrect code, please open an issue and provide a
patch. But recently you have rewrote the correct code (Py_SETREF was not
involved) in more complicated way [1] and have rejected my patch that
gets rid of the duplication of this complicated code [2]. Please don't
"fix" the code that is not broken.
[1] https://bugs.python.org/issue26491
[2] https://bugs.python.org/issue31585
> Probably, we're the wrong people to be talking about this. The proposal is to make these macros part of the official API so that it starts to appear in source code everywhere. The question isn't whether the above makes sense to you and me; instead, it is whether other people can make heads or tails out the above examples. As a result of making the macros official, will the Python world have a net increase in complexity or decrease in complexity?
I afraid that these macros will be used in any case, even when they are
not the part of an official C API, because they are handy. The main
purpose of documenting them officially is documenting in what cases
these macros are appropriate and make the code more reliable, and in
what cases they are not enough and a more complex code should be used.
This would be a lesson about correct replacing references. I didn't
write this in the source comment because it was purposed for experienced
Python core developers, and all usages under our control and passes a
peer review.