Skip to content

Conversation

@fbozhang
Copy link

@fbozhang fbozhang commented Jul 5, 2025

This modification has the following advantages:

  1. Maintain the input order.
  2. Prevent the output from being a set, which would cause issues with JSON serialization (e.g., when passing parameters to certain third-party SDKs that may internally use json.dumps, and I cannot modify the third party's encoder).

Copy link
Collaborator

@auvipy auvipy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please also add unit tests to verify this and make the CI green

@fbozhang
Copy link
Author

fbozhang commented Jul 5, 2025

please also add unit tests to verify this and make the CI green

I’ve added the tests and the CI is green now.

Copy link
Member

@browniebroke browniebroke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems sensible to me 👍🏻

However, it will have to wait for 3.17 as I see this as potentially disruptive for some downstream users. Left a small suggestion


assert serializer.is_valid()
assert serializer.validated_data['nested']['example'] == {1, 2}
assert serializer.validated_data['nested']['example'] == [1, 2]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hum, that's a bit unfortunate that this data type is exposed at this level. I'm thinking of potential users testing at the serializer level might get some new test failures with this change.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

I think we just need to note in the new version's documentation that the return type is a list, so that if a user upgrades and their tests fail, they'll know exactly what to look at.

Since the input, as mentioned in the signature, is already an ordered sequence (a list or a tuple), it would be much more user-friendly if the output keeps that same order.

@browniebroke browniebroke added this to the 3.17 milestone Jul 6, 2025
@fbozhang
Copy link
Author

fbozhang commented Jul 6, 2025

Seems sensible to me 👍🏻

However, it will have to wait for 3.17 as I see this as potentially disruptive for some downstream users. Left a small suggestion

Good point — waiting for 3.17 sounds like the right call. Appreciate the suggestion!

@fbozhang fbozhang closed this Aug 17, 2025
@fbozhang fbozhang deleted the master branch August 17, 2025 16:37
@fbozhang fbozhang restored the master branch August 17, 2025 16:39
@fbozhang fbozhang reopened this Aug 17, 2025
@stale
Copy link

stale bot commented Oct 18, 2025

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Oct 18, 2025
@auvipy auvipy requested a review from Copilot December 5, 2025 10:19
Copilot finished reviewing on behalf of auvipy December 5, 2025 10:21
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR modifies MultipleChoiceField to return ordered lists instead of sets, ensuring JSON serialization compatibility and maintaining the order of input values. The change uses dict.fromkeys() to deduplicate values while preserving insertion order.

Key Changes

  • Changed to_internal_value() and to_representation() methods to return lists using list(dict.fromkeys([...]))
  • Updated all test expectations from sets to lists
  • Added JSON serialization tests to prevent regression

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
rest_framework/fields.py Modified MultipleChoiceField methods to return ordered lists instead of sets using dict.fromkeys() for deduplication
tests/test_fields.py Updated test expectations from sets to lists, added order-preserving test case, and added JSON serialization validation tests
tests/test_serializer_nested.py Updated nested serializer test assertions to expect lists instead of sets

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 2181 to 2186
valid_inputs = {
(): set(),
('aircon',): {'aircon'},
('aircon', 'manual'): {'aircon', 'manual'},
(): list(),
('aircon',): ['aircon'],
('aircon', 'manual'): ['aircon', 'manual'],
('manual', 'aircon'): ['manual', 'aircon'],
}
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing test case for duplicate values. The change to use dict.fromkeys() deduplicates values, but there's no test case to verify this behavior. Consider adding a test case like ('aircon', 'aircon'): ['aircon'] to ensure duplicates are properly handled and deduplicated while maintaining order.

Copilot uses AI. Check for mistakes.
Comment on lines 2191 to 2194
outputs = [
(['aircon', 'manual', 'incorrect'], {'aircon', 'manual', 'incorrect'})
(['aircon', 'manual', 'incorrect'], ['aircon', 'manual', 'incorrect']),
(['manual', 'aircon', 'incorrect'], ['manual', 'aircon', 'incorrect']),
]
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing test case for duplicate values in the outputs. The to_representation method now deduplicates values while maintaining order, but there's no test to verify this behavior. Consider adding a test case with duplicate values like (['aircon', 'manual', 'aircon'], ['aircon', 'manual']) to ensure the deduplication logic works correctly.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants