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

Introduce temporary named expressions formatch subjects#18446

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

Conversation

@sterliakov
Copy link
Collaborator

@sterliakovsterliakov commentedJan 11, 2025
edited
Loading

Fixes#18440.Fixes#17230.Fixes#16650. Improves behavior in#14731 (but still thinks that match is non-exhaustive, "missing return" false positive remains).

#16503 did this specifically forCallExpr, but that isn't the only kind of such statements. I propose to expand this for more general expressions and believe that a blacklist is more reasonable here: we donot want to introduce a temporary name only for certain expressions that either are already named or can be used to infer contained variables (inline tuple/list/dict/set literals).

Writing logic to generate a name for every other kind of expression would be quite cumbersome - I circumvent this by using a simple counter to generate unique names on demand.

@github-actions

This comment has been minimized.

@sterliakov
Copy link
CollaboratorAuthor

Whoa, I expected this to produce at least a couple of unused ignore diagnostics, but apparently pattern matching isn't very popular in wild...

@sterliakovsterliakov marked this pull request as ready for reviewJanuary 11, 2025 21:44
@github-actions

This comment has been minimized.

@sterliakov

This comment was marked as resolved.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@sterliakov
Copy link
CollaboratorAuthor

This interferes with recently added narrowing by item/attribute (aka discriminated union,testMatchNarrowingUnionClassViaAttribute). So a simple solution like this won't fly. This information for index/attr should be stored in some other way to support narrowing of attr/item and the object itself at the same time. This may still work for other, less informative nodes (await?)

@sterliakovsterliakov reopened thisApr 4, 2025
@sterliakovsterliakov marked this pull request as draftApril 4, 2025 22:41
@github-actions

This comment has been minimized.

@sterliakov
Copy link
CollaboratorAuthor

To support narrowing the subject and its "dependencies" simultaneously, I propose to just push the narrowed type of subject to typemap as the type of its original form, allowing for any inference on it.

@sterliakovsterliakov marked this pull request as ready for reviewApril 5, 2025 01:28
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

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.

LG, but I have one suggestion

def_make_named_statement_for_match(self,s:MatchStmt)->Expression:
"""Construct a fake NameExpr for inference if a match clause is complex."""
subject=s.subject
expressions_to_preserve= (
Copy link
Member

Choose a reason for hiding this comment

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

IIUC match statement handling re-uses binder in some code paths. Then I I think instead of this list we should do the same that binder does:

frommypy.literalsimportliteral# name is confusing, but this is what you wantifnotliteral(expr):<makedummyname>

Copy link
CollaboratorAuthor

Choose a reason for hiding this comment

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

Nice idea, but are you sure?

mypy/mypy/literals.py

Lines 117 to 124 infc991a0

defliteral(e:Expression)->int:
"""Return the literal kind for an expression."""
ifisinstance(e,ComparisonExpr):
returnmin(literal(o)foroine.operands)
elifisinstance(e,OpExpr):
returnmin(literal(e.left),literal(e.right))

This will breaktestMatchOperations case added here, for example, as1 < 2 will returnLITERAL_YES, and we do not store types of comparison exprs in binder AFAIC.

Copy link
Member

Choose a reason for hiding this comment

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

Right, binder also doesisinstance(expr, (IndexExpr, MemberExpr, NameExpr)) before checking forliteral(). But then this list will not be simplified much. Even then probably it would make sense to somehow re-use binder logic here.

Btw I am not super-confident aboutAssignmentExpr, what about something likex := y[z] (wherez isnot a literal)? This will have troubles with binder.

Copy link
Member

Choose a reason for hiding this comment

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

Sorry, I meant the oppositex[y] := z with non-literaly.

Copy link
CollaboratorAuthor

Choose a reason for hiding this comment

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

Sorry, I meant the oppositex[y] := z with non-literaly

Did I miss a new PEP? If I didn't, this should be reported elsewhere as a SyntaxError...

Copy link
CollaboratorAuthor

Choose a reason for hiding this comment

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

Maybe we can add a common ancestor to{Str,Bytes,Int,Float,Complex}Expr? Semantically they should have a "primitive literal" superclass, then this list will look much saner - just "name or primitive".

Copy link
CollaboratorAuthor

Choose a reason for hiding this comment

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

Hm. I only decided to allow primitive literals as an optimization, but nothing will break if we store their types. Matching of primitive literals sounds like something no one should be doing (often). Let's remove them altogether!

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

def_make_named_statement_for_match(self,s:MatchStmt)->Expression:
"""Construct a fake NameExpr for inference if a match clause is complex."""
subject=s.subject
ifisinstance(subject, (NameExpr,AssignmentExpr)):
Copy link
Member

Choose a reason for hiding this comment

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

What I wanted is something like this:

ifisinstance(subject, (IndexExpr,MemberExpr,NameExpr)andliteral(subject):<useexistingexpression>else:<createfakename>

plus an explicit comment that this should be kept in sync with corresponding logic in binder. This way it will be easier to spot a bug if something changes in binder.

Copy link
CollaboratorAuthor

Choose a reason for hiding this comment

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

Hm, okay, you finally made me realize that the problem with walrus is not situated here - thanks! I think the new version should be closer.

@github-actions
Copy link
Contributor

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

@ilevkivskyiilevkivskyi merged commit555edf3 intopython:masterAug 3, 2025
20 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

Projects

None yet

Milestone

No milestone

3 participants

@sterliakov@ilevkivskyi@hauntsaninja

[8]ページ先頭

©2009-2025 Movatter.jp