Skip to content

Commit 15bc26c

Browse files
kinto0facebook-github-bot
authored andcommitted
integration test incorrect interpreter behavior (#1737)
Summary: interpreter fails to update type errors when changing from a bad one to a good one reported here #1632 Differential Revision: D87664939
1 parent 501486e commit 15bc26c

File tree

3 files changed

+113
-0
lines changed

3 files changed

+113
-0
lines changed

pyrefly/lib/test/lsp/lsp_interaction/configuration.rs

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,97 @@ fn test_workspace_pythonpath_ignored_when_set_in_config_file() {
278278
interaction.shutdown().expect("Failed to shutdown");
279279
}
280280

281+
// Only run this test on unix since windows has no way to mock a .exe without compiling something
282+
// (we call python with python.exe)
283+
#[cfg(unix)]
284+
#[test]
285+
fn test_interpreter_change_removes_type_errors() {
286+
let test_files_root = get_test_files_root();
287+
let good_interpreter_path =
288+
setup_dummy_interpreter(&test_files_root.path().join("custom_interpreter"));
289+
let bad_interpreter_path = setup_dummy_interpreter(
290+
&test_files_root
291+
.path()
292+
.join("interpreter_with_no_site_packages"),
293+
);
294+
295+
let mut interaction = LspInteraction::new();
296+
interaction.set_root(test_files_root.path().to_path_buf());
297+
interaction
298+
.initialize(InitializeSettings {
299+
configuration: Some(Some(
300+
json!([{"pyrefly": {"displayTypeErrors": "force-on"}}]),
301+
)),
302+
..Default::default()
303+
})
304+
.unwrap();
305+
306+
interaction.client.did_open("custom_interpreter/src/foo.py");
307+
// Without any interpreter configured, there should be 1 import error
308+
interaction
309+
.client
310+
.expect_publish_diagnostics_error_count(
311+
test_files_root.path().join("custom_interpreter/src/foo.py"),
312+
1,
313+
)
314+
.unwrap();
315+
// Configure broken interpreter with empty site-packages - should still have 1 import error
316+
interaction.client.did_change_configuration();
317+
interaction
318+
.client
319+
.expect_request::<WorkspaceConfiguration>(json!({"items":[{"section":"python"}]}))
320+
.unwrap()
321+
.send_configuration_response(json!([
322+
{
323+
"pythonPath": bad_interpreter_path.to_str().unwrap()
324+
}
325+
]));
326+
interaction
327+
.client
328+
.expect_publish_diagnostics_error_count(
329+
test_files_root.path().join("custom_interpreter/src/foo.py"),
330+
1,
331+
)
332+
.unwrap();
333+
334+
// Switch to good interpreter with site-packages
335+
interaction.client.did_change_configuration();
336+
interaction
337+
.client
338+
.expect_request::<WorkspaceConfiguration>(json!({"items":[{"section":"python"}]}))
339+
.unwrap()
340+
.send_configuration_response(json!([
341+
{
342+
"pythonPath": good_interpreter_path.to_str().unwrap()
343+
}
344+
]));
345+
346+
// BUG: Expecting 1 error demonstrates incorrect behavior.
347+
// After switching to good interpreter, the error should be resolved to 0.
348+
interaction
349+
.client
350+
.expect_publish_diagnostics_error_count(
351+
test_files_root.path().join("custom_interpreter/src/foo.py"),
352+
1,
353+
)
354+
.unwrap();
355+
356+
// BUG: it works after a did_close -> did_open
357+
interaction
358+
.client
359+
.did_close("custom_interpreter/src/foo.py");
360+
interaction.client.did_open("custom_interpreter/src/foo.py");
361+
interaction
362+
.client
363+
.expect_publish_diagnostics_error_count(
364+
test_files_root.path().join("custom_interpreter/src/foo.py"),
365+
0,
366+
)
367+
.unwrap();
368+
369+
interaction.shutdown().unwrap();
370+
}
371+
281372
#[test]
282373
fn test_disable_language_services() {
283374
let test_files_root = get_test_files_root();

pyrefly/lib/test/lsp/lsp_interaction/object_model.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ use lsp_types::notification::DidChangeNotebookDocument;
3737
use lsp_types::notification::DidChangeTextDocument;
3838
use lsp_types::notification::DidChangeWatchedFiles;
3939
use lsp_types::notification::DidCloseNotebookDocument;
40+
use lsp_types::notification::DidCloseTextDocument;
4041
use lsp_types::notification::DidOpenNotebookDocument;
4142
use lsp_types::notification::DidOpenTextDocument;
4243
use lsp_types::notification::Exit;
@@ -451,6 +452,18 @@ impl TestClient {
451452
}))
452453
}
453454

455+
pub fn did_close(&self, file: &'static str) {
456+
let path = self.get_root_or_panic().join(file);
457+
self.send_notification::<DidCloseTextDocument>(json!({
458+
"textDocument": {
459+
"uri": Url::from_file_path(&path).unwrap().to_string(),
460+
"languageId": "python",
461+
"version": 1,
462+
"text": read_to_string(&path).unwrap(),
463+
},
464+
}));
465+
}
466+
454467
pub fn did_open(&self, file: &'static str) {
455468
let path = self.get_root_or_panic().join(file);
456469
self.send_notification::<DidOpenTextDocument>(json!({
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/bin/bash
2+
if [[ "$1" == "-c" && "$2" == *"import json, sys"* ]]; then
3+
cat << 'EOF'
4+
{"python_platform": "linux", "python_version": "3.12.0", "site_package_path": []}
5+
EOF
6+
else
7+
echo "Mock python interpreter - args:" "$@" >&2
8+
exit 1
9+
fi

0 commit comments

Comments
 (0)