Fixing EnumField choices validation
This commit is contained in:
		| @@ -9,6 +9,7 @@ Development | |||||||
| - (Fill this out as you fix issues and develop your features). | - (Fill this out as you fix issues and develop your features). | ||||||
| - Bug fix: ignore LazyReferenceFields when clearing _changed_fields #2484 | - Bug fix: ignore LazyReferenceFields when clearing _changed_fields #2484 | ||||||
| - Improve connection doc #2481 | - Improve connection doc #2481 | ||||||
|  | - EnumField improvements: now `choices` limits the values of an enum to allow | ||||||
|  |  | ||||||
| Changes in 0.23.0 | Changes in 0.23.0 | ||||||
| ================= | ================= | ||||||
|   | |||||||
| @@ -1636,11 +1636,14 @@ class EnumField(BaseField): | |||||||
|  |  | ||||||
|     def __init__(self, enum, **kwargs): |     def __init__(self, enum, **kwargs): | ||||||
|         self._enum_cls = enum |         self._enum_cls = enum | ||||||
|         if "choices" in kwargs: |         if kwargs.get("choices"): | ||||||
|             raise ValueError( |             invalid_choices = [] | ||||||
|                 "'choices' can't be set on EnumField, " |             for choice in kwargs["choices"]: | ||||||
|                 "it is implicitly set as the enum class" |                 if not isinstance(choice, enum): | ||||||
|             ) |                     invalid_choices.append(choice) | ||||||
|  |             if invalid_choices: | ||||||
|  |                 raise ValueError("Invalid choices: %r" % invalid_choices) | ||||||
|  |         else: | ||||||
|             kwargs["choices"] = list(self._enum_cls)  # Implicit validator |             kwargs["choices"] = list(self._enum_cls)  # Implicit validator | ||||||
|         super().__init__(**kwargs) |         super().__init__(**kwargs) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,6 +12,11 @@ class Status(Enum): | |||||||
|     DONE = "done" |     DONE = "done" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class Color(Enum): | ||||||
|  |     RED = 1 | ||||||
|  |     BLUE = 2 | ||||||
|  |  | ||||||
|  |  | ||||||
| class ModelWithEnum(Document): | class ModelWithEnum(Document): | ||||||
|     status = EnumField(Status) |     status = EnumField(Status) | ||||||
|  |  | ||||||
| @@ -74,14 +79,17 @@ class TestStringEnumField(MongoDBTestCase): | |||||||
|         with pytest.raises(ValidationError): |         with pytest.raises(ValidationError): | ||||||
|             m.validate() |             m.validate() | ||||||
|  |  | ||||||
|     def test_user_is_informed_when_tries_to_set_choices(self): |     def test_partial_choices(self): | ||||||
|         with pytest.raises(ValueError, match="'choices' can't be set on EnumField"): |         partial = [Status.DONE] | ||||||
|  |         assert EnumField(Status, choices=partial).choices == partial | ||||||
|  |  | ||||||
|  |     def test_wrong_choices(self): | ||||||
|  |         with pytest.raises(ValueError, match="Invalid choices"): | ||||||
|             EnumField(Status, choices=["my", "custom", "options"]) |             EnumField(Status, choices=["my", "custom", "options"]) | ||||||
|  |         with pytest.raises(ValueError, match="Invalid choices"): | ||||||
|  |             EnumField(Status, choices=[Color.RED]) | ||||||
| class Color(Enum): |         with pytest.raises(ValueError, match="Invalid choices"): | ||||||
|     RED = 1 |             EnumField(Status, choices=[Status.DONE, Color.RED]) | ||||||
|     BLUE = 2 |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class ModelWithColor(Document): | class ModelWithColor(Document): | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user