Codebase list flask-babel / fb32f51
Import upstream version 2.0.0+git20220810.1.38d5c3d Debian Janitor 1 year, 4 months ago
11 changed file(s) with 171 addition(s) and 117 deletion(s). Raw diff Collapse all Expand all
77 Maintainer: Tyler Kennedy
88 Maintainer-email: tk@tkte.ch
99 License: BSD
10 Description: # Flask Babel
11
12 ![Tests](https://github.com/python-babel/flask-babel/workflows/Tests/badge.svg?branch=master)
13 [![PyPI](https://img.shields.io/pypi/v/flask-babel.svg?maxAge=2592000)](https://pypi.python.org/pypi/Flask-Babel)
14
15 Implements i18n and l10n support for Flask. This is based on the Python
16 [babel][] module as well as [pytz][] both of which are installed automatically
17 for you if you install this library.
18
19 # Documention
20
21 The latest documentation is available [here][docs].
22
23 [babel]: https://github.com/python-babel/babel
24 [pytz]: https://pypi.python.org/pypi/pytz/
25 [docs]: https://flask-babel.tkte.ch/
26 [semver]: https://semver.org/
27
28 Platform: UNKNOWN
2910 Classifier: Development Status :: 5 - Production/Stable
3011 Classifier: Environment :: Web Environment
3112 Classifier: Intended Audience :: Developers
4223 Classifier: Topic :: Software Development :: Libraries :: Python Modules
4324 Description-Content-Type: text/markdown
4425 Provides-Extra: dev
26 License-File: LICENSE
27
28 # Flask Babel
29
30 ![Tests](https://github.com/python-babel/flask-babel/workflows/Tests/badge.svg?branch=master)
31 [![PyPI](https://img.shields.io/pypi/v/flask-babel.svg?maxAge=2592000)](https://pypi.python.org/pypi/Flask-Babel)
32
33 Implements i18n and l10n support for Flask. This is based on the Python
34 [babel][] module as well as [pytz][] both of which are installed automatically
35 for you if you install this library.
36
37 # Documention
38
39 The latest documentation is available [here][docs].
40
41 [babel]: https://github.com/python-babel/babel
42 [pytz]: https://pypi.python.org/pypi/pytz/
43 [docs]: https://python-babel.github.io/flask-babel/
44 [semver]: https://semver.org/
1515 flask_babel/speaklater.py
1616 tests/babel.cfg
1717 tests/test_date_formatting.py
18 tests/test_force_locale.py
1819 tests/test_gettext.py
1920 tests/test_integration.py
2021 tests/test_number_formatting.py
2829 tests/translations/de/LC_MESSAGES/messages.po
2930 tests/translations/de/LC_MESSAGES/test.mo
3031 tests/translations/de/LC_MESSAGES/test.po
32 tests/translations/fr/LC_MESSAGES/.keep
3133 tests/translations_different_domain/myapp.pot
3234 tests/translations_different_domain/de/LC_MESSAGES/myapp.mo
3335 tests/translations_different_domain/de/LC_MESSAGES/myapp.po
0 Babel>=2.3
1 Flask
2 Jinja2>=2.5
03 pytz
1 Flask
2 Babel>=2.3
3 Jinja2>=2.5
44
55 [dev]
6 Pallets-Sphinx-Themes
7 bumpversion
8 ghp-import
69 pytest
710 pytest-mock
8 bumpversion
9 ghp-import
1011 sphinx
11 Pallets-Sphinx-Themes
77 Maintainer: Tyler Kennedy
88 Maintainer-email: tk@tkte.ch
99 License: BSD
10 Description: # Flask Babel
11
12 ![Tests](https://github.com/python-babel/flask-babel/workflows/Tests/badge.svg?branch=master)
13 [![PyPI](https://img.shields.io/pypi/v/flask-babel.svg?maxAge=2592000)](https://pypi.python.org/pypi/Flask-Babel)
14
15 Implements i18n and l10n support for Flask. This is based on the Python
16 [babel][] module as well as [pytz][] both of which are installed automatically
17 for you if you install this library.
18
19 # Documention
20
21 The latest documentation is available [here][docs].
22
23 [babel]: https://github.com/python-babel/babel
24 [pytz]: https://pypi.python.org/pypi/pytz/
25 [docs]: https://flask-babel.tkte.ch/
26 [semver]: https://semver.org/
27
28 Platform: UNKNOWN
2910 Classifier: Development Status :: 5 - Production/Stable
3011 Classifier: Environment :: Web Environment
3112 Classifier: Intended Audience :: Developers
4223 Classifier: Topic :: Software Development :: Libraries :: Python Modules
4324 Description-Content-Type: text/markdown
4425 Provides-Extra: dev
26 License-File: LICENSE
27
28 # Flask Babel
29
30 ![Tests](https://github.com/python-babel/flask-babel/workflows/Tests/badge.svg?branch=master)
31 [![PyPI](https://img.shields.io/pypi/v/flask-babel.svg?maxAge=2592000)](https://pypi.python.org/pypi/Flask-Babel)
32
33 Implements i18n and l10n support for Flask. This is based on the Python
34 [babel][] module as well as [pytz][] both of which are installed automatically
35 for you if you install this library.
36
37 # Documention
38
39 The latest documentation is available [here][docs].
40
41 [babel]: https://github.com/python-babel/babel
42 [pytz]: https://pypi.python.org/pypi/pytz/
43 [docs]: https://python-babel.github.io/flask-babel/
44 [semver]: https://semver.org/
1212
1313 [babel]: https://github.com/python-babel/babel
1414 [pytz]: https://pypi.python.org/pypi/pytz/
15 [docs]: https://flask-babel.tkte.ch/
15 [docs]: https://python-babel.github.io/flask-babel/
1616 [semver]: https://semver.org/
296296 make sure to check them by hand and remove the fuzzy flag before
297297 compiling.
298298
299 Reloading Translations
300 ----------------------
301
302 The compiled translations will only be loaded initially. This means you have
303 to restart the server whenever you compile translations and want to see
304 those changes. To automatically reload translations you can tell the reloader
305 to watch the compiled ``.mo`` files::
306
307 $ flask run --extra-files app/translations/en_GB/LC_MESSAGES/messages.mo
308 # or
309 $ export FLASK_RUN_EXTRA_FILES=app/translations/en_GB/LC_MESSAGES/messages.mo
310 $ flask run
311
312 See `reloader`_ for more details.
313
299314 Troubleshooting
300315 ---------------
301316
388403 .. _babel: http://babel.edgewall.org/
389404 .. _pytz: http://pytz.sourceforge.net/
390405 .. _speaklater: http://pypi.python.org/pypi/speaklater
406 .. _reloader: https://flask.palletsprojects.com/en/1.1.x/cli/#watch-extra-files-with-the-reloader
00 """
1 flaskext.babel
2 ~~~~~~~~~~~~~~
1 flask_babel
2 ~~~~~~~~~~~
33
44 Implements i18n/l10n support for Flask applications based on Babel.
55
88 """
99 from __future__ import absolute_import
1010 import os
11 from types import SimpleNamespace
1112
1213 from datetime import datetime
1314 from contextlib import contextmanager
14 from flask import current_app, request
15 from flask.ctx import has_request_context
15 from flask import current_app, g
1616 from flask.helpers import locked_cached_property
1717 from babel import dates, numbers, support, Locale
1818 from pytz import timezone, UTC
150150 if not os.path.isdir(locale_dir):
151151 continue
152152
153 if filter(lambda x: x.endswith('.mo'), os.listdir(locale_dir)):
153 if any(x.endswith('.mo') for x in os.listdir(locale_dir)):
154154 result.append(Locale.parse(folder))
155155
156156 # If not other translations are found, add the default locale.
328328 """Convert a datetime object to the user's timezone. This automatically
329329 happens on all date formatting unless rebasing is disabled. If you need
330330 to convert a :class:`datetime.datetime` object at any time to the user's
331 timezone (as returned by :func:`get_timezone` this function can be used).
331 timezone (as returned by :func:`get_timezone`) this function can be used.
332332 """
333333 if datetime.tzinfo is None:
334334 datetime = datetime.replace(tzinfo=UTC)
354354 time.
355355
356356 The format parameter can either be ``'short'``, ``'medium'``,
357 ``'long'`` or ``'full'`` (in which cause the language's default for
357 ``'long'`` or ``'full'`` (in which case the language's default for
358358 that setting is used, or the default from the :attr:`Babel.date_formats`
359359 mapping is used) or a format string as documented by Babel.
360360
374374 of a :class:`~datetime.datetime` object.
375375
376376 The format parameter can either be ``'short'``, ``'medium'``,
377 ``'long'`` or ``'full'`` (in which cause the language's default for
377 ``'long'`` or ``'full'`` (in which case the language's default for
378378 that setting is used, or the default from the :attr:`Babel.date_formats`
379379 mapping is used) or a format string as documented by Babel.
380380
396396 time.
397397
398398 The format parameter can either be ``'short'``, ``'medium'``,
399 ``'long'`` or ``'full'`` (in which cause the language's default for
399 ``'long'`` or ``'full'`` (in which case the language's default for
400400 that setting is used, or the default from the :attr:`Babel.date_formats`
401401 mapping is used) or a format string as documented by Babel.
402402
660660
661661
662662 def _get_current_context():
663 if has_request_context():
664 return request
665
666 if current_app:
667 return current_app
663 if not g:
664 return None
665
666 if not hasattr(g, "_flask_babel"):
667 g._flask_babel = SimpleNamespace()
668
669 return g._flask_babel
668670
669671
670672 def get_domain():
11 from __future__ import with_statement
22
33 from datetime import datetime, timedelta
4 from threading import Semaphore, Thread
54
65 import flask
76
106105 app.config['BABEL_DEFAULT_TIMEZONE'] = 'Europe/Vienna'
107106 babel.refresh()
108107 assert babel.format_datetime(d) == 'Apr 12, 2010, 3:46:00 PM'
109
110
111 def test_force_locale():
112 app = flask.Flask(__name__)
113 b = babel.Babel(app)
114
115 @b.localeselector
116 def select_locale():
117 return 'de_DE'
118
119 with app.test_request_context():
120 assert str(babel.get_locale()) == 'de_DE'
121 with babel.force_locale('en_US'):
122 assert str(babel.get_locale()) == 'en_US'
123 assert str(babel.get_locale()) == 'de_DE'
124
125
126 def test_force_locale_with_threading():
127 app = flask.Flask(__name__)
128 b = babel.Babel(app)
129
130 @b.localeselector
131 def select_locale():
132 return 'de_DE'
133
134 semaphore = Semaphore(value=0)
135
136 def first_request():
137 with app.test_request_context():
138 with babel.force_locale('en_US'):
139 assert str(babel.get_locale()) == 'en_US'
140 semaphore.acquire()
141
142 thread = Thread(target=first_request)
143 thread.start()
144
145 try:
146 with app.test_request_context():
147 assert str(babel.get_locale()) == 'de_DE'
148 finally:
149 semaphore.release()
150 thread.join()
151
152
153 def test_refresh_during_force_locale():
154 app = flask.Flask(__name__)
155 b = babel.Babel(app)
156
157 @b.localeselector
158 def select_locale():
159 return 'de_DE'
160
161 with app.test_request_context():
162 with babel.force_locale('en_US'):
163 assert str(babel.get_locale()) == 'en_US'
164 babel.refresh()
165 assert str(babel.get_locale()) == 'en_US'
0 from threading import Semaphore, Thread
1
2 import flask
3
4 import flask_babel as babel
5
6
7 def test_force_locale():
8 app = flask.Flask(__name__)
9 b = babel.Babel(app)
10
11 @b.localeselector
12 def select_locale():
13 return 'de_DE'
14
15 with app.test_request_context():
16 assert str(babel.get_locale()) == 'de_DE'
17 with babel.force_locale('en_US'):
18 assert str(babel.get_locale()) == 'en_US'
19 assert str(babel.get_locale()) == 'de_DE'
20
21
22 def test_force_locale_with_threading():
23 app = flask.Flask(__name__)
24 b = babel.Babel(app)
25
26 @b.localeselector
27 def select_locale():
28 return 'de_DE'
29
30 semaphore = Semaphore(value=0)
31
32 def first_request():
33 with app.test_request_context():
34 with babel.force_locale('en_US'):
35 assert str(babel.get_locale()) == 'en_US'
36 semaphore.acquire()
37
38 thread = Thread(target=first_request)
39 thread.start()
40
41 try:
42 with app.test_request_context():
43 assert str(babel.get_locale()) == 'de_DE'
44 finally:
45 semaphore.release()
46 thread.join()
47
48
49 def test_force_locale_with_threading_and_app_context():
50 app = flask.Flask(__name__)
51 b = babel.Babel(app)
52
53 @b.localeselector
54 def select_locale():
55 return 'de_DE'
56
57 semaphore = Semaphore(value=0)
58
59 def first_app_context():
60 with app.app_context():
61 with babel.force_locale('en_US'):
62 assert str(babel.get_locale()) == 'en_US'
63 semaphore.acquire()
64
65 thread = Thread(target=first_app_context)
66 thread.start()
67
68 try:
69 with app.app_context():
70 assert str(babel.get_locale()) == 'de_DE'
71 finally:
72 semaphore.release()
73 thread.join()
74
75
76 def test_refresh_during_force_locale():
77 app = flask.Flask(__name__)
78 b = babel.Babel(app)
79
80 @b.localeselector
81 def select_locale():
82 return 'de_DE'
83
84 with app.test_request_context():
85 with babel.force_locale('en_US'):
86 assert str(babel.get_locale()) == 'en_US'
87 babel.refresh()
88 assert str(babel.get_locale()) == 'en_US'
2121 def test_multiple_directories():
2222 """
2323 Ensure we can load translations from multiple directories.
24
25 This also ensures that directories without any translation files
26 are not taken into account.
2427 """
2528 b = babel.Babel()
2629 app = flask.Flask(__name__)