#34807: importing `django.forms` causes circular import error
---------------------------------+------------------------------------
     Reporter:  Collin Anderson  |                    Owner:  nobody
         Type:  Bug              |                   Status:  new
    Component:  Forms            |                  Version:  dev
     Severity:  Release blocker  |               Resolution:
     Keywords:                   |             Triage Stage:  Accepted
    Has patch:  0                |      Needs documentation:  0
  Needs tests:  0                |  Patch needs improvement:  0
Easy pickings:  0                |                    UI/UX:  0
---------------------------------+------------------------------------
Changes (by Tim Graham):

 * stage:  Unreviewed => Accepted
 * severity:  Normal => Release blocker


Old description:

> circular import between forms and models and choices.
>
> before 500e01073adda32d514962 you could import forms just fine.
>
> {{{
> git checkout 500e01073adda32d514962^
> python3 -c"from django.db import models"  # works fine
> python3 -c"from django import forms"  # works fine
> }}}
>

> but since 500e01073adda32d514962 this hasn't worked due to circular
> import.
>
> {{{
> git checkout 500e01073adda32d514962
> python3 -c"from django.db import models"  # works fine
> python3 -c"from django import forms"  # fails:
>
> Traceback (most recent call last):
>   File "<string>", line 1, in <module>
>   File "django/forms/__init__.py", line 6, in <module>
>     from django.forms.boundfield import *  # NOQA
>   File "django/forms/boundfield.py", line 5, in <module>
>     from django.forms.widgets import MultiWidget, Textarea, TextInput
>   File "django/forms/widgets.py", line 15, in <module>
>     from django.utils.choices import normalize_choices
>   File "django/utils/choices.py", line 3, in <module>
>     from django.db.models.enums import ChoicesMeta
>   File "django/db/models/__init__.py", line 3, in <module>
>     from django.db.models.aggregates import *  # NOQA
>   File "django/db/models/aggregates.py", line 5, in <module>
>     from django.db.models.expressions import Case, Func, Star, Value,
> When
>   File "django/db/models/expressions.py", line 12, in <module>
>     from django.db.models import fields
>   File "django/db/models/fields/__init__.py", line 18, in <module>
>     from django.utils.choices import CallableChoiceIterator,
> normalize_choices
> ImportError: cannot import name 'CallableChoiceIterator' from partially
> initialized module 'django.utils.choices' (most likely due to a circular
> import) (django/utils/choices.py)
>
> python3 -c"from django.utils import choices" # also fails:
>
> Traceback (most recent call last):
>   File "<string>", line 1, in <module>
>   File "django/utils/choices.py", line 3, in <module>
>     from django.db.models.enums import ChoicesMeta
>   File "django/db/models/__init__.py", line 3, in <module>
>     from django.db.models.aggregates import *  # NOQA
>   File "django/db/models/aggregates.py", line 5, in <module>
>     from django.db.models.expressions import Case, Func, Star, Value,
> When
>   File "django/db/models/expressions.py", line 12, in <module>
>     from django.db.models import fields
>   File "django/db/models/fields/__init__.py", line 10, in <module>
>     from django import forms
>   File "django/forms/__init__.py", line 6, in <module>
>     from django.forms.boundfield import *  # NOQA
>   File "django/forms/boundfield.py", line 5, in <module>
>     from django.forms.widgets import MultiWidget, Textarea, TextInput
>   File "django/forms/widgets.py", line 15, in <module>
>     from django.utils.choices import normalize_choices
> ImportError: cannot import name 'normalize_choices' from partially
> initialized module 'django.utils.choices' (most likely due to a circular
> import) (django/utils/choices.py)
> }}}
>
> Models has always had a dependency on Forms, but now Models depends on
> Forms depends on `utils.choices` which depend on
> `models.enums.ChoicesMeta`
>
> Summary of the circle: `django.forms` -> 'forms.widgets` ->
> `django.utils.choices` -> `django.db.models.enums` -> `models.__init__`
> -> `models.aggregates` -> `models.fields` -> `django.forms`
>
> If `django.db.models` is imported before forms then it happens to import
> fine because the order of imports happens to lines up perfectally, but
> it's very very fragile. `models.__init__` -> `models.aggregates` ->
> `models.fields`  -> `django.forms` -> 'forms.widgets` ->
> `django.utils.choices` -> `django.db.models.enums`.

New description:

 circular import between forms and models and choices.

 before [500e01073adda32d514962] you could import forms just fine.

 {{{
 git checkout 500e01073adda32d514962^
 python3 -c"from django.db import models"  # works fine
 python3 -c"from django import forms"  # works fine
 }}}


 but since [500e01073adda32d514962] this hasn't worked due to circular
 import.

 {{{
 git checkout 500e01073adda32d514962
 python3 -c"from django.db import models"  # works fine
 python3 -c"from django import forms"  # fails:

 Traceback (most recent call last):
   File "<string>", line 1, in <module>
   File "django/forms/__init__.py", line 6, in <module>
     from django.forms.boundfield import *  # NOQA
   File "django/forms/boundfield.py", line 5, in <module>
     from django.forms.widgets import MultiWidget, Textarea, TextInput
   File "django/forms/widgets.py", line 15, in <module>
     from django.utils.choices import normalize_choices
   File "django/utils/choices.py", line 3, in <module>
     from django.db.models.enums import ChoicesMeta
   File "django/db/models/__init__.py", line 3, in <module>
     from django.db.models.aggregates import *  # NOQA
   File "django/db/models/aggregates.py", line 5, in <module>
     from django.db.models.expressions import Case, Func, Star, Value, When
   File "django/db/models/expressions.py", line 12, in <module>
     from django.db.models import fields
   File "django/db/models/fields/__init__.py", line 18, in <module>
     from django.utils.choices import CallableChoiceIterator,
 normalize_choices
 ImportError: cannot import name 'CallableChoiceIterator' from partially
 initialized module 'django.utils.choices' (most likely due to a circular
 import) (django/utils/choices.py)

 python3 -c"from django.utils import choices" # also fails:

 Traceback (most recent call last):
   File "<string>", line 1, in <module>
   File "django/utils/choices.py", line 3, in <module>
     from django.db.models.enums import ChoicesMeta
   File "django/db/models/__init__.py", line 3, in <module>
     from django.db.models.aggregates import *  # NOQA
   File "django/db/models/aggregates.py", line 5, in <module>
     from django.db.models.expressions import Case, Func, Star, Value, When
   File "django/db/models/expressions.py", line 12, in <module>
     from django.db.models import fields
   File "django/db/models/fields/__init__.py", line 10, in <module>
     from django import forms
   File "django/forms/__init__.py", line 6, in <module>
     from django.forms.boundfield import *  # NOQA
   File "django/forms/boundfield.py", line 5, in <module>
     from django.forms.widgets import MultiWidget, Textarea, TextInput
   File "django/forms/widgets.py", line 15, in <module>
     from django.utils.choices import normalize_choices
 ImportError: cannot import name 'normalize_choices' from partially
 initialized module 'django.utils.choices' (most likely due to a circular
 import) (django/utils/choices.py)
 }}}

 Models has always had a dependency on Forms, but now Models depends on
 Forms depends on `utils.choices` which depend on
 `models.enums.ChoicesMeta`

 Summary of the circle: `django.forms` -> `forms.widgets` ->
 `django.utils.choices` -> `django.db.models.enums` -> `models.__init__` ->
 `models.aggregates` -> `models.fields` -> `django.forms`.

 If `django.db.models` is imported before forms then it happens to import
 fine because the order of imports happens to lines up perfectally, but
 it's very very fragile. `models.__init__` -> `models.aggregates` ->
 `models.fields`  -> `django.forms` -> `forms.widgets` ->
 `django.utils.choices` -> `django.db.models.enums`.

--

-- 
Ticket URL: <https://code.djangoproject.com/ticket/34807#comment:1>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018a4d1c1463-00fb6186-7d9d-4599-b9b3-d7cdd3a3ab62-000000%40eu-central-1.amazonses.com.

Reply via email to