Skip to content

Feat/import autocomplete#3084

Open
NarxPal wants to merge 7 commits intofacebook:mainfrom
NarxPal:feat/import-autocomplete
Open

Feat/import autocomplete#3084
NarxPal wants to merge 7 commits intofacebook:mainfrom
NarxPal:feat/import-autocomplete

Conversation

@NarxPal
Copy link
Copy Markdown

@NarxPal NarxPal commented Apr 9, 2026

Summary

earlier exported symbols were appearing only when we had importedName for the module.
for eg.
from math import sq

here , sq is the importedName

since it has chars for importedName the completion suggestion will show symbols for it, but in case when

from math import

there is no importedName the completion suggestion won't work since from_stmt_import_from_name fn in pyrefly/lib/state/lsp.rs require importedName.

so I added importedNameEmpty to match the condition for from math import | and trigger completion when there's no name. after that i made sure that ThisModule entries appear first, so i marked them Local in completion source. and did Reexport for OtherModule entries.

up until now i was able to trigger completion and symbols are appearing as expected but pyrefly/test are failing due to difference in ordering in the suggestions, so i would like to discuss should we change the ordering inside tests or is there other way out?

one test error eg.

2 | from foo import func
  |                 ^^^^
  |

thread 'test::lsp::completion::from_import_deprecated' (22054) panicked at pyrefly/lib/test/lsp/completion.rs:769:5:
assertion failed: `(left == right)`

Diff < left / right > :
 # main.py
 2 | from foo import func
                ^
 Completion Results:
 
 2 | from foo import func
                         ^
 Completion Results:
<- (Variable) deprecated
 - (Function) func_ok
>- (Variable) deprecated

Fixes #2999

Test Plan

  • Manually verified in VS Code using a local Pyrefly build from this branch.
  • Opened a Python file with from math import | and triggered completion.
  • Confirmed symbol-like math exports are shown (for example sqrt, sin, cos) and unrelated helper suggestions are shown at bottom.
  • Also verified from math import s| still returns expected symbol completions.

@meta-cla
Copy link
Copy Markdown

meta-cla bot commented Apr 9, 2026

Hi @NarxPal!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks!

@github-actions github-actions bot added the size/l label Apr 9, 2026
@meta-cla meta-cla bot added the cla signed label Apr 9, 2026
@meta-cla
Copy link
Copy Markdown

meta-cla bot commented Apr 9, 2026

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

@github-actions github-actions bot added size/l and removed size/l labels Apr 10, 2026
@NarxPal NarxPal marked this pull request as ready for review April 10, 2026 18:55
@NarxPal NarxPal marked this pull request as draft April 10, 2026 18:58
@NarxPal NarxPal marked this pull request as ready for review April 10, 2026 19:48
@NarxPal
Copy link
Copy Markdown
Author

NarxPal commented Apr 10, 2026

so i was facing two tests fail before which have now been resolved, below is the complete detail regarding the error in test and how i resolved them:

each two test failure were seen in -
pyrefly / test (macOS-latest)
pyrefly / test (ubuntu-latest)
pyrefly / test (windows-latest)

1. test failure for from_import_empty_test

test failure code:
---- test::lsp::completion::from_import_empty_test stdout ----
DEBUG Running with 3 threads (10 MiB stack size)
DEBUG Running epoch 1 of run 0
DEBUG Committing transaction
ERROR Parse error: Expected one or more symbol names after import [parse-error]
 --> main.py:2:16
  |
2 | from foo import
  |                ^
3 | #              ^
  |

thread 'test::lsp::completion::from_import_empty_test' (22058) panicked at pyrefly/lib/test/lsp/completion.rs:735:5:
assertion failed: `(left == right)`

Diff < left / right > :
 # main.py
 2 | from foo import
                    ^
 Completion Results:
>- (Variable) imperial_guard
>- (Constant) __annotations__
>- (Constant) __builtins__
>- (Constant) __cached__
>- (Constant) __debug__
>- (Constant) __dict__
>- (Constant) __doc__
>- (Constant) __file__
>- (Constant) __loader__
>- (Constant) __name__
>- (Constant) __package__
>- (Constant) __path__
>- (Constant) __spec__
 

At the marked cursor (^) in from foo import| completion request was being sent which made completion suggestion appear in Completion Results while our test file pyrefly/lib/test/lsp/completion.rs expects no Completion Results which can be seen in following code:

fn from_import_empty_test() {
    let foo_code = r#"
imperial_guard = "cool"
"#;
    let main_code = r#"
from foo import
#              ^
"#;
    let report = get_batched_lsp_operations_report_allow_error(
        &[("main", main_code), ("foo", foo_code)],
        get_default_test_report(),
    );
    assert_eq!(
        r#"
# main.py
2 | from foo import
                   ^
Completion Results:


# foo.py
"#

Solution:

in empty_imported_name_from_covering_nodes fn

      if pos <= slot_start || pos > line_end {
           return None;
       }

this avoided unnecessary completion request being sent during from foo import|

2. test failure for from_import_deprecated

test failure code
---- test::lsp::completion::from_import_deprecated stdout ----
DEBUG Running with 3 threads (10 MiB stack size)
DEBUG Running epoch 1 of run 0
DEBUG Committing transaction
ERROR Could not import `func` from `foo` [missing-module-attribute]
 --> main.py:2:17
  |
2 | from foo import func
  |                 ^^^^
  |

thread 'test::lsp::completion::from_import_deprecated' (22054) panicked at pyrefly/lib/test/lsp/completion.rs:769:5:
assertion failed: `(left == right)`

Diff < left / right > :
 # main.py
 2 | from foo import func
                ^
 Completion Results:
 
 2 | from foo import func
                         ^
 Completion Results:
<- (Variable) deprecated
 - (Function) func_ok
>- (Variable) deprecated
 - (Constant) __annotations__
 - (Constant) __builtins__
 - (Constant) __cached__
 - (Constant) __debug__
 - (Constant) __dict__
 - (Constant) __doc__
 - (Constant) __file__
 - (Constant) __loader__
 - (Constant) __name__
 - (Constant) __package__
 - (Constant) __path__
 - (Constant) __spec__
 - (Function) [DEPRECATED] func_not_ok
 
 
 # foo.py

Here, Completion Results required (Variable) deprecated to be positioned below (Function) func_ok but due to my changes in file - pyrefly/lib/lsp/wasm/completion.rs :

                    let exports = self.get_exports(&handle);
                    for (name, export) in exports.iter() {
                        let (is_deprecated, kind, source) = match export {
                            ExportLocation::ThisModule(export) => (
                                export.deprecation.is_some(),
                                export
                                    .symbol_kind
                                    .map_or(CompletionItemKind::VARIABLE, |k| {
                                        k.to_lsp_completion_item_kind()
                                    }),
                                CompletionSource::Local,
                            ),
                            ExportLocation::OtherModule(_, _) => {
                                (false, CompletionItemKind::VARIABLE, CompletionSource::Local)  //  <----- Failure: mismatch occured when `CompletionSource::Reexport` was used here previously
                            }
                        };

when i used CompletionSource::Reexport in ExportLocation::OtherModule , those items got a lower rank bucket than Local, so deprecated moved below direct module symbols like func_ok. this caused ordering mismatch with the test file. so i changed it to CompletionSource::Local to prefer test file ordering.

Test Plan

  • CARGO_TARGET_DIR=/work/pyrefly-target cargo test from_import_empty_test

    • Passed
  • CARGO_TARGET_DIR=/work/pyrefly-target cargo test from_import_deprecated

    • Passed
  • CARGO_TARGET_DIR=/work/pyrefly-target python3 test.py --no-test --no-conformance --no-jsonschema

    • Passed

Notes

  • Used CARGO_TARGET_DIR=/work/pyrefly-target to avoid build-path issues from spaces in the workspace path.

Manual Verification (VS Code)

  • Verified in VS Code using a local Pyrefly binary built from this branch.
  • Opened a Python file with from math import | and triggered completion.
  • Confirmed math symbol completions are shown (for example: sqrt, sin, cos).
  • Also verified from math import s| still returns expected symbol completions.
Screenshot from 2026-04-11 00-01-48 Screenshot from 2026-04-11 02-26-01

@github-actions github-actions bot added size/l and removed size/l labels Apr 10, 2026
@github-actions github-actions bot added size/l and removed size/l labels Apr 10, 2026
@NarxPal
Copy link
Copy Markdown
Author

NarxPal commented Apr 10, 2026

test failures are resolved and from..import autocomplete implementation now works as expected , pr is ready to merge!

cc @stroxler

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reddit - Python: Module Import autocomplete suggestions in nvim

1 participant