"weakly-referenced object no longer exists" when enabled=False in Limiter()
phesSofthouse opened this issue · comments
Expected Behaviour
Should turn off rate limiting (Im using it for disabling rate limiting when running unit tests)
Current Behaviour
Raises an error:
File "python3.10/site-packages/flask/app.py", line 1823, in full_dispatch_request
rv = self.dispatch_request()
File "python3.10/site-packages/flask/app.py", line 1799, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
File "python3.10/site-packages/flask_limiter/extension.py", line 1209, in __inner
self.limiter._auto_check
ReferenceError: weakly-referenced object no longer exists
Steps to Reproduce
Relevant code in my project:
limiter = Limiter(
get_remote_address,
strategy="fixed-window-elastic-expiry",
storage_uri=app.config["LIMITER_STORAGE_URI"],
enabled=False,
)
limiter.init_app(app)
forgot_password_view = ForgotPasswordView.as_view("forgotpassword")
forgot_password_view = limiter.limit("1/minute", methods=["POST"])(
forgot_password_view
)
app.add_url_rule(
"/forgot-password",
view_func=forgot_password_view,
methods=["GET", "POST"],
)
Same thing also happens when using RATELIMIT_ENABLED = False instead of the limiter parameter.
Your Environment
- Flask-limiter version: flask-limiter[redis]==3.4.0
- Flask version: flask==2.2.3
- Operating system: Macos Ventura 13.3.1
- Python version: 3.10.11
This implies that there is no reference to the limiter
left and it was collected by the GC. Is the code snippet you shared done within the scope of a method call where the scope of limiter
is the method scope?
The reason there is no problem when enabled=True
is that the init_app
method adds the limiter
to app.extensions
here but that code path is never hit when enabled=False
.
Im running the application factory pattern in flask, so the limiter is in the create_app() function.
So to prevent the GC from picking up the limiter, this does the trick.
app.limiter = limiter
(I realise this is only a short term solution until I refactor the structure of my project.)
Thanks for the help and amazing work with the library!
@phesSofthouse I'd recommend doing something along the lines of the guide here.
Basically create a global limiter=Limiter(....)
somewhere and then in the create_app
do the init_app
.