Delay GC on object

Ah, maybe it’s just the mechanics I see from C++. What I see in the happy path is, destructors are called immediately when a function exits. As if every function body has it’s own __enter__, __exit__, calls Py_XDECREF on each object

import traceback
from pyrx import Ap, Db, Ge


def foo():
    db = Db.Database(False, True)
#<<PyRx25.1.arx!boost::python::objects::value_holder<PyDbDatabase>::`scalar deleting destructor'(unsigned int)	C++

       
@Ap.Command()
def doit():
    try:
        foo() # db ctor -> dtor
        foo() # db ctor -> dtor
    except Exception as err:
        traceback.print_exception(err)
        
#  doit from C++
#  PyObjectPtr rslt(PyObject_CallNoArgs(pMethod));
#  if (rslt != nullptr)
#      return;

# using PyObjectPtr = std::unique_ptr < PyObject, decltype([](PyObject* ptr) noexcept
#     {
#         PyDecRef(ptr);
#     }) > 

I have an open object detector, that I can run to check C++ ref counts, as some functions may be called in different contexts, I.e. from a modeless wxPython dialog. The result is always the same

But just in is case, all of the memory handling functions are exposed to Python. I.e.
obj.dispose()
obj.keepAlive(bool)
obj.isNullObj()

ideally, users would never need to use these, a lot of users are coming from AutoLISP and probably aren’t used to doing memory management.
it should be tasty and delicious :grin:

What I see in the happy path is, destructors are called immediately when a function exits.

That may indeed be what happens. The point is it’s not guaranteed to happen. It’s not part of the language’s specified behavior. For all we know, the next version of Python could come out with a GC tweak that changes that.

1 Like