Skip to content
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

Explore use of internal WeakUnion implementation for ambiguous overload resolution #4347

Closed
erictraut opened this issue Dec 17, 2022 · 3 comments
Labels
addressed in next version Issue is fixed and will appear in next published version enhancement request New feature or request

Comments

@erictraut
Copy link
Collaborator

erictraut commented Dec 17, 2022

The overload resolution behavior in mypy and pyright differ somewhat, and this causes problems for some library and stub authors. The difference occurs in situations where one or more arguments evaluates to Any, and the overload match becomes ambiguous due to this lack of type information. Pyright intentionally chooses the first overload match in this situation, whereas mypy evaluates the type of the call expression as Any in this situation. Both behaviors are well justified. In pyright's case, an Any result is far from ideal because pyright is used as the basis for a language server (pylance), and completion suggestions cannot be provided for an Any type.

There has been discussion in the typing forums of supporting a WeakUnion type. It would be equivalent to a Union except that it would be compatible with another type if one or more of its subtypes was compatible. That means WeakUnion would be non-type-safe, but it would be more type safe than Any.

There was insufficient consensus among the typing community to officially support WeakUnion in the typing standard, but pyright could implement something like this internally. Externally, it could act like Any (or Unknown, which is pyright's nomencalture for an implied Any). This would make it compatible with mypy, and yet it would allow pylance to present meaningful completion suggestions.

This change will have an inevitable performance impact because pyright will need to evaluate all overloads rather than stopping after the first one that matches. This performance impact can be significant if there are many overloads. We'll need to determine whether this performance impact is acceptable.

@erictraut erictraut added the enhancement request New feature or request label Dec 17, 2022
erictraut pushed a commit that referenced this issue Dec 17, 2022
…y when the overload match is ambiguous because an argument evaluates to `Any` or `Unknown`. In this case, the call expression evaluates to `Unknown`. Previously, pyright used the first of the matching overloads in this case. This addresses #4347.
@erictraut
Copy link
Collaborator Author

I found a way to mirror mypy's behavior while preserving the language server completion suggestions. There is a performance impact, but it's limited to cases when one or more arguments evaluate to Any or Unknown.

This change will be included in the next release.

@erictraut erictraut added the addressed in next version Issue is fixed and will appear in next published version label Dec 17, 2022
@matangover
Copy link

matangover commented Dec 17, 2022

It's an elegant solution. Thank you!

@erictraut
Copy link
Collaborator Author

This is addressed in pyright 1.1.285, which I just published. It will also be included in a future release of pylance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
addressed in next version Issue is fixed and will appear in next published version enhancement request New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants