New submission from Eric Cousineau <eric.cousineau@tri.global>:

Due to how `PyObject_CallFinalizer` is written in python3, `__del__` will only 
*ever* be called once.

In my use case, I am experimenting with a feature in `pybind11` to prevent 
slicing with Python class instances that inherit from pybind11-C++ base 
classes, which involves detecting when an instance loses all reference in 
Python (`Py_REFCNT(...) == 0`) but still has reference in C++ 
(`shared_ptr::count() > 0`), and reviving the Python portion when this 
situation happens.

In python2, I could do this without a hitch, as a resurrected object could have 
its `__del__` method called multiple times (through `tp_dealloc` I believe?). 
But in python3, the object is marked with `_PyGC_SET_FINALIZED(...)`, thus 
preventing `__del__` from being called again.

It'd be nice to either (a) somehow allow `__del__` to be called naturally 
without too much fuss or, at the least, (b) have this reflected in the 
documentation:
https://docs.python.org/3/reference/datamodel.html#object.__del__

See attached `revive_test`. Example execution:

```
$ python2 ./revive_test.py 
Revive
Destroy
[ Done ]

$ python3 ./revive_test.py 
Revive
[ Done ]
```

----------
assignee: docs@python
components: Documentation
files: revive_test.py
messages: 308660
nosy: Eric Cousineau, docs@python
priority: normal
severity: normal
status: open
title: Difference in ressurrection behavior with __del__ in py2 vs. py3
type: behavior
versions: Python 3.4, Python 3.5, Python 3.6
Added file: https://bugs.python.org/file47339/revive_test.py

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue32377>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to