-
Notifications
You must be signed in to change notification settings - Fork 267
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
Raise validation error when unhashable items added to a set #1619
Raise validation error when unhashable items added to a set #1619
Conversation
CodSpeed Performance ReportMerging #1619 will not alter performanceComparing Summary
|
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1619 +/- ##
==========================================
- Coverage 90.21% 89.60% -0.61%
==========================================
Files 106 115 +9
Lines 16339 17929 +1590
Branches 36 25 -11
==========================================
+ Hits 14740 16066 +1326
- Misses 1592 1844 +252
- Partials 7 19 +12
... and 63 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
|
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.
Thanks, overall this looks in the right direction, I'd like to suggest an efficiency gain before merging.
src/input/return_enums.rs
Outdated
match validate_hashable(py, item.borrow_input(), state, validator) { | ||
Ok(item) => { | ||
set.build_add(item)?; |
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.
Making the change like this will have the cost of running hash twice for every element added to the set. I suggest instead the code is adjusted to only try calling item.hash()
if set.build_add(item)
fails, that way we're only adding overhead on the unhappy path.
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.
Sinceset.build_set
takes ownership of item
, instead of cloning item
to calculate the hash if set.build_set
fails, I thought it would be better to instead inspect the PyErr
and return the SetItemNotHashable
if it's a TypeError
. What do you think?
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.
Let's go with that 👍
ee71da1
to
4eecd19
Compare
@pydantic/oss - any opinion on the new error type introduced here? Seems ok to me, though we'll need to handle downstream in |
Thanks @mikeedjones for looking into this. Can this be made more generic in some way? Sets are not the only type requiring hashable members. Dict keys comes to mind, although I don't think there's currently a way to reproduce the same error, as we only allow mappings to validate against dicts (meaning if you already have a valid mapping, keys are guaranteed to be hashable). |
I agree that would be better @Viicos - but as you point out in most other instances the hashability of the relevant item is checked much earlier in the validation. A generic version might be a validator for python's |
tests/validators/test_set.py
Outdated
def __hash__(self): | ||
raise TypeError('unhashable type') |
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.
Nit: the canonical way to create an unhashable type is to set __hash__ = None
Yeah I think it's fine to continue with this approach scoped to sets, and we can extend/change this in the future. |
LGTM! |
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 @mikeedjones for adding the downstream PR too 👍
Change Summary
Adds the
validate_hashable
function to check that items being added to a set byvalidate_iter_to_set
have an implemented__hash__
function. Adds the associatedSetItemNotHashable
error and error message.I'm not sure this is the best place to check whether or not items being added to a set are hashable, and I'm not sure binding the object is strictly necessary to check its hashability. Maybe this validation should happen in
SetValidator
instead and only capture the case where the user is specifically trying to add unhashable objects to a set?Related issue number
pydantic/pydantic#11360 in the pydantic repo - I can open a mirror issue in pydantic-core?
Checklist
pydantic-core
(except for expected changes)Selected Reviewer: @davidhewitt