Skip to content

Commit b2a6824

Browse files
committed
fix(quart): Support for quart_flask_patch
1 parent 4c9731b commit b2a6824

File tree

3 files changed

+58
-11
lines changed

3 files changed

+58
-11
lines changed

sentry_sdk/integrations/flask.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,16 @@ def __init__(
7272
@staticmethod
7373
def setup_once():
7474
# type: () -> None
75+
try:
76+
from quart import Quart
77+
78+
if Flask == Quart:
79+
# This is Quart masquerading as Flask, don't enable the Flask
80+
# integration. See https://github.com/getsentry/sentry-python/issues/2709
81+
raise DidNotEnable("Quart is impersonating Flask")
82+
except ImportError:
83+
pass
84+
7585
version = package_version("flask")
7686
_check_minimum_version(FlaskIntegration, version)
7787

tests/integrations/quart/test_quart.py

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,22 @@
1313
from sentry_sdk.integrations.logging import LoggingIntegration
1414
import sentry_sdk.integrations.quart as quart_sentry
1515

16-
from quart import Quart, Response, abort, stream_with_context
17-
from quart.views import View
1816

19-
from quart_auth import AuthUser, login_user
20-
21-
try:
22-
from quart_auth import QuartAuth
17+
def quart_app_factory():
18+
# These imports are inlined because the test_quart_flask_patch testcase tests
19+
# behavior that is triggered by importing a package before any Quart imports
20+
# happen
21+
from quart import Quart
2322

24-
auth_manager = QuartAuth()
25-
except ImportError:
26-
from quart_auth import AuthManager
23+
try:
24+
from quart_auth import QuartAuth
2725

28-
auth_manager = AuthManager()
26+
auth_manager = QuartAuth()
27+
except ImportError:
28+
from quart_auth import AuthManager
2929

30+
auth_manager = AuthManager()
3031

31-
def quart_app_factory():
3232
app = Quart(__name__)
3333
app.debug = False
3434
app.config["TESTING"] = False
@@ -71,6 +71,34 @@ def integration_enabled_params(request):
7171
raise ValueError(request.param)
7272

7373

74+
@pytest.mark.asyncio
75+
@pytest.mark.forked
76+
async def test_quart_flask_patch(sentry_init, capture_events, reset_integrations):
77+
# This testcase is forked because import quart_flask_patch needs to run
78+
# before anything else Quart-related is imported (since it monkeypatches
79+
# some things) and we don't want this to affect other testcases.
80+
#
81+
# It's also important that this testcase is run before any other testcase
82+
# that uses quart_app_factory.
83+
import quart_flask_patch # noqa: F401
84+
85+
app = quart_app_factory()
86+
sentry_init(
87+
integrations=[quart_sentry.QuartIntegration()],
88+
)
89+
90+
@app.route("/")
91+
async def index():
92+
return "ok"
93+
94+
events = capture_events()
95+
96+
client = app.test_client()
97+
await client.get("/")
98+
99+
assert not events
100+
101+
74102
@pytest.mark.asyncio
75103
async def test_has_context(sentry_init, capture_events):
76104
sentry_init(integrations=[quart_sentry.QuartIntegration()])
@@ -213,6 +241,8 @@ async def test_quart_auth_configured(
213241
monkeypatch,
214242
integration_enabled_params,
215243
):
244+
from quart_auth import AuthUser, login_user
245+
216246
sentry_init(send_default_pii=send_default_pii, **integration_enabled_params)
217247
app = quart_app_factory()
218248

@@ -368,6 +398,8 @@ async def error_handler(err):
368398

369399
@pytest.mark.asyncio
370400
async def test_bad_request_not_captured(sentry_init, capture_events):
401+
from quart import abort
402+
371403
sentry_init(integrations=[quart_sentry.QuartIntegration()])
372404
app = quart_app_factory()
373405
events = capture_events()
@@ -385,6 +417,8 @@ async def index():
385417

386418
@pytest.mark.asyncio
387419
async def test_does_not_leak_scope(sentry_init, capture_events):
420+
from quart import Response, stream_with_context
421+
388422
sentry_init(integrations=[quart_sentry.QuartIntegration()])
389423
app = quart_app_factory()
390424
events = capture_events()
@@ -514,6 +548,8 @@ async def error():
514548

515549
@pytest.mark.asyncio
516550
async def test_class_based_views(sentry_init, capture_events):
551+
from quart.views import View
552+
517553
sentry_init(integrations=[quart_sentry.QuartIntegration()])
518554
app = quart_app_factory()
519555
events = capture_events()

tox.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,7 @@ deps =
501501
# Quart
502502
quart: quart-auth
503503
quart: pytest-asyncio
504+
quart: quart-flask-patch
504505
quart-v0.16: blinker<1.6
505506
quart-v0.16: jinja2<3.1.0
506507
quart-v0.16: Werkzeug<2.1.0

0 commit comments

Comments
 (0)