Skip to content

Support compare_as callable at field #10834

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

andresliszt
Copy link
Contributor

@andresliszt andresliszt commented Nov 13, 2024

Change Summary

This PR adds compare_as callable in the Field class to add custom comparison. The classical example in the numpy ndarray, see #7307. Note that attrs defines a similar eq callable (see the docs)

import numpy

@define
class C:
   an_array = field(eq=attrs.cmp_using(eq=numpy.array_equal))

and the pydantic implementation looks like

import numpy
from pydantic import BaseModel, ConfigDict, Field


class C(BaseModel):
   an_array: np.ndarray = Field(compare_as=numpy.array_equal, default = np.array([1,2,3]))

   model_config = ConfigDict(allow_arbitrary_types = True)

Note that I intentionally added a default = np.array([1,2,3]) to illustrate the example where exclude_default = True in the serialization, this callable can be forwarded to the Rust side. See this discussion

Related issue number

#7307
#pydantic/pydantic-core#1114

Checklist

  • The pull request title is a good summary of the changes - it will be used in the changelog
  • Unit tests for the changes exist
  • Tests pass on CI
  • Documentation reflects the changes where applicable
  • My PR is ready to review, please add a comment including the phrase "please review" to assign reviewers

Selected Reviewer: @sydney-runkle

@github-actions github-actions bot added the relnotes-fix Used for bugfixes. label Nov 13, 2024
Copy link

codspeed-hq bot commented Nov 13, 2024

CodSpeed Performance Report

Merging #10834 will not alter performance

Comparing andresliszt:add/compare-as (35f2f43) with main (9783bc8)

Summary

✅ 43 untouched benchmarks

Copy link
Contributor

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  pydantic
  fields.py
  main.py
Project Total  

This report was generated by python-coverage-comment-action

@andresliszt
Copy link
Contributor Author

please review

@sydney-runkle
Copy link
Contributor

@andresliszt,

Thanks for the PR. Looks like there are a couple of solutions available on this front, including this one, plus:

Sorry for our review delays here. I've pinged @davidhewitt to see what he thinks regarding the best way forward here. We're eager to get a fix for this / related issues into v2.11!

@andresliszt
Copy link
Contributor Author

@andresliszt,

Thanks for the PR. Looks like there are a couple of solutions available on this front, including this one, plus:

Sorry for our review delays here. I've pinged @davidhewitt to see what he thinks regarding the best way forward here. We're eager to get a fix for this / related issues into v2.11!

Nice! Yeah I openned add default comparison, this is a generalization. In that PR the callable was used only to compare default values, which is done in Rust. The compare_as callable is used in the pydantic BaseModel.__eq__ and also can be forwarded to the Rust side to exclude default values.

@sydney-runkle
Copy link
Contributor

Cool. I think we want to move forward with an approach similar to this one. We're pushing out v2.10 mid week this week, but would love to help get this into v2.11, so will be more active in helping get this across the line after the release :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants