[issue17589] Make documentation about macros in C API explicit about rvalue vs statement
New submission from Larry Hastings: CPython API "functions" implemented as macros can expand into either rvalues or statements. Most expand into statements (often using the do {} while (0) syntactic sugar trick), but occasionally they're legal as rvalues. As of this writing Py_INCREF works as an rvalue. But discussion on another tracker issue (#17206) proposes changing the implementation in such a way that it will only be usable as a statement. Although it's mildly unlikely, it's certainly possible that this will break somebody's code. I propose that the documentation make an explicit ruling on whether macros are usable as rvalues or as statements. Perhaps a blanket statement would suffice, "all macros are only supported for use as statements except where explicitly noted", then annotate specific macros that are supported for use as rvalues. Though that raises the question of acknowledging in the documentation that some things are macros--I think the documentation glosses over that fact right now. Note: I added you three (Georg, Mark, Martin) as I thought you might have an opinion on this one way or the other. If you're not interested, my apologies. ---------- assignee: docs@python components: Documentation messages: 185646 nosy: Mark.Shannon, docs@python, georg.brandl, larry, loewis priority: normal severity: normal stage: needs patch status: open title: Make documentation about macros in C API explicit about rvalue vs statement type: enhancement versions: Python 3.4 _______________________________________ Python tracker <report@bugs.python.org> <http://bugs.python.org/issue17589> _______________________________________
Georg Brandl added the comment: There are also some macros usable as lvalues, such as Py_REFCNT or Py_SIZE (they aren't documented at all currently). Anyway, documenting as statement-only unless explicitly stated differently is fine with me. ---------- _______________________________________ Python tracker <report@bugs.python.org> <http://bugs.python.org/issue17589> _______________________________________
Antoine Pitrou added the comment: Py_INCREF usable as an rvalue sounds more like an accident than a deliberate feature, and it would be IMO counter-productive to codify this behaviour in the docs. As for the lvalue usage of Py_REFCNT and Py_SIZE, I think it would be better if it were limited to CPython core. But arguably writers of extension types may want to mutate the size field of a varsize object. ---------- nosy: +pitrou _______________________________________ Python tracker <report@bugs.python.org> <http://bugs.python.org/issue17589> _______________________________________
Larry Hastings added the comment:
Py_INCREF usable as an rvalue sounds more like an accident than a deliberate feature
I'd go with "misfeature", but in no way is it accidental. The coding deliberately preserves the rvalue-ness of it, c.f. _Py_REF_DEBUG_COMMA. ---------- _______________________________________ Python tracker <report@bugs.python.org> <http://bugs.python.org/issue17589> _______________________________________
Amaury Forgeot d'Arc added the comment: There are some extension modules (pytables) that do return Py_INREF(x), x; and Py_RETURN_NONE is also defined with a comma expression. Oh, and Cython: #define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False)) ---------- nosy: +amaury.forgeotdarc _______________________________________ Python tracker <report@bugs.python.org> <http://bugs.python.org/issue17589> _______________________________________
Changes by Mark Dickinson <dickinsm@gmail.com>: ---------- nosy: +mark.dickinson _______________________________________ Python tracker <report@bugs.python.org> <http://bugs.python.org/issue17589> _______________________________________
Larry Hastings added the comment: Amaury: I'd appreciate it if you'd bring those examples up on bug 17206. If we're going to change the semantics of Py_INCREF I'd prefer we did it with our eyes wide open. ---------- _______________________________________ Python tracker <report@bugs.python.org> <http://bugs.python.org/issue17589> _______________________________________
Larry Hastings added the comment: Oh, and, yes, it's true that Py_RETURN_NONE currently takes advantage of Py_INCREF being an rvalue, and changing Py_INCREF to a statement would break the existing implementation. But Py_RETURN_NONE itself is of necessity a statement. We would simply change Py_RETURN_NONE's implementation to multiple statements, probably with the do { ... } while(0) trick, so it worked again. I'd be shocked if that change broke any existing code. So that's no big deal. Having external code that depends on Py_INCREF being an rvalue is my concern, and what I hoped you'd bring up on bug #17206. ---------- _______________________________________ Python tracker <report@bugs.python.org> <http://bugs.python.org/issue17589> _______________________________________
Changes by Arfrever Frehtes Taifersar Arahesis <Arfrever.FTA@GMail.Com>: ---------- nosy: +Arfrever _______________________________________ Python tracker <report@bugs.python.org> <http://bugs.python.org/issue17589> _______________________________________
Change by STINNER Victor <vstinner@python.org>: ---------- components: +C API _______________________________________ Python tracker <report@bugs.python.org> <https://bugs.python.org/issue17589> _______________________________________
participants (7)
-
Amaury Forgeot d'Arc
-
Antoine Pitrou
-
Arfrever Frehtes Taifersar Arahesis
-
Georg Brandl
-
Larry Hastings
-
Mark Dickinson
-
STINNER Victor