Hum, to give more context to the discussion, the two discussed macros
are documented this way:
#ifndef Py_LIMITED_API
/* Safely decref `op` and set `op` to `op2`.
*
* As in case of Py_CLEAR "the obvious" code can be deadly:
*
* Py_DECREF(op);
* op = op2;
*
* The safe way is:
*
* Py_SETREF(op, op2);
*
* That arranges to set `op` to `op2` _before_ decref'ing, so that any code
* triggered as a side-effect of `op` getting torn down no longer believes
* `op` points to a valid object.
*
* Py_XSETREF is a variant of Py_SETREF that uses Py_XDECREF instead of
* Py_DECREF.
*/
#define Py_SETREF(op, op2) \
do { \
PyObject *_py_tmp = (PyObject *)(op); \
(op) = (op2); \
Py_DECREF(_py_tmp); \
} while (0)
#define Py_XSETREF(op, op2) \
do { \
PyObject *_py_tmp = (PyObject *)(op); \
(op) = (op2); \
Py_XDECREF(_py_tmp); \
} while (0)
#endif /* ifndef Py_LIMITED_API */
Victor
2017-11-09 13:22 GMT+01:00 Raymond Hettinger <[email protected]>:
>
>> On Nov 9, 2017, at 2:44 AM, Serhiy Storchaka <[email protected]> wrote:
>>
>> 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?
>
> It didn't really seem like a bad idea until after you swept through the code
> with 200+ applications of the macro and I saw how unclear the results were.
> Even code that I wrote myself is now harder for me to grok (for example, the
> macro was applied 17 times to already correct code in itertools).
>
> We used to employ a somewhat plain coding style that was easy to walk
> through, but the following examples seem opaque. I find it takes practice to
> look at any one of these and say that it is unequivocally correct (were the
> function error return arguments handled correctly, are the typecasts proper,
> at what point can a reentrant call occur, which is the source operand and
> which is the destination, is the macro using either of the operands twice, is
> the destination operand an allowable lvalue, do I need to decref the source
> operand afterwards, etc):
>
> Py_SETREF(((PyHeapTypeObject*)type)->ht_name, value)
> Py_SETREF(newconst, PyFrozenSet_New(newconst));
> Py_XSETREF(c->u->u_private, s->v.ClassDef.name);
> Py_SETREF(*p, t);
> Py_XSETREF(self->lineno, PyTuple_GET_ITEM(info, 1));
> Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
> Py_XSETREF(self->checker, PyObject_GetAttrString(ob, "_check_retval_"));
> Py_XSETREF(fut->fut_source_tb,
> _PyObject_CallNoArg(traceback_extract_stack));
>
> Stylistically, all of these seem awkward and I think there is more to it than
> just the name. I'm not sure it is wise to pass complex inputs into a
> two-argument macro that makes an assignment and has a conditional refcount
> side-effect. Even now, one of the above looks to me like it might not be
> correct.
>
> 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?
>
> My personal experience with the macros hasn't been positive. Perhaps
> everyone else thinks it's fine. If so, I won't stand in your way.
>
>
> Raymond
>
> _______________________________________________
> Python-Dev mailing list
> [email protected]
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/victor.stinner%40gmail.com
_______________________________________________
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com