checkpoint

⚒️ Generated with [Fabro](https://fabro.sh)
This commit is contained in:
Fabro 2026-03-16 08:08:44 -04:00
parent 69ed19c68a
commit e16044b4d5
5 changed files with 79 additions and 0 deletions

57
checkpoint.json Normal file
View file

@ -0,0 +1,57 @@
{
"timestamp": "2026-03-16T12:08:44.115224Z",
"current_node": "setup",
"completed_nodes": [
"start",
"setup"
],
"node_retries": {
"start": 1,
"setup": 1
},
"context_values": {
"current_node": "setup",
"internal.retry_count.setup": 1,
"current.preamble": "Goal: Migrations uses value of enum object instead of its name.\nDescription\n\t \n\t\t(last modified by oasl)\n\t \nWhen using Enum object as a default value for a CharField, the generated migration file uses the value of the Enum object instead of the its name. This causes a problem when using Django translation on the value of the Enum object. \nThe problem is that, when the Enum object value get translated to the users language, the old migration files raise an error stating that the Enum does not have the corresponding value. (because the Enum value is translated to another language)\nExample:\nLet say we have this code in models.py:\nfrom enum import Enum\nfrom django.utils.translation import gettext_lazy as _\nfrom django.db import models\nclass Status(Enum):\n\tGOOD = _('Good') # 'Good' will be translated\n\tBAD = _('Bad') # 'Bad' will be translated\n\tdef __str__(self):\n\t\treturn self.name\nclass Item(models.Model):\n\tstatus = models.CharField(default=Status.GOOD, max_length=128)\nIn the generated migration file, the code will be:\n...\n('status', models.CharField(default=Status('Good'), max_length=128))\n...\nAfter the translation, 'Good' will be translated to another word and it will not be part of the Status Enum class any more, so the migration file will raise the error on the previous line:\nValueError: 'Good' is not a valid Status\nShouldn't the code generated by the migration uses the name of the Status Enum 'GOOD', not the value of it, since it is changeable?\nIt should be:\n('status', models.CharField(default=Status['GOOD'], max_length=128))\nThis will be correct regardless of the translated word\n\n\n\n## Additional Context\n\nThanks for this report, however I'm not sure how translated values can brake migrations. Can you provide a sample project to reproduce this issue? Migrations with translatable strings works fine for me: >>> class TextEnum(enum.Enum): ... C = _('translatable value') ... >>> TextEnum(_('translatable value')) <TextEnum.C: 'translatable value'> >>> TextEnum('translatable value') <TextEnum.C: 'translatable value'>\nTo experience the bug: In any Django project, set the default value of a CharField as an enum object: class EnumClass(Enum): VALUE = _('Value') where: VALUE: is the constant enum object name 'Value': is the translatable enum object value In the model: field = models.CharField(default=EnumClass.VALUE, max_length=128) then run: python manage.py makemigrations In the generated migration file, you will notice that the default value of the field is set to: EnumClass('Value'), so it calls the enum object by its translatable value not it is constant name. (This is exactly the BUG, you can think of it without even continue) run: python manage.py migrate In the settings.py file: LANGUAGE_CODE = 'fr-FR' # set it to any language code other than English Run the project after generating, translating, and compiling the messages file (see: message-files) The project will raise the error: ValueError: 'Value' is not a valid EnumClass , on the generated migration file.\nThis use case looks quite niche for me, i.e. I would expect to store a unified values (the same for all languages) and translate only labels visible for users, however I agree that we can fix this.\nHere is the diff based on the @oasl solution Shouldn't the code generated by the migration uses the name of the Status Enum 'GOOD', not the value of it, since it is changeable? It should be: ('status', models.CharField(default=Status['GOOD'], max_length=128)) diff --git a/django/db/migrations/serializer.py b/django/db/migrations/serializer.py index 27b5cbd379..b00c6f0df2 100644 --- a/django/db/migrations/serializer.py +++ b/django/db/migrations/serializer.py @@ -120,9 +120,9 @@ class EnumSerializer(BaseSerializer): def serialize(self): enum_class = self.value.__class__ module = enum_class.__module__ - v_string, v_imports = serializer_factory(self.value.value).serialize() + _, v_imports = serializer_factory(self.value.value).serialize() imports = {'import %s' % module, *v_imports} - return \"%s.%s(%s)\" % (module, enum_class.__name__, v_string), imports + return \"%s.%s['%s']\" % (module, enum_class.__name__, self.value), imports @felixxm, what do you think?\nYou cannot use a string representation of self.value i.e. 'EnumClass.GOOD', IMO we should use a name property: return \"%s.%s[%r]\" % (module, enum_class.__name__, self.value.name), imports\n",
"failure_signature": "setup|deterministic|script failed with exit code: <n> ## stdout fatal: destination path '.' already exists and is not an empty directory.",
"internal.run_id": "01KKV8RMXS7S4C581X4TXV8QN1",
"internal.fidelity": "compact",
"command.output": "fatal: destination path '.' already exists and is not an empty directory.\n",
"command.stderr": "",
"internal.node_visit_count": 1,
"internal.thread_id": "start",
"internal.retry_count.start": 1,
"outcome": "fail",
"failure_class": "deterministic",
"graph.goal": "Migrations uses value of enum object instead of its name.\nDescription\n\t \n\t\t(last modified by oasl)\n\t \nWhen using Enum object as a default value for a CharField, the generated migration file uses the value of the Enum object instead of the its name. This causes a problem when using Django translation on the value of the Enum object. \nThe problem is that, when the Enum object value get translated to the users language, the old migration files raise an error stating that the Enum does not have the corresponding value. (because the Enum value is translated to another language)\nExample:\nLet say we have this code in models.py:\nfrom enum import Enum\nfrom django.utils.translation import gettext_lazy as _\nfrom django.db import models\nclass Status(Enum):\n\tGOOD = _('Good') # 'Good' will be translated\n\tBAD = _('Bad') # 'Bad' will be translated\n\tdef __str__(self):\n\t\treturn self.name\nclass Item(models.Model):\n\tstatus = models.CharField(default=Status.GOOD, max_length=128)\nIn the generated migration file, the code will be:\n...\n('status', models.CharField(default=Status('Good'), max_length=128))\n...\nAfter the translation, 'Good' will be translated to another word and it will not be part of the Status Enum class any more, so the migration file will raise the error on the previous line:\nValueError: 'Good' is not a valid Status\nShouldn't the code generated by the migration uses the name of the Status Enum 'GOOD', not the value of it, since it is changeable?\nIt should be:\n('status', models.CharField(default=Status['GOOD'], max_length=128))\nThis will be correct regardless of the translated word\n\n\n\n## Additional Context\n\nThanks for this report, however I'm not sure how translated values can brake migrations. Can you provide a sample project to reproduce this issue? Migrations with translatable strings works fine for me: >>> class TextEnum(enum.Enum): ... C = _('translatable value') ... >>> TextEnum(_('translatable value')) <TextEnum.C: 'translatable value'> >>> TextEnum('translatable value') <TextEnum.C: 'translatable value'>\nTo experience the bug: In any Django project, set the default value of a CharField as an enum object: class EnumClass(Enum): VALUE = _('Value') where: VALUE: is the constant enum object name 'Value': is the translatable enum object value In the model: field = models.CharField(default=EnumClass.VALUE, max_length=128) then run: python manage.py makemigrations In the generated migration file, you will notice that the default value of the field is set to: EnumClass('Value'), so it calls the enum object by its translatable value not it is constant name. (This is exactly the BUG, you can think of it without even continue) run: python manage.py migrate In the settings.py file: LANGUAGE_CODE = 'fr-FR' # set it to any language code other than English Run the project after generating, translating, and compiling the messages file (see: message-files) The project will raise the error: ValueError: 'Value' is not a valid EnumClass , on the generated migration file.\nThis use case looks quite niche for me, i.e. I would expect to store a unified values (the same for all languages) and translate only labels visible for users, however I agree that we can fix this.\nHere is the diff based on the @oasl solution Shouldn't the code generated by the migration uses the name of the Status Enum 'GOOD', not the value of it, since it is changeable? It should be: ('status', models.CharField(default=Status['GOOD'], max_length=128)) diff --git a/django/db/migrations/serializer.py b/django/db/migrations/serializer.py index 27b5cbd379..b00c6f0df2 100644 --- a/django/db/migrations/serializer.py +++ b/django/db/migrations/serializer.py @@ -120,9 +120,9 @@ class EnumSerializer(BaseSerializer): def serialize(self): enum_class = self.value.__class__ module = enum_class.__module__ - v_string, v_imports = serializer_factory(self.value.value).serialize() + _, v_imports = serializer_factory(self.value.value).serialize() imports = {'import %s' % module, *v_imports} - return \"%s.%s(%s)\" % (module, enum_class.__name__, v_string), imports + return \"%s.%s['%s']\" % (module, enum_class.__name__, self.value), imports @felixxm, what do you think?\nYou cannot use a string representation of self.value i.e. 'EnumClass.GOOD', IMO we should use a name property: return \"%s.%s[%r]\" % (module, enum_class.__name__, self.value.name), imports",
"graph.rankdir": "LR",
"thread.start.current_node": "setup"
},
"logs": [],
"node_outcomes": {
"start": {
"status": "success",
"duration_ms": 0
},
"setup": {
"status": "fail",
"context_updates": {
"command.output": "fatal: destination path '.' already exists and is not an empty directory.\n",
"command.stderr": ""
},
"failure": {
"message": "Script failed with exit code: 128\n\n## stdout\nfatal: destination path '.' already exists and is not an empty directory.\n",
"failure_class": "deterministic"
},
"duration_ms": 24
}
},
"next_node_id": "solve",
"loop_failure_signatures": {
"setup|deterministic|script failed with exit code: <n> ## stdout fatal: destination path '.' already exists and is not an empty directory.": 1
},
"node_visits": {
"start": 1,
"setup": 1
}
}

View file

@ -0,0 +1,5 @@
{
"command": "git clone https://github.com/django/django.git . && git checkout e02f67ef2d03d48128e7a118bf75f0418e24e8ac && python -m pip install -e .",
"language": "shell",
"timeout_ms": null
}

View file

@ -0,0 +1,5 @@
{
"duration_ms": 23,
"exit_code": 128,
"timed_out": false
}

6
nodes/setup/status.json Normal file
View file

@ -0,0 +1,6 @@
{
"status": "fail",
"notes": null,
"failure_reason": "Script failed with exit code: 128\n\n## stdout\nfatal: destination path '.' already exists and is not an empty directory.\n",
"timestamp": "2026-03-16T12:08:44.115050+00:00"
}

6
nodes/start/status.json Normal file
View file

@ -0,0 +1,6 @@
{
"status": "success",
"notes": null,
"failure_reason": null,
"timestamp": "2026-03-16T12:08:44.089931+00:00"
}