Skip to content

Commit 38d5c3d

Browse files
authored
Merge pull request #184 from lautat/fix/app-context-force-locale
Fix force locale in app context and multiple threads
2 parents 0847cc6 + 3883ee7 commit 38d5c3d

File tree

3 files changed

+97
-64
lines changed

3 files changed

+97
-64
lines changed

flask_babel/__init__.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
"""
1010
from __future__ import absolute_import
1111
import os
12+
from types import SimpleNamespace
1213

1314
from datetime import datetime
1415
from contextlib import contextmanager
15-
from flask import current_app, request
16-
from flask.ctx import has_request_context
16+
from flask import current_app, g
1717
from flask.helpers import locked_cached_property
1818
from babel import dates, numbers, support, Locale
1919
from pytz import timezone, UTC
@@ -661,11 +661,13 @@ def lazy_pgettext(self, context, string, **variables):
661661

662662

663663
def _get_current_context():
664-
if has_request_context():
665-
return request
664+
if not g:
665+
return None
666+
667+
if not hasattr(g, "_flask_babel"):
668+
g._flask_babel = SimpleNamespace()
666669

667-
if current_app:
668-
return current_app
670+
return g._flask_babel
669671

670672

671673
def get_domain():

tests/test_date_formatting.py

Lines changed: 0 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
from __future__ import with_statement
33

44
from datetime import datetime, timedelta
5-
from threading import Semaphore, Thread
65

76
import flask
87

@@ -107,60 +106,3 @@ def test_refreshing():
107106
app.config['BABEL_DEFAULT_TIMEZONE'] = 'Europe/Vienna'
108107
babel.refresh()
109108
assert babel.format_datetime(d) == 'Apr 12, 2010, 3:46:00 PM'
110-
111-
112-
def test_force_locale():
113-
app = flask.Flask(__name__)
114-
b = babel.Babel(app)
115-
116-
@b.localeselector
117-
def select_locale():
118-
return 'de_DE'
119-
120-
with app.test_request_context():
121-
assert str(babel.get_locale()) == 'de_DE'
122-
with babel.force_locale('en_US'):
123-
assert str(babel.get_locale()) == 'en_US'
124-
assert str(babel.get_locale()) == 'de_DE'
125-
126-
127-
def test_force_locale_with_threading():
128-
app = flask.Flask(__name__)
129-
b = babel.Babel(app)
130-
131-
@b.localeselector
132-
def select_locale():
133-
return 'de_DE'
134-
135-
semaphore = Semaphore(value=0)
136-
137-
def first_request():
138-
with app.test_request_context():
139-
with babel.force_locale('en_US'):
140-
assert str(babel.get_locale()) == 'en_US'
141-
semaphore.acquire()
142-
143-
thread = Thread(target=first_request)
144-
thread.start()
145-
146-
try:
147-
with app.test_request_context():
148-
assert str(babel.get_locale()) == 'de_DE'
149-
finally:
150-
semaphore.release()
151-
thread.join()
152-
153-
154-
def test_refresh_during_force_locale():
155-
app = flask.Flask(__name__)
156-
b = babel.Babel(app)
157-
158-
@b.localeselector
159-
def select_locale():
160-
return 'de_DE'
161-
162-
with app.test_request_context():
163-
with babel.force_locale('en_US'):
164-
assert str(babel.get_locale()) == 'en_US'
165-
babel.refresh()
166-
assert str(babel.get_locale()) == 'en_US'

tests/test_force_locale.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
from threading import Semaphore, Thread
2+
3+
import flask
4+
5+
import flask_babel as babel
6+
7+
8+
def test_force_locale():
9+
app = flask.Flask(__name__)
10+
b = babel.Babel(app)
11+
12+
@b.localeselector
13+
def select_locale():
14+
return 'de_DE'
15+
16+
with app.test_request_context():
17+
assert str(babel.get_locale()) == 'de_DE'
18+
with babel.force_locale('en_US'):
19+
assert str(babel.get_locale()) == 'en_US'
20+
assert str(babel.get_locale()) == 'de_DE'
21+
22+
23+
def test_force_locale_with_threading():
24+
app = flask.Flask(__name__)
25+
b = babel.Babel(app)
26+
27+
@b.localeselector
28+
def select_locale():
29+
return 'de_DE'
30+
31+
semaphore = Semaphore(value=0)
32+
33+
def first_request():
34+
with app.test_request_context():
35+
with babel.force_locale('en_US'):
36+
assert str(babel.get_locale()) == 'en_US'
37+
semaphore.acquire()
38+
39+
thread = Thread(target=first_request)
40+
thread.start()
41+
42+
try:
43+
with app.test_request_context():
44+
assert str(babel.get_locale()) == 'de_DE'
45+
finally:
46+
semaphore.release()
47+
thread.join()
48+
49+
50+
def test_force_locale_with_threading_and_app_context():
51+
app = flask.Flask(__name__)
52+
b = babel.Babel(app)
53+
54+
@b.localeselector
55+
def select_locale():
56+
return 'de_DE'
57+
58+
semaphore = Semaphore(value=0)
59+
60+
def first_app_context():
61+
with app.app_context():
62+
with babel.force_locale('en_US'):
63+
assert str(babel.get_locale()) == 'en_US'
64+
semaphore.acquire()
65+
66+
thread = Thread(target=first_app_context)
67+
thread.start()
68+
69+
try:
70+
with app.app_context():
71+
assert str(babel.get_locale()) == 'de_DE'
72+
finally:
73+
semaphore.release()
74+
thread.join()
75+
76+
77+
def test_refresh_during_force_locale():
78+
app = flask.Flask(__name__)
79+
b = babel.Babel(app)
80+
81+
@b.localeselector
82+
def select_locale():
83+
return 'de_DE'
84+
85+
with app.test_request_context():
86+
with babel.force_locale('en_US'):
87+
assert str(babel.get_locale()) == 'en_US'
88+
babel.refresh()
89+
assert str(babel.get_locale()) == 'en_US'

0 commit comments

Comments
 (0)