Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Fixmro of generic subclass#10100

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
sydney-runkle merged 11 commits intopydantic:mainfromkc0506:fix-generic-mro
Sep 10, 2024
Merged

Conversation

kc0506
Copy link
Contributor

@kc0506kc0506 commentedAug 11, 2024
edited
Loading

Change Summary

OverrideModelMetaclass.mro such that indexed generic type can be inserted into__mro__ of its subclasses.

For example:

classA(BaseModel,Generic[T]): ...classB(A[T]): ...classC(B[bool]): ...# beforeassertC.__mro__== (C,B[bool],B,A,BaseModel,Generic,object)# afterassertC.__mro__== (C,B[bool],B,A[bool],A,BaseModel,Generic,object)

This allowC() to be assigned toA[bool].

I have checked all testcases intest_generic.py. This change doesn't break existing tests. Also, I collected all the tests where__mro__ is affected by this change, and add them into new tests.

Related issue number

fix#10039

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

sydney-runkle reacted with thumbs up emoji
@github-actionsgithub-actionsbot added the relnotes-fixUsed for bugfixes. labelAug 11, 2024
@kc0506kc0506 changed the titleFix genericmroFixmro of generic subclassAug 11, 2024
@codspeed-hqCodSpeed HQ
Copy link

codspeed-hqbot commentedAug 11, 2024
edited
Loading

CodSpeed Performance Report

Merging#10100 willnot alter performance

Comparingkc0506:fix-generic-mro (dc7cd94) withmain (287c266)

Summary

✅ 49 untouched benchmarks

@github-actionsGitHub Actions
Copy link
Contributor

github-actionsbot commentedAug 11, 2024
edited
Loading

Coverage report

This PR does not seem to contain any modification to coverable code.

@sydney-runkle
Copy link
Contributor

Hmm, I think the way to solve this is actually going to be revalidating instances of classes that have a shared generic parent. Happy to think about this proposal more tomorrow.

@dmontagu, I haven't looked in depth, but this is up your alley, and might be worth a glance.

Copy link
Contributor

@dmontagudmontagu left a comment

Choose a reason for hiding this comment

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

So I think this may make sense in principle, but if we merge it I think we should try to do a better job of substituting the parameters in intermediate classes even when they aren’t the same.

E.g., if I haveclass A(BaseModel, Generic[T]):… andclass B(A[T], Generic[S]): … we should haveA[int] in the mro ofB[int, str]. I don’t think it should be too hard to achieve this (or at least do a better job than exact equality checking), but if it is unreasonably hard to follow through the substitutions we don’t need to let perfect get in the way of better.

That said, I am not 100% sure if this is better than revalidating into the other generic type. But I think this will result in better behavior in the cases that are affected, so I’m inclined to merge this approach.

@kc0506
Copy link
ContributorAuthor

kc0506 commentedAug 15, 2024
edited
Loading

@dmontagu Thanks for the review!
I made some changes, so now this can work:

classA(BaseModel,Generic[T1]): ...classB1(A[T1],Generic[T1,T2]): ...assertA[int]inB1[T1,str][int].__mro__assertA[int]inB1[int,str].__mro__

Please let me know if there are still some cases I didn't think through.

@sydney-runklesydney-runkle added relnotes-changeUsed for changes to existing functionality which don't have a better categorization. and removed relnotes-fixUsed for bugfixes. labelsAug 15, 2024
# class B(A[int], Generic[T]): ...
# class C(B[str], Generic[T]): ...
#
key = '__pydantic_inserted_mro_origins__'
Copy link
Contributor

Choose a reason for hiding this comment

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

This__pydantic_inserted_mro_origins__ should be added as an annotated attribute on theBaseModel class if we are going to use it like this. I think it would also be reasonable to add it as a field in the__pydantic_generic_metadata__ if that makes sense, but if we are using a new attribute inBaseModel it should be added near this area:

__pydantic_generic_metadata__:ClassVar[_generics.PydanticGenericMetadata]

sydney-runkle reacted with thumbs up emoji
Copy link
Contributor

@dmontagudmontagu left a comment
edited
Loading

Choose a reason for hiding this comment

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

Seehttps://github.com/pydantic/pydantic/pull/10100/files#r1721798498; once that is addressed I'm good with this PR.

@sydney-runklesydney-runkle mentioned this pull requestAug 20, 2024
19 tasks
@sydney-runklesydney-runkle added the awaiting author revisionawaiting changes from the PR author labelAug 20, 2024
@kc0506
Copy link
ContributorAuthor

kc0506 commentedAug 20, 2024
edited
Loading

@dmontagu I found that my current solution cannot handle this (very unlikely) case:

classA(BaseModel,Generic[T1]): ...classB(A[T2],Generic[T2]): ...classC(B[T3],Generic[T3]): ...classD(C[T1],Generic[T1]): ...classE(D[T2],Generic[T2]):...

because the MRO ofD[T2] will be like

D[~T2], D,C[~T2], C[~T1], C,B[~T2], B[~T1], B[~T3], B,A[~T2], A[~T1], A[~T3], A[~T2], A, ...

and the repeatedA[T2] is invalid.

Do you think this is worth fixing, or we could mark it as an expected fail and address it in other PR?

@dmontagu
Copy link
Contributor

dmontagu commentedAug 20, 2024
edited
Loading

I'd say it's at least worth adding an xfailing test, I don't think it's the craziest case but I also don't think getting that right needs to prevent releasing a partial fix that fixes cases that are much more likely to be encountered.

sydney-runkle reacted with thumbs up emoji

@sydney-runkle
Copy link
Contributor

@kc0506, if you're able to finish this up in the next couple of days, we can get this into our v2.9 release! Thanks for your awesome work here.

@kc0506
Copy link
ContributorAuthor

kc0506 commentedAug 22, 2024
edited
Loading

@kc0506, if you're able to finish this up in the next couple of days, we can get this into our v2.9 release! Thanks for your awesome work here.

Sure, I will try to wrap it up by this weekend.

sydney-runkle reacted with heart emoji

@kc0506
Copy link
ContributorAuthor

I've updated the logic insdiemro. The new approach does not need an extra class variable and can solve the failed case mentioned above, as well as remove redundant bases (e.g.A[int], A[T2], A[T1], A, ... will now become simplyA[int], A, ...).

I think this is ready to be merged. Looking forward to any feedbacks!

sydney-runkle reacted with thumbs up emoji

@kc0506kc0506 requested a review fromdmontaguAugust 26, 2024 15:37
Copy link
Contributor

@dmontagudmontagu left a comment

Choose a reason for hiding this comment

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

I won't be surprised if this still ends up needing to be tweaked in some way in the future, but this is closer to what I had imagined the relevant code should look like, great improvement.

LGTM

sydney-runkle reacted with heart emoji
@sydney-runkle
Copy link
Contributor

sydney-runkle commentedAug 27, 2024
edited
Loading

@kc0506,

Awesome work here. I'm going to do another review here as well this afternoon, then we'll merge this after our v2.9 release (we've already released the beta, so can't introduce any major changes during this beta trial period).

kc0506 reacted with thumbs up emoji

Copy link
Contributor

@sydney-runklesydney-runkle left a comment

Choose a reason for hiding this comment

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

Amazing work here. Thanks a bunch for your contribution!!

I'm a bit worried about a few of the unchecked dict accesses, so let's make sure no unexpected behavior is witnessed here leading up to our v2.10 release.

@sydney-runklesydney-runkleenabled auto-merge (squash)September 10, 2024 17:03
@sydney-runklesydney-runkle merged commitcb57c13 intopydantic:mainSep 10, 2024
57 checks passed
@kc0506kc0506 deleted the fix-generic-mro branchOctober 14, 2024 10:05
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@dmontagudmontagudmontagu approved these changes

@sydney-runklesydney-runklesydney-runkle approved these changes

Assignees
No one assigned
Labels
ready for reviewrelnotes-changeUsed for changes to existing functionality which don't have a better categorization.
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

Nested generic inheritance
3 participants
@kc0506@sydney-runkle@dmontagu

[8]ページ先頭

©2009-2025 Movatter.jp