New GitHub issue #99537 from vstinner:<br>

<hr>

<pre>
A lot of C code in Python uses this pattern:

```c
Py_XDECREF(var);
var = value;
```

If *var* was holding the last strong reference to a Python object, the object finalizer is called which can call arbitrary Python code which can access the *var* variable which is now a dangling pointer, and so **Python does just crash in this case**.

The correct pattern is:

```c
old_var = var;
var = value;
Py_XDECREF(old_var);
```

And Py_SETREF() can be used to make this code shorter and easier to read and maintain:

```c
Py_XSETREF(var, value);
````

While the pattern is unsafe, maybe it's not possible to crash Python. But I prefer to replace this pattern with Py_SETREF() or Py_XSETREF() so I don't have to think about: oh, is it possible to crash Python?

Again, Py_SETREF() also makes the code shorter, easier to read and maintain.

While we are here, I also propose to replace:

```c
Py_XDECREF(var);
var = NULL;
```

with:

```c
Py_CLEAR(var);
```

which is shorter than:

```c
Py_XSETREF(var, NULL);
```

---

See also issue #99300 "Replace Py_INCREF()/Py_XINCREF() usage with Py_NewRef()/Py_XNewRef()" and issue #99481 "Add Py_HOLD_REF() macro to hold a strong reference to a Python object while executing code".
</pre>

<hr>

<a href="https://github.com/python/cpython/issues/99537">View on GitHub</a>
<p>Labels: type-bug</p>
<p>Assignee: </p>