-
-
Notifications
You must be signed in to change notification settings - Fork 928
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Avoid losing type of UUID when serializing/deserializing #1575
Conversation
Serializing UUIDs as strs and deserializing them as strs can lead to somewhat obscure bugs such as the one that led to the creation of this PR in django-cacheback codeinthehole/django-cacheback#100 which some would call unexpected behaviour. After all, an UUID is altogether a different type from strs and if bytes got their own serializer/deserializer for UUID the same logic should apply.
for more information, see https://pre-commit.ci
@@ -29,7 +29,7 @@ class JSONEncoder(_encoder_cls): | |||
def default(self, o, | |||
dates=(datetime.datetime, datetime.date), | |||
times=(datetime.time,), | |||
textual=(decimal.Decimal, uuid.UUID, DjangoPromise), | |||
textual=(decimal.Decimal, DjangoPromise), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we document this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmmm, there's an entry for - JSON serializer now handles datetimes, Django promise, UUID and Decimal.
in 4.0. It doesn't specify how it's handled but maybe (if accepted) this change could be documented as part of the next release?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I pushed 6b89388 to keep the userguide (the only place I could find where JSON serialization is discussed) updated c:
In PR celery#1575 a new serializer for UUIDs was introduced, however it fails when deserializing UUIDs which version is not within 1 and 5. Given that there's a new standard (https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-04) ganining traction that introduces UUIDs v6, v7 and v8, we change the code to allow such versions. In the test, we generate one UUID for each version using the package `uuid6` (https://github.com/oittaa/uuid6-python)
In PR #1575 a new serializer for UUIDs was introduced, however it fails when deserializing UUIDs which version is not within 1 and 5. Given that there's a new standard (https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-04) ganining traction that introduces UUIDs v6, v7 and v8, we change the code to allow such versions. In the test, we generate one UUID for each version using the package `uuid6` (https://github.com/oittaa/uuid6-python)
Kombu 5.3 fixed bugs that incorrectly cast UUID and datetime objects to strings. We are expected those to be strings in many places, so going to constrain this for now. celery/kombu#1575 celery/kombu#1515 https://github.com/celery/kombu/releases/tag/v5.3.0
Kombu 5.3 fixed bugs that incorrectly cast UUID and datetime objects to strings. We expect those to be strings in many places. celery/kombu#1575 celery/kombu#1515 https://github.com/celery/kombu/releases/tag/v5.3.0
This PR is quite dangerous as if you have celery workers running 5.2.4, and you are deploying a new codebase using celery 5.3.1, the old workers cannot decode the arguments for the new tasks if there was a |
cc @auvipy |
Sorry, this is not the actual PR that introduced the change. I'll try to find the original one and post the warning there. |
Serializing UUIDs as strs and deserializing them as strs can lead to
somewhat obscure bugs such as the one that led to the creation of this
PR in django-cacheback
codeinthehole/django-cacheback#100 which some
would call unexpected behaviour.
After all, an UUID is altogether a different type from strs and if
bytes got their own serializer/deserializer for UUID the same logic
should apply.
I added a case for every uuidX constructor found in CPython.
Lemme know what you think of it and if there's anything I'm misreading :D.
P.D: I understand that UUIDs are now serialized as a convenience for users
but perhaps it's a bit non-intuitive that after versions of not supporting them
now they're converted to a different type when deserializing?