python-babel / flask-babel

i18n and l10n support for Flask based on Babel and pytz
https://python-babel.github.io/flask-babel/
Other
432 stars 159 forks source link

Flask-Babel with Pytest gives AssertionError: a localeselector function is already registered #169

Closed mybooc closed 3 years ago

mybooc commented 3 years ago

I asked this question also on stackoverflow but no replies. Maybe it has to do with the (werkzeug) test_client.

I am using pytest and want the test_client to run with different parameters. This means the fixture scope should be 'function'. With the first parameter ('de') no problems but with the next ('en' and 'es') the above error message is shown. The message comes from Flask-Babel init.py. My questions:

This is the fixture:

@pytest.fixture(scope='function', params=['de', 'en', 'es'])
def client_lang_code_ni(request):

    lang_code = request.param
    project_config = os.getenv('PROJECT_CONFIG')
    flask_app = create_app(project_config)
    with flask_app.test_client() as client:
        with flask_app.app_context():
            rv = client.get('/' + lang_code + '/')
            yield (client, lang_code)

The Flask app is nothing special:

def create_app(project_config):
    ...
    @babel.localeselector
    def get_locale():
        do something

My workaround, which appears to work fine: use a global variable that indicates if the get_locale function was decorated already. If not, I decorate it myself.

    #@babel.localeselector
    def get_locale():
        do something

    global babel_localeselector_already_registered
    if not babel_localeselector_already_registered:
        get_locale = babel.localeselector(get_locale)
        babel_localeselector_already_registered = True