Repository navigation
impl Autocomplete Abstract, Protocol and method override #1589 - #5444
asukaminato0721 wants to merge 10 commits into
Conversation
|
This pull request has been imported. If you are a Meta employee, you can view this in D128243979. (Because this pull request was imported automatically, there will not be any future comments.) |
This comment has been minimized.
This comment has been minimized.
Generated annotations must use Python syntax and omit a bound receiver.
Keep diagnostic text out of generated Python annotations while preserving semantic references for imports.
Preserve parameter kinds, type parameters, and source-safe defaults when generating method signatures.
Retain overloads, async declarations, property setters, and class-variable annotations in generated members.
Keep class headers, docstrings, existing decorators, and indentation intact when inserting member implementations.
Collect inherited abstract members and generate local edits for the selected class. Cover method and property stubs.
Check protocol methods and class variables without turning data members into methods.
Use structured annotation references to preserve aliases and avoid collisions. Check imported callable contracts and base specialization.
Cover inline classes, missing final newlines, nested indentation, and existing decorators.
Register the action with quick fixes so LSP kind filters and automatic requests return the expected actions.
00fb613 to
74248a6
Compare
|
According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅ |
stroxler
left a comment
There was a problem hiding this comment.
Thanks! This is looking better, but it's a complicated feature and a fresh round of review caught quite a few new edge cases where the behavior doesn't seem quite right:
-
Generic stubs insert unsupported syntax on older Python targets.
A legacyTypeVarmethod becomesdef identity[T](...), which fails to parse on Python 3.11. The renderer needs a target-version guard; declining unsupported generation is an acceptable minimal fix.
[Location: signature renderer]()pyrefly/pyrefly/lib/state/lsp/quick_fixes/implement_abstract_members.rs
Lines 483 to 513 in 74248a6
-
Returned generic callables lose their type-variable binder.
def factory[T](self) -> Callable[[T], T]becomesdef factory(self) -> Callable[[T], T]. Applying the action introduces twoUnknownNameerrors forT. Preserve the quantification or decline annotations that cannot be represented safely.
[Location: callable annotation rendering]()pyrefly/crates/pyrefly_types/src/display.rs
Lines 932 to 977 in 74248a6
-
Abstract async generators become coroutines.
The generatedasync defcontains onlyraise NotImplementedError, so it loses generator-ness. Pyrefly reports an incompatible override; executingasync forproduces aTypeErrorinstead of reaching the stub. Preserve the function kind or generate a compatible synchronous stub.
[Location: declaration and body generation]()pyrefly/pyrefly/lib/state/lsp/quick_fixes/implement_abstract_members.rs
Lines 411 to 419 in 74248a6
-
Async properties acquire a second coroutine wrapper.
An abstractasync def value(self) -> intproperty becomesasync def value(self) -> Coroutine[Any, Any, int], producing aBadOverride. Normalization changes the top-level signature, but rendering uses the separate getter stored in property metadata. Normalize the signature actually rendered.
Normalization · [Getter selection]()pyrefly/pyrefly/lib/state/lsp/quick_fixes/implement_abstract_members.rs
Lines 372 to 383 in 74248a6
-
The module-import fallback can resolve annotations through a rebound name.
With a localPayloadcollision andbase = 42, the action insertsimport baseat the top but generatesbase.Payloadafter the rebinding. This introduces missing-attribute errors and breaks annotation evaluation. Use a collision-free module alias.
[Location: import planning]()pyrefly/pyrefly/lib/state/lsp/quick_fixes/implement_abstract_members.rs
Lines 133 to 163 in 74248a6
stroxler
left a comment
There was a problem hiding this comment.
Review automatically exported from Phabricator review in Meta.
Summary: Fix-forward for D128243979 (#5444). These tests capture the current behavior of cases that the "Implement abstract members" quick fix and insertable inlay hints get wrong. Each `BUG` comment describes the problem; later diffs in this stack fix them and update the expectations: - A `ParamSpec` signature removes the whole action. - Legacy `TypeVar`s produce PEP 695 syntax, which fails before Python 3.12. - Async generators become coroutines. - Type parameters that only appear in a returned callable lose their declaration. - The `import <module>` fallback is used even when the module name is rebound in the file. - The action is offered anywhere in a class body, and in protocol classes. - Annotations for overloaded functions, generic functions, and functions with default arguments are wrong: they keep only the first overload, leave type parameters undefined, or make optional parameters required. - The generated layout has uneven blank lines, and setters repeat the getter's docstring. - Pushing a member down into a class whose `pass` shares a line with a docstring removes the docstring. ___ landed-with-radar-review Differential Revision: D128955269 fbshipit-source-id: b2f2e62cde3ac4b6e99bac4130054f420229957d
|
This pull request has been merged in d7b6429. |
Summary
Fixes part of #1589 #2207
microsoft/pylance-release#146
Implemented an “Implement abstract members” quick fix that derives missing abstract members via the solver, copies signatures/decorators/docstrings, and inserts stubs into the selected class, then wired it into LSP code actions.
Test Plan
add test