Skip to content

Problematic to have to specify a scoping function? #35

@rsyring

Description

@rsyring

When using an app factory pattern, it's problematic to have to specify a scoping function prior to app init (which is where you can check app.testing):

from flask_webtest import get_scopefunc

db = SQLAlchemy(session_options={'scopefunc': get_scopefunc()})

def init_ext(app):
    db.init_app(app)

The default scoping function of flask-sqlalchemy is just using the app context:

def _app_ctx_id() -> int:
    """Get the id of the current Flask application context for the session scope."""
    return id(app_ctx._get_current_object())  # type: ignore[attr-defined]

This means that, instead of messing around with the scoping function, we can just push a new app context before the request and that will give us a different SA session. Presumably, this why @guruofgentoo added FLASK_WEBTEST_PUSH_APP_CONTEXT in 88d7251

As I think about all of this, it seems to me it would simplify our code base considerably if we:

  • Push the app context by default, use the config option and/or TestApp(..., push_app_context=False) to change the default behavior.
  • Get rid of all usage of and reference to SessionScope and greenlet
  • Change docs to instruct pushing a new app context if/when a new session is needed.
    • I'm not sure how this applies to greenlets. Presumably there is some mechanism already in place that ensures the correct app context is in place when a greenlet comes back to code that is waiting? I.e. through the greenlet equivalent of a thread local?
    • Where did the greenlet need come from anyway? I saw the commit that added it but there was no commentary on why.
  • If custom session logic is needed, there is nothing stopping someone from turning off the context push and setting up a scopfunc on their own.
  • We could adjust the TestApp class to expose the context manager that is used to wrap each request thereby making it easy to subclass TestApp and wrap each request it makes in some custom functionality.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions