Django keeps object references in case of exception

22 views
Skip to first unread message

claudio...@gmail.com

unread,
Aug 3, 2018, 10:25:10 AM8/3/18
to Django users
Hi all.

I know Python but I'm pretty new to Django. It seems to me this is a bug, but I'd like your opinions before actually filing a bug report.

this is my function, executed by an http call:

@csrf_exempt
def main(request):

    obj = MyClass()
    # raise AssertionError

    return HttpResponse('OK\n', content_type='text/plain')


this is MyClass:

class MyClass:

    def __init__(self):
        pass

    def __del__(self) :
        print('>>>>>>>>>>>>> DEL')


without raising the AssertionError, everything works fine and I see the print() output in the server log as soon the function main() terminates.
But uncommenting the raise line I don't see the print() output; triggering the server reload by saving a source file, the print() output shows up.

This happens with the internal webserver as well as with Lighttpd + Gunicorn.

I think Django is keeping some reference to the frame object of the function main(). This behaviour doesn't let me to close things like file descriptors or sockets in case of untrapped exception.

Is this a bug? Or... what I'm doing wrong?

I'm running Django 2.0.7, Python 3.6.1, Linux.
Thanks.

Christophe Pettus

unread,
Aug 3, 2018, 1:34:20 PM8/3/18
to django...@googlegroups.com

> On Aug 3, 2018, at 07:23, claudio...@gmail.com wrote:
>
> It seems to me this is a bug, but I'd like your opinions before actually filing a bug report.

I suspect what you are seeing there is a difference in garbage collection behavior. __del__ is not run immediately upon the reference count reaching 0; it's run when the object is garbage-collected, which can be some time later.

--
-- Christophe Pettus
x...@thebuild.com

claudio...@gmail.com

unread,
Aug 3, 2018, 2:56:04 PM8/3/18
to Django users
Sorry but... no. It's not mandatory for any Python implementation, but the CPython interpreter collects any objects as soon as its reference count reaches zero, thus running the __del__ method.

Reply all
Reply to author
Forward
0 new messages