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

Prevent crash with Unpack of a fixed tuple in PEP695 type alias#18451

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

Conversation

@sterliakov
Copy link
Collaborator

@sterliakovsterliakov commentedJan 13, 2025
edited by ilevkivskyi
Loading

Fixes#18309.

Add missingvisit_type_alias_stmt() implementation to mixedtraverser.py to visit the alias target directly.

@github-actions

This comment has been minimized.

@sterliakov
Copy link
CollaboratorAuthor

Primer results are terrible, I'll look closer tomorrow - all those errors should have moved to another location, not disappeared entirely.

@sterliakovsterliakovforce-pushed thebugfix/st-type-alias-transform branch 2 times, most recently from57ba734 to0ceb6adCompareJanuary 13, 2025 13:36
@github-actions

This comment has been minimized.

@sterliakov
Copy link
CollaboratorAuthor

sterliakov commentedJan 13, 2025
edited
Loading

This is more complicated than I expected.

The problem reduces to the following (playground):

fromcollections.abcimportCallable,CoroutinefromtypingimportAny,Concatenate,Generic,TypeVarIntFun=TypeVar("IntFun",bound=Callable[Concatenate[int, ...],str])StrFun=TypeVar("StrFun",bound=Callable[Concatenate[str, ...],str])AnyFun=TypeVar("AnyFun",bound=Callable[...,str])classIntC(Generic[IntFun]): ...classStrC(Generic[StrFun]): ...AnyC=IntC[AnyFun]|StrC[AnyFun]defrun(_:AnyC[IntFun])->IntFun: ...# E: Type argument "IntFun" of "StrC" must be a subtype of "Callable[[str, VarArg(Any), KwArg(Any)], str]"  [type-var]

(the error exists on master and does not exist with this patch applied)

And I have no idea what is more reasonable here.AnyC generic arg allows any callable, soAnyC[IntFun] should be allowed. However, this feels like a type error, because that means allowingStrC[IntFun]?However, I don't see how such type can appear anywhere: if somethingresolves toStrC[IntFun], that would be an error?

@A5rocks
Copy link
Collaborator

Even simpler reproducer (no callables):

importtypingIntT=typing.TypeVar("IntT",bound=int)StrT=typing.TypeVar("StrT",bound=str)AnyT=typing.TypeVar("AnyT",bound=typing.Any)classIntC(typing.Generic[IntT]): ...classStrC(typing.Generic[StrT]): ...AnyC=IntC[AnyT]|StrC[AnyT]defrun(_:AnyC[StrT])->StrT: ...# E: Type argument "StrT" of "IntC" must be a subtype of "int"

IMO there should be an error onAnyC, rather than at usage time. Yes, thebound=Any is there, but... like... it's not necessarilyAny. If the user wantsAny they can sayAnyC = IntC[Any] | StrC[Any]. I'll go open an issue about this :^)

@sterliakov
Copy link
CollaboratorAuthor

@A5rocks I'm not sure I want to see any errors on theAnyC definition: it would be extremely weird to read that something bound to Any can't be used to substitute some typevar. Having errors when aliases are defined with incompatible typevars is great (we didn't before, this PR makes such aliases fail early). But rejecting a compatible typevar (and one withAny bound should probably be considered compatible) is questionable.

@A5rocks
Copy link
Collaborator

A5rocks commentedJan 13, 2025
edited
Loading

I'm not sure I want to see any errors on theAnyC definition: it would be extremely weird to read that something bound to Any can't be used to substitute some typevar.

I thinkAny in the bound is actually not useful information. IMO, the type alias is obviously wrong if you cannot use it (other than passingAny), so it should get an error. I tried looking at PEP 484 forbound=... and it just says:

while an upper bound just requires that the actual type is a subtype of the boundary type.

... which isn't very useful. I mean at best we could pretend "subtype" here means the PEP 483 version of it (which doesn't includeAny) but the typing spec says:

an upper bound just requires that the actual type isassignable to the bound.

and like, assignability allowsAny I'm pretty sure. And every type is "assignable" toAny I think. So it doesn't help.

@ilevkivskyi
Copy link
Member

Not giving error on type alias definition is intentional. It is to allow a pattern like this:

# in one fileT=TypeVar("T",bound=int)classC(Generic[T]): ...# in other fileT=TypeVar("T")# same as bound=objectA=list[C[T]]x:A[int]# OKy:A[str]# Error

People often use "throw away" type variable for type aliases. With the error at alias definition, one would be forced to copy over all type variable bounds for no added safety.

sterliakov reacted with thumbs up emoji

@sterliakov
Copy link
CollaboratorAuthor

I agree that this strictness with definition-time checks somewhat harms usability. Anyway, let's see where#18456 goes. I don't believe that changing behaviour of aliases to fix the tree traversal is reasonable.

Is there something else we can visit instead ofget_proper_type or the alias as here? We need to make the visitor work on the original tuple.

In the meantime#18456 takes another approach that doesn't affect checking existing aliases, but suffers from not modifying the tuple where it is expected. Maybe that's good enough?

@ilevkivskyi
Copy link
Member

@sterliakov A proper fix would be to simply updatemixedtraverser.py to havevisit_type_alias_stmt() that would accept the alias target (similar tovisit_type_allias_expr() you will need to set/unsetself.in_type_lias_expr flag to avoid errors about bounds in type alias definitions). I am kind of surprised that nothing else broke, as it is a relatively major omission in the implementation of new syntax.

Btw another thing (that I noticed while looking at your other attempt) is that you may need to add this line

# Invalidate recursive status cache in case it was previously set.existing.node._is_recursive=None

to the new syntax code path, as it looks like I forgot to copy it in#17961 (if you do, please also add a corresponding test), you can make a separate PR for this.

@sterliakov
Copy link
CollaboratorAuthor

sterliakov commentedJan 14, 2025
edited
Loading

Amazing, thanks! I got lost invisit_type_alias{,_stmt,_expr,_type} when looking through these overrides, probably due to this long common prefix, and failed to notice that this one isn't overridden.

you may need to add this line

It's there in reuseddef _update_type_alias, yes, and I'll keep that PR to reduce code duplication - let's focus on the traverser here.

@github-actions
Copy link
Contributor

According tomypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅

@sterliakovsterliakov marked this pull request as ready for reviewJanuary 15, 2025 00:12
Copy link
Member

@ilevkivskyiilevkivskyi left a comment

Choose a reason for hiding this comment

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

Please update the PR description so that it reflects the current state of the PR.

sterliakov reacted with thumbs up emoji
@ilevkivskyiilevkivskyi merged commitfb7b254 intopython:masterJan 15, 2025
18 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@ilevkivskyiilevkivskyiilevkivskyi approved these changes

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

I can not assign a value to variable of a type built from the unpacking of another type with the new pythong 3.13 generic syntax

3 participants

@sterliakov@A5rocks@ilevkivskyi

[8]ページ先頭

©2009-2025 Movatter.jp