Description
I don't know the rationale for now calling django.setup()
before the test collection (cf #119 (comment)), but what I know is that it's causing an issue in a corner case implying lazy translations in a modelForm field choice list, because of the new feature allowing one to customiz the empty choice.
Here's how to reproduce:
1/ Create an app with the following models.py
:
from django import forms
from django.db import models
from django.utils.translation import ugettext_lazy as _
class Foo(models.Model):
choice = models.CharField(max_length=200, choices=(
(_('Audio'), (('vinyl', 'Vinyl'), ('cd', 'CD'))),
(_('Video'), (('vhs', 'VHS Tape'), ('dvd', 'DVD'))),
))
class MyForm(forms.ModelForm):
class Meta:
fields = ['choice']
model = Foo
2/ Now create a simple test file that imports this, eg from foo.models import MyForm
3/ Here's the result:
tests/test_models.py:1: in <module>
from foo.models import MyForm
foo/models.py:14: in <module>
class MyForm(forms.ModelForm):
../../.virtualenvs/bugmig/local/lib/python2.7/site-packages/django/forms/models.py:283: in __new__
opts.help_texts, opts.error_messages)
../../.virtualenvs/bugmig/local/lib/python2.7/site-packages/django/forms/models.py:210: in fields_for_model
formfield = f.formfield(**kwargs)
../../.virtualenvs/bugmig/local/lib/python2.7/site-packages/django/db/models/fields/__init__.py:1059: in formfield
return super(CharField, self).formfield(**defaults)
../../.virtualenvs/bugmig/local/lib/python2.7/site-packages/django/db/models/fields/__init__.py:818: in formfield
defaults['choices'] = self.get_choices(include_blank=include_blank)
../../.virtualenvs/bugmig/local/lib/python2.7/site-packages/django/db/models/fields/__init__.py:732: in get_choices
if choice in ('', None):
../../.virtualenvs/bugmig/local/lib/python2.7/site-packages/django/utils/functional.py:169: in __eq__
return self.__cast() == other
../../.virtualenvs/bugmig/local/lib/python2.7/site-packages/django/utils/functional.py:157: in __cast
return self.__text_cast()
../../.virtualenvs/bugmig/local/lib/python2.7/site-packages/django/utils/functional.py:148: in __text_cast
return func(*self.__args, **self.__kw)
../../.virtualenvs/bugmig/local/lib/python2.7/site-packages/django/utils/translation/__init__.py:83: in ugettext
return _trans.ugettext(message)
../../.virtualenvs/bugmig/local/lib/python2.7/site-packages/django/utils/translation/trans_real.py:319: in ugettext
return do_translate(message, 'ugettext')
../../.virtualenvs/bugmig/local/lib/python2.7/site-packages/django/utils/translation/trans_real.py:300: in do_translate
_default = translation(settings.LANGUAGE_CODE)
../../.virtualenvs/bugmig/local/lib/python2.7/site-packages/django/utils/translation/trans_real.py:210: in translation
_translations[language] = DjangoTranslation(language)
../../.virtualenvs/bugmig/local/lib/python2.7/site-packages/django/utils/translation/trans_real.py:120: in __init__
self._add_installed_apps_translations()
../../.virtualenvs/bugmig/local/lib/python2.7/site-packages/django/utils/translation/trans_real.py:166: in _add_installed_apps_translations
"The translation infrastructure cannot be initialized before the "
E AppRegistryNotReady: The translation infrastructure cannot be initialized before the apps registry is ready. Check that you don't make non-lazy gettext calls at import time.
This is a special case that only happens because we have translated named groups.
From my investigations, here's what happening:
When building the model form, it goes through the choice list to see if we've customized the empty choice: https://github.com/django/django/blob/master/django/db/models/fields/__init__.py#L732
To compare the choice with '' or None, we must first translate it for real (and thus "unlazy" the translation). Then, at the end, we try to merge all the translations together, and thus need to access the app configs (https://github.com/django/django/blob/master/django/utils/translation/trans_real.py#L163).
As we haven't run Django's setup yet (we're still in the test collection phase), the app-loading hasn't even started, and thus the failure.
I can obviously fix this issue by doing the setup myself in my conftest file, but I'm wondering if this should (could?) be fixed at pytest_django's level?