question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Maximum recursion depth exceeded

See original GitHub issue

If the security object gets initialized before the app exists (i.e. using the factory method) and init_app is called later, security._state is never set. This makes sense because _state is dependent upon the app, however, when an attribute on security is accessed, the redefinition of __getattr__ looks for _state, which isn’t set, so __getattr__ get’s called, looks for _state, etc, and then bam

RuntimeError: maximum recursion depth exceeded while calling a Python object

I opened a PR, but closed it because I’m not sure if it’s the right fix. I solved the issue myself by doing:

security = app.extensions['security']
@security.login_context_processor
...

but at the very least, I think there should be a better exception that gets raised (the max recursion depth really threw me off for a bit.) The solution in the PR would work, but would require the above to become something like

with app.app_context():
    @security.login_context_processor
    ...

which maybe works? Curious what other people think is a good solution.

Issue Analytics

  • State:closed
  • Created 9 years ago
  • Reactions:5
  • Comments:15 (3 by maintainers)

github_iconTop GitHub Comments

6reactions
jxltomcommented, Feb 9, 2017

I have searched for the old issues and found that the author has explained here and here in #141 that the constructor and init_app are not meant to be used together. This is for initialize many applications with same Security instance. So this may not be a bug or just adding self._state = None as followings can fixing this issue.

if app is not None and datastore is not None:
    self._state = self.init_app(app, datastore, **kwargs)
else:
    self._state = None

@diginikkari The proper way for initialize is that accessing attributes by getattr is OK when using constructors. But when using factory method, users need to access security attributes by state object which is returned by init_app. Here is an example on how to initialize using factory method. This example is for accessing send_mail_task, but you can use it for other attributes such as login_context_processor as well. I have posted a more detailed example on how to use Celey async task as send_mail_task using factory method here.

from celery import Celery
from flask import Flask
from flask_security import Security, .. datastore stuff ..
from flask_mail import Mail

celery = Celery()
mail = Mail()
security = Security()

def create_app(config):
    """Initialize Flask instance."""
    app = Flask(__name__)
    mail.init_app(app)
    security_ctx = security.init_app(app,..datastore stuff..)

    @security_ctx.send_mail_task
    def delay_flask_security_mail(msg):
        send_flask_mail.delay(msg)

    return app
1reaction
KeNaCocommented, Mar 27, 2016

As @eriktaubeneck and @diginikkari said, Flask-Social now dont support flask factory pattern. Also there is manual for it.
As I see some people try to fix it partially: #471, #465, #384(I ask @Diaoul if he want to fix failing tests or not. If not, I add this part to my solution.), #317 Also I start implement proper solution in my branch, pls review code and give me feedback. State of work:

  • Implement flask factory pattern support DONE
  • (Old) Test failing for some python versions. - I think this is about my tox and py versions setup not about real bugs. DONE
  • Change tests to test factory approach. WIP

[Update 1] Old test: it was my setup problem, now tests fail only for py33, some _ssl3 stuff, w8 for package update. [Update 2] Old test: yes, it was problem in py33 compilation. Now all test pass. [Update 3] PM #495

Read more comments on GitHub >

github_iconTop Results From Across the Web

What is the maximum recursion depth in Python, and how to ...
The recursion limit is usually 1000. – Boris Verkhovskiy. Apr 24, 2019 at 7:29. 4.
Read more >
Python: Maximum Recursion Depth Exceeded [How to Fix It]
The maximum recursion depth in Python is 1000. To check it, call sys.getrecursionlimit() function. To change it, call sys.setrecursionlimit().
Read more >
Python maximum recursion depth exceeded in comparison
The “maximum recursion depth exceeded in comparison” error is raised when you try to execute a function that exceeds Python's built in recursion...
Read more >
Python RecursionError: Maximum Recursion Depth Exceeded ...
A Python RecursionError exception is raised when the execution of your program exceeds the recursion limit of the Python interpreter. Two ways ...
Read more >
maximum recursion depth exceeded while calling a Python ...
When the interpreter detects that the maximum depth for recursion has reached, it throws the recursionerror ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found