I'm having an issue where the Python destructor for a Tensorflow session object is not being called.
Consider the following code, run under Python 3.4+:
import tensorflow as tf
# CODE THAT CHANGES BEHAVIOR
datashape = [1]
y = tf.ones(shape=datashape)
sess = tf.Session()
sess.delete2 = sess.__del__
def override(p, methods):
oldType = type(p)
newType = type(oldType.__name__ + "_Override", (oldType,), methods)
p.__class__ = newType
def p(self):
print("__del__ called")
self.delete2()
def monkey(x):
override(x, {"__del__": p})
monkey(sess)
print("Deleting sess:")
(We got the monkeypatching code from Monkey patch __del__ to new function. You can also reproduce this without it by installing TensorFlow in a virtualenv and directly editing the source https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/client/session.py#L686)
When we comment out the two lines following the # CODE THAT CHANGES BEHAVIOR
comment, upon interpreter exit, we see __del__ called
printed.
When we leave those two lines out, we don't see __del__ called
printed.
Additionally, if you wrap all the code inside a function (e.g. using the __main__
convention) we also see __del__
called.
Note: according to the accepted answer in Why aren't destructors guaranteed to be called on interpreter exit?, Python 3.4+ guarantees that destructors are always called on interpreter exit.
Why does this behavior occur, and how can we fix it?