fix: Handle unhashable BooleanField representation value#9973
Conversation
There was a problem hiding this comment.
Pull request overview
This PR makes BooleanField.to_representation() resilient to unhashable values (e.g., [], {}, set()) by suppressing TypeError during membership checks, aligning its behavior with to_internal_value() while preserving the existing bool(value) fallback.
Changes:
- Wrap
BooleanField.to_representation()’s TRUE/FALSE/NULL token membership checks incontextlib.suppress(TypeError). - Update
BooleanFieldoutput tests to use a list of(value, expected)pairs (allowing unhashable test inputs) and add coverage for unhashable collections.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
rest_framework/fields.py |
Suppresses TypeError during set-membership checks in BooleanField.to_representation() so unhashable values fall back to bool(value). |
tests/test_fields.py |
Extends BooleanField representation coverage to include unhashable collections by switching outputs to tuple-pairs and adding new cases. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
PR seems reasonable and appropriate. Only a potential edge-case scenario might be cause for concern; Let's say that, either by mistake or due to a custom library integration, a complex custom object that cannot be converted to a string or whose type cannot be checked was passed to the Old Behavior: The code raised a New Behavior: The code does not crash; instead, it passes the object through the However, this is simply a bug fix that needed to be addressed anyway. That’s why I think it’s acceptable. |
Taking a step back away from the model field itself, what concrete example would cause that from being used? I'm thinking of a minimal example of a serializer with the data/Python object that would make use of this. I think we would need to map a complex field (e.g. dict) to a |
Yes, actually, this is more of an improvement aimed at preventing the “representation” step from crashing. As it stands now, the system crashes when dealing with a complex variable type because there is no mechanism to handle this situation. This code prevents that error and manages this part using a boolean. |
This is a small consistency fix for
BooleanField.to_representation(), matching the existingTypeErrorhandling used byto_internal_value()while preserving the existingbool(value)fallback.Summary
BooleanField.to_representation()now handles unhashable values consistently withto_internal_value().Previously, values like
[],{}, orset()could raiseTypeErrorduring membership checks before reaching the existingbool(value)fallback. This change suppressesTypeErroraround the explicit true/false/null token checks, allowing unrecognized unhashable values to be represented by their truthiness.Test
uv run --no-project --with 'django==5.2.*' --with 'pytest==9.*' --with pytest-django --with dj-database-url --with importlib-metadata --with pytz -m pytest tests/test_fields.py -k BooleanField