-
Notifications
You must be signed in to change notification settings - Fork 281
allow sorting keys on to_json and to_python by passing in sort_keys #1637
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
base: main
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
📢 Thoughts on this report? Let us know! |
CodSpeed Performance ReportMerging #1637 will not alter performanceComparing Summary
|
07a31f5
to
7222c8d
Compare
please review |
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.
Main issue is perf regression
I separated the test out, I also refactor the functions so we can reuse when Let me know what else I need to improve. Thanks |
please review, not sure how I can take it from here |
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.
Hmm I see now that this is not recursive (it only applies to the top level keys). Would it be hard to make it recursive? I fear that if we implement the non-recursive version someone is going to come along and want the recursive version... if so we can make it a Literal['recursive', 'top-level', 'unsorted']
or something like that.
0cf4b6d
to
95f9329
Compare
Added different sort mode as above, updated the PR description. |
please review 👍 |
95f9329
to
c83a212
Compare
please review 👍 |
c83a212
to
0075a4b
Compare
please review 👍 There is this test that is failing, unclear if its related to my change. Let me know any other places i can optimize. Thanks! |
dce2689
to
5ce696c
Compare
please review 👍 |
dfe7380
to
1b8d824
Compare
please review 👍 |
1 similar comment
please review 👍 |
@DouweM please review :) |
dc0ec59
to
11501f6
Compare
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.
Thanks for your work on this @aezomz! I'm a Rust newbie as well, but I have a feeling we can significantly simplify this code by dropping the recursive dict sorting and moving this to the serializer for the dict type specifically. Can you give that a try please?
I also think it's worth seeing if we can reduce the duplication between the if sort_keys
/else
branches, but I know Rust typing may make that tricky...
Let me know if you get stuck, we can bring in some of our Rust experts!
11501f6
to
200865b
Compare
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.
@aezomz Thanks, this looks a lot better already, but I have a feeling we can get rid of the recursive sorting entirely, if we do it at each level (model + dict) explicitly.
I'm running into the limits of my Rust skills though, and I'm not sure the data types involved actually allow us to do this.
@davidhewitt Would you mind having a Rusty eyed look for us? :)
if !exclude_default(value, &field_extra, serializer).map_err(py_err_se_err)? { | ||
// Get potentially sorted value | ||
if extra.sort_keys { | ||
let sorted_dict = sort_dict_recursive(value.py(), value).map_err(py_err_se_err)?; |
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.
Why do we still need to sort_dict_recursive
here if we're already doing that in the dict serialization itself? (Same question for the 2 calls below)
let value = | ||
value_serializer.to_python(&value, next_include.as_ref(), next_exclude.as_ref(), extra)?; | ||
let value = if extra.sort_keys { | ||
let sorted_value = sort_dict_recursive(py, &value)?; |
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.
Could we not do a recursive sort here, but sort new_dict
specifically after we've built it here?
); | ||
map.serialize_entry(&key, &value_serialize)?; | ||
if extra.sort_keys { | ||
let sorted_dict = sort_dict_recursive(value.py(), &value).map_err(py_err_se_err)?; |
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.
Same as above -- I'd like to get rid of recursive sorting and do this after we build the map
here. But I'm not 100% sure the data types here allow that...
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.
@aezomz Thanks, this looks a lot better already, but I have a feeling we can get rid of the recursive sorting entirely, if we do it at each level (model + dict) explicitly.
I'm running into the limits of my Rust skills though, and I'm not sure the data types involved actually allow us to do this.
@davidhewitt Would you mind having a Rusty eyed look for us? :)
Hello Pydantic Team! This is my first time contributing to a Rust and Pyo3 related repo.
I am also new in Rust.
Do you think this PR will make sense?
Since I have been trying to do model_dump_json with sort keys too.
This feature should simulate the same as how we use
json.dumps(data, sort_keys=True)
Take note that
field_d
is extra and still manage to sortPlease let me know if I miss out any other features that
sort_keys=True
is suppose to do!Thanks!
Change Summary
allow sorting keys on to_json and to_python by passing in sort_keys
Related issue number
should fix pydantic/pydantic#7424
Might need to create another MR on Python repo though, need to check.
Checklist
pydantic-core
(except for expected changes)Selected Reviewer: @davidhewitt