Conversation
There was a problem hiding this comment.
Pull request overview
This pull request implements call-site type inference for the code generation quick-fix feature. When generating function or class stubs for undefined names, the system now analyzes how the undefined name is being called and infers appropriate parameter signatures with type annotations.
Changes:
- Enhanced the generate code actions to infer parameter names and types from call sites
- Added support for inferring type annotations for function/class parameters based on argument types
- Updated test expectations to reflect the new inferred signatures (e.g.,
TypeVar(arg1: str)instead ofTypeVar())
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| pyrefly/lib/state/lsp/quick_fixes/generate_code.rs | Core implementation: added functions to infer parameters from call sites, convert types to annotations, and generate properly typed function/class signatures |
| pyrefly/lib/state/lsp.rs | Updated function call to pass transaction and handle parameters needed for type inference |
| pyrefly/lib/test/lsp/code_actions.rs | Updated test expectations and added new test case demonstrating call-site inference with typed parameters |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| for arg in &call.arguments.args { | ||
| let (prefix, expr) = match arg { | ||
| Expr::Starred(starred) => ("*", starred.value.as_ref()), | ||
| _ => ("", arg), | ||
| }; | ||
| let base_name = param_name_from_expr(expr).unwrap_or_else(|| { | ||
| let name = format!("arg{counter}"); | ||
| counter += 1; | ||
| name | ||
| }); | ||
| let name = unique_name(base_name, &mut used_names); | ||
| let annotation = infer_annotation(transaction, handle, expr.range()) | ||
| .and_then(|ty| type_to_annotation(ty, stdlib)); | ||
| params.push(InferredParam { | ||
| prefix, | ||
| name, | ||
| annotation, | ||
| }); | ||
| } |
There was a problem hiding this comment.
The handling of starred arguments may produce incorrect parameter signatures in some cases. When inferring from a call like func(*items) where items is a list or tuple with a known length, the code will generate def func(*items) which accepts any number of arguments. However, if items has a known fixed length (e.g., a tuple of 3 elements), it might be more accurate to generate separate positional parameters instead. Consider checking if the starred argument has a known fixed-length tuple type and expanding it to individual parameters in such cases.
|
According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅ |
Summary
Fixes #2357
Added call-site inference for generated function/class signatures (including
__init__) and optional variable annotations.Test Plan
Updated expectations for TypeVar('T') and added a new call-site inference test.