Break reference cycle created by default in Flask instances.

Flask instances with static folders were creating a reference cycle
via their "static" view function (which held a strong reference back
to the Flask instance to call its `send_static_file` method). This
prevented CPython from freeing the memory for a Flask instance
when all external references to it were released.

Now use a weakref for the back reference to avoid this.

Co-authored-by: Joshua Bronson <jab@users.noreply.github.com>
This commit is contained in:
Bogdan Opanchuk 2020-10-03 07:05:05 -07:00 committed by GitHub
parent 4e8b020494
commit 8efea0ccbb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 1 deletions

View file

@ -1,5 +1,6 @@
import os
import sys
import weakref
from datetime import timedelta
from itertools import chain
from threading import Lock
@ -478,11 +479,14 @@ class Flask(Scaffold):
assert (
bool(static_host) == host_matching
), "Invalid static_host/host_matching combination"
# Use a weakref to avoid creating a reference cycle between the app
# and the view function (see #3761).
self_ref = weakref.ref(self)
self.add_url_rule(
f"{self.static_url_path}/<path:filename>",
endpoint="static",
host=static_host,
view_func=self.send_static_file,
view_func=lambda **kw: self_ref().send_static_file(**kw),
)
# Set the name of the Click group in case someone wants to add