Skip to content

[RFC] watch pyrefly settings #25041

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

kinto0
Copy link

@kinto0 kinto0 commented May 7, 2025

I tested my patch in pre-release this morning but it only works after a window-reload. It doesn't work in the following cases:

  • on pyrefly setting change
20250507-1509-58.9438483.mp4
  • on install of pyrefly (it flickers but starts up again when it should not)
20250507-1508-53.1954191.mp4

In the PR, I tested the config settings but not the watch behavior because I couldn't get Pylance working locally.

The first issue makes sense to me: I'm pretty sure I should've kept this (fixed in this PR).

The second issue does not: we refresh on settings changes assuming this.languageServer != the new one.

I'm still not able to test this locally: my windows machine is failing to compile right now. I will have access to a mac later today, but I will likely have the same issues testing it as last time. In the meantime, I've patched pyrefly to change python.languageServer then change it back on activation and changes to the disableLanguageServices setting (patch).

I'm looking for advice:

  • Is it too late to put this in the pre-release? (likely, but that is OK with me because of my patch)
  • Any idea why Pylance is not disabled on install of pyrefly?

@kinto0 kinto0 changed the title watch pyrefly settings [RFC] watch pyrefly settings May 7, 2025
@kinto0 kinto0 marked this pull request as ready for review May 7, 2025 16:07
@karthiknadig karthiknadig requested a review from rchiodo May 7, 2025 16:48
@kinto0 kinto0 requested a review from karthiknadig May 7, 2025 21:23
@kinto0
Copy link
Author

kinto0 commented May 7, 2025

@karthiknadig I still can't get pylance ever started locally to test. Would you be able to assist?

this is all I see in the output pane:

2025-05-07 17:40:16.535 [info] Experiment 'All' is active
2025-05-07 17:40:16.535 [info] Native locator: Refresh started
2025-05-07 17:40:16.535 [info] > pyenv which python
2025-05-07 17:40:16.535 [info] cwd: .
2025-05-07 17:40:16.609 [info] > conda info --json
2025-05-07 17:40:16.642 [info] > /opt/anaconda3/bin/conda info --json
2025-05-07 17:40:29.634 [info] Discover tests for workspace name: undefined - uri: /Users/kylei/Library/Application Support/Code/User/settings.json
2025-05-07 17:40:38.359 [info] Discover tests for workspace name: undefined - uri: /Users/kylei/Library/Application Support/Code/User/settings.json

Rich mentioned here that pylance needs to be installed in the extensions folder. I don't have pylance source so I can't get that one, but I do have the release pylance there (because it's installed normally). I also tried cloning this repo into the extensions folder but that made no difference.

Thanks!

@karthiknadig
Copy link
Member

@rchiodo can you help with this. I suspect we may need to re-load here.

@rchiodo
Copy link

rchiodo commented May 8, 2025

The output looks like it's not even trying to start pylance. Meaning that would be entirely in the Python extension.

@rchiodo
Copy link

rchiodo commented May 8, 2025

I'll try building this branch and see what I get.

@rchiodo
Copy link

rchiodo commented May 8, 2025

Yeah this works for me. I just followed the steps in the contributing wiki.

  • npm i
  • pip install nox
  • nox --session setup_repo
  • Open in VS code
  • Hit F5

I had pylance just installed like normal.

@rchiodo
Copy link

rchiodo commented May 8, 2025

When I set this it seems it's not starting Pylance though:

image

Or it's killing it as I get this in our log:

2025-05-07 17:22:52.442 [info] Starting inspector on 127.0.0.1:6600 failed: address already in use

2025-05-07 17:22:54.277 [info] [Info  - 5:22:54 PM] (18332) Server root directory: file:///c%3A/Users/rchiodo/.vscode/extensions/ms-python.vscode-pylance-2025.4.103/dist
2025-05-07 17:22:54.278 [info] [Info  - 5:22:54 PM] (18332) Pylance language server 2025.4.103 (pyright version 1.1.400, commit b962ffc2) starting
2025-05-07 17:22:54.281 [info] [Info  - 5:22:54 PM] (18332) Starting service instance "notebook_errors" for workspace "c:\Users\rchiodo\source\testing\notebook_errors"
2025-05-07 17:22:54.368 [info] [Info  - 5:22:54 PM] Server process exited successfully

@rchiodo
Copy link

rchiodo commented May 8, 2025

I did some debugging. The changing of this setting seems to set off a cascade of events:

image

First this fires:

        this.disposables.push(
            this.workspace.onDidChangeConfiguration((event: ConfigurationChangeEvent) => {
                if (event.affectsConfiguration('python')) {
                    this.onDidChanged(event);
                }
            }),
        );

Well because the pyrefly setting is prefixed with python.

That causes the internal 'update' method to get called.

That in turn changes the 'languageServer' setting to a new value, which then causes another update.

That then causes this to fire

    private async onDidChangeConfiguration(event: ConfigurationChangeEvent): Promise<void> {
        const workspacesUris = this.workspaceService.workspaceFolders?.map((workspace) => workspace.uri) ?? [];

        workspacesUris.forEach(async (resource) => {
            if (event.affectsConfiguration(`python.languageServer`, resource)) {
                await this.refreshLanguageServer(resource); <--- This here
            } else if (event.affectsConfiguration(`python.analysis.pylanceLspClientEnabled`, resource)) {
                await this.refreshLanguageServer(resource, /* forced */ true);
            } else if (event.affectsConfiguration(`python.pyrefly.disableLanguageServices`, resource)) {
                await this.refreshLanguageServer(resource);
            }
        });
    }

Then we get another update for the pyrefly setting changes which then causes this to fire:

    private async onDidChangeConfiguration(event: ConfigurationChangeEvent): Promise<void> {
        const workspacesUris = this.workspaceService.workspaceFolders?.map((workspace) => workspace.uri) ?? [];

        workspacesUris.forEach(async (resource) => {
            if (event.affectsConfiguration(`python.languageServer`, resource)) {
                await this.refreshLanguageServer(resource);
            } else if (event.affectsConfiguration(`python.analysis.pylanceLspClientEnabled`, resource)) {
                await this.refreshLanguageServer(resource, /* forced */ true);
            } else if (event.affectsConfiguration(`python.pyrefly.disableLanguageServices`, resource)) {
                await this.refreshLanguageServer(resource); <--- This here
            }
        });
    }

Which in effect doesn't turn off the language server. Well it actually depends upon what the setting was on startup. It either turns it on and then off again or turns it on twice.

I think the python extension needs to be changed to not double fire this event.

@kinto0
Copy link
Author

kinto0 commented May 8, 2025

I did some debugging. The changing of this setting seems to set off a cascade of events:

image

First this fires:

        this.disposables.push(
            this.workspace.onDidChangeConfiguration((event: ConfigurationChangeEvent) => {
                if (event.affectsConfiguration('python')) {
                    this.onDidChanged(event);
                }
            }),
        );

Well because the pyrefly setting is prefixed with python.

That causes the internal 'update' method to get called.

That in turn changes the 'languageServer' setting to a new value, which then causes another update.

That then causes this to fire

    private async onDidChangeConfiguration(event: ConfigurationChangeEvent): Promise<void> {
        const workspacesUris = this.workspaceService.workspaceFolders?.map((workspace) => workspace.uri) ?? [];

        workspacesUris.forEach(async (resource) => {
            if (event.affectsConfiguration(`python.languageServer`, resource)) {
                await this.refreshLanguageServer(resource); <--- This here
            } else if (event.affectsConfiguration(`python.analysis.pylanceLspClientEnabled`, resource)) {
                await this.refreshLanguageServer(resource, /* forced */ true);
            } else if (event.affectsConfiguration(`python.pyrefly.disableLanguageServices`, resource)) {
                await this.refreshLanguageServer(resource);
            }
        });
    }

Are you sure this second update "This here" isn't caused by my patch? To test these changed, I think we need to be on an older version of pyrefly. I Install specific version...ed 0.12.1 when testing this.

@rchiodo
Copy link

rchiodo commented May 16, 2025

Are you sure this second update "This here" isn't caused by my patch? To test these changed, I think we need to be on an older version of pyrefly. I Install specific version...ed 0.12.1 when testing this.

Yeah, that made things a lot easier to get working. I pushed an update which I think should fix the problem. At least for me locally, with using pyrefly 0.12.1, the setting works as designed.

@kinto0
Copy link
Author

kinto0 commented May 16, 2025

Are you sure this second update "This here" isn't caused by my patch? To test these changed, I think we need to be on an older version of pyrefly. I Install specific version...ed 0.12.1 when testing this.

Yeah, that made things a lot easier to get working. I pushed an update which I think should fix the problem. At least for me locally, with using pyrefly 0.12.1, the setting works as designed.

Awesome! Thanks for the fix. I can test in the morning. Did this fix the issue for both settings updates and on Pyrefly install?

No rush in getting this in until the next release. I'll just remove my pyrefly patch once these go into this extension (everything works fine right now with the hack).

@rchiodo
Copy link

rchiodo commented May 16, 2025

Sorry I didn't realize there was a problem on install. That would likely have to be handled with something waiting for install of pyrefly.

Yeah install requires a restart of the extension host for the logic to work.

@rchiodo
Copy link

rchiodo commented May 16, 2025

@karthiknadig do you know how the Python extension indicates 'restart' required on install? Maybe pyrefly can just set that same setting

@karthiknadig
Copy link
Member

karthiknadig commented May 16, 2025

@rchiodo I think this has to be handled in the on change handler. Some time ago we used to request reload of the extension on language server change by popping up a notification, and later triggering the reload window command. I think we removed it after we made it so you did not need to reload.

@rchiodo
Copy link

rchiodo commented May 16, 2025

Yeah I looked at the VS code source. Restart Extensions isn't controlled by the extension at all. VS code decides based on if the extension is already running etc. So we'd have to listen to this event: https://github.com/microsoft/vscode/blob/2d6afddc470bf44f7e60fb5b6e6fdd08e771409b/src/vscode-dts/vscode.d.ts#L17320-L17321

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants