Sublime Forum

Recognising conda environments in lsp-pyright with latest lsp v2

#1

I’ve upgraded LSP to the latest version (v2, which now uses python 3.8) and the corresponding pyright package too.

I’ve noticed that my usual method of getting lsp to recognise conda environments has stopped working. Specifically, using a pyrightconfig.json file with contents like the following:

{
	"venvPath": "/Users/username/miniconda3/envs",
	"venv": "general",
}

It used to work well in the past. Now lsp-pyright is defaulting back to the system python.

Inspecting the lsp log panel I can see that venvPath is registering but for some reason I can’t discern from the logs it is default to the system python instead.

Is there some new approach I need to employ?

I’ve set the venvPath in the pyright settings, but that doesn’t improve anything (I can tell from the logs that both venvPaths are detected).

Setting pythonPath to the desired binary in the project settings works just fine (and, AFAICT, LSP is working fine too). But it is a more cumbersome way to go so I was hoping to see if I could still use venvPath and venv.

Any insights? Is this a general path issue? I would have thought not as that’s what venvPath is for.

0 Likes

#2

LSP/LSP-pyright has nothing to do with pyrightconfig.json. The file is directly read by pyright, the server. But there is no recent pyright issue found on Github related to venvPath.


Update: In my local test, it works fine.

0 Likes

#3

What did you see about venvPath in the log? (the whole line/section in the raw log)

0 Likes

#4

Thanks for the help!!

Here’s the top of the log after a re-configuration by removing the pythonPath settings:

:: [21:22:42.795] --> LSP-pyright initialize (1): {'processId': 2050, 'clientInfo': {'name': 'Sublime Text LSP', 'version': '2.0.0'}, 'rootUri': 'file:///Users/username/Developer/zekell/zekell_sqlite', 'rootPath': '/Users/username/Developer/zekell/zekell_sqlite', 'workspaceFolders': [{'name': 'zekell_sqlite', 'uri': 'file:///Users/username/Developer/zekell/zekell_sqlite'}], 'capabilities': {'general': {'regularExpressions': {'engine': 'ECMAScript'}, 'markdown': {'parser': 'Python-Markdown', 'version': '3.2.2'}}, 'textDocument': {'synchronization': {'dynamicRegistration': True, 'didSave': True, 'willSave': True, 'willSaveWaitUntil': True}, 'hover': {'dynamicRegistration': True, 'contentFormat': ['markdown', 'plaintext']}, 'completion': {'dynamicRegistration': True, 'completionItem': {'snippetSupport': True, 'deprecatedSupport': True, 'documentationFormat': ['markdown', 'plaintext'], 'tagSupport': {'valueSet': [1]}, 'resolveSupport': {'properties': ['detail', 'documentation', 'additionalTextEdits']}, 'insertReplaceSupport': True, 'insertTextModeSupport': {'valueSet': [2]}, 'labelDetailsSupport': True}, 'completionItemKind': {'valueSet': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]}, 'insertTextMode': 2, 'completionList': {'itemDefaults': ['editRange', 'insertTextFormat', 'data']}}, 'signatureHelp': {'dynamicRegistration': True, 'contextSupport': True, 'signatureInformation': {'activeParameterSupport': True, 'documentationFormat': ['markdown', 'plaintext'], 'parameterInformation': {'labelOffsetSupport': True}}}, 'references': {'dynamicRegistration': True}, 'documentHighlight': {'dynamicRegistration': True}, 'documentSymbol': {'dynamicRegistration': True, 'hierarchicalDocumentSymbolSupport': True, 'symbolKind': {'valueSet': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]}, 'tagSupport': {'valueSet': [1]}}, 'documentLink': {'dynamicRegistration': True, 'tooltipSupport': True}, 'formatting': {'dynamicRegistration': True}, 'rangeFormatting': {'dynamicRegistration': True, 'rangesSupport': True}, 'declaration': {'dynamicRegistration': True, 'linkSupport': True}, 'definition': {'dynamicRegistration': True, 'linkSupport': True}, 'typeDefinition': {'dynamicRegistration': True, 'linkSupport': True}, 'implementation': {'dynamicRegistration': True, 'linkSupport': True}, 'codeAction': {'dynamicRegistration': True, 'codeActionLiteralSupport': {'codeActionKind': {'valueSet': ['quickfix', 'refactor', 'refactor.extract', 'refactor.inline', 'refactor.rewrite', 'source.fixAll', 'source.organizeImports']}}, 'dataSupport': True, 'isPreferredSupport': True, 'resolveSupport': {'properties': ['edit']}}, 'rename': {'dynamicRegistration': True, 'prepareSupport': True, 'prepareSupportDefaultBehavior': 1}, 'colorProvider': {'dynamicRegistration': True}, 'publishDiagnostics': {'relatedInformation': True, 'tagSupport': {'valueSet': [1, 2]}, 'versionSupport': True, 'codeDescriptionSupport': True, 'dataSupport': True}, 'diagnostic': {'dynamicRegistration': True, 'relatedDocumentSupport': True}, 'selectionRange': {'dynamicRegistration': True}, 'foldingRange': {'dynamicRegistration': True, 'foldingRangeKind': {'valueSet': ['comment', 'imports', 'region']}}, 'codeLens': {'dynamicRegistration': True}, 'inlayHint': {'dynamicRegistration': True, 'resolveSupport': {'properties': ['textEdits', 'label.command']}}, 'semanticTokens': {'dynamicRegistration': True, 'requests': {'range': True, 'full': {'delta': True}}, 'tokenTypes': ['namespace', 'type', 'class', 'enum', 'interface', 'struct', 'typeParameter', 'parameter', 'variable', 'property', 'enumMember', 'event', 'function', 'method', 'macro', 'keyword', 'modifier', 'comment', 'string', 'number', 'regexp', 'operator', 'decorator'], 'tokenModifiers': ['declaration', 'definition', 'readonly', 'static', 'deprecated', 'abstract', 'async', 'modification', 'documentation', 'defaultLibrary'], 'formats': ['relative'], 'overlappingTokenSupport': False, 'multilineTokenSupport': True, 'augmentsSyntaxTokens': True}, 'callHierarchy': {'dynamicRegistration': True}, 'typeHierarchy': {'dynamicRegistration': True}}, 'workspace': {'applyEdit': True, 'didChangeConfiguration': {'dynamicRegistration': True}, 'executeCommand': {}, 'workspaceEdit': {'documentChanges': True, 'failureHandling': 'abort'}, 'workspaceFolders': True, 'symbol': {'dynamicRegistration': True, 'resolveSupport': {'properties': ['location.range']}, 'symbolKind': {'valueSet': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]}, 'tagSupport': {'valueSet': [1]}}, 'configuration': True, 'codeLens': {'refreshSupport': True}, 'inlayHint': {'refreshSupport': True}, 'semanticTokens': {'refreshSupport': True}, 'diagnostics': {'refreshSupport': True}, 'didChangeWatchedFiles': {'dynamicRegistration': True}}, 'window': {'showDocument': {'support': True}, 'showMessage': {'messageActionItem': {'additionalPropertiesSupport': True}}, 'workDoneProgress': True}}, 'initializationOptions': {}}
:: [21:22:42.800] <<< LSP-json (24) (duration: 102ms): None
:: [21:22:42.800]  -> LSP-json exit: None
:: [21:22:42.800] <<< LSP-pyright (3) (duration: 74ms): None
:: [21:22:42.801]  -> LSP-pyright exit: None
:: [21:22:43.063] <-  LSP-pyright window/logMessage: {'type': 3, 'message': 'Pyright language server 1.1.359 starting'}
:: [21:22:43.063] <-  LSP-pyright window/logMessage: {'type': 3, 'message': 'Server root directory: file:///Users/username/Library/Caches/Sublime%20Text/Package%20Storage/LSP-pyright/20.12.2/language-server/node_modules/pyright/dist'}
:: [21:22:43.071] <-  LSP-pyright window/logMessage: {'type': 3, 'message': 'Starting service instance "zekell_sqlite"'}
:: [21:22:43.071] <<< LSP-pyright (1) (duration: 276ms): {'capabilities': {'definitionProvider': {'workDoneProgress': True}, 'declarationProvider': {'workDoneProgress': True}, 'typeDefinitionProvider': {'workDoneProgress': True}, 'referencesProvider': {'workDoneProgress': True}, 'documentSymbolProvider': {'workDoneProgress': True}, 'workspaceSymbolProvider': {'workDoneProgress': True}, 'hoverProvider': {'workDoneProgress': True}, 'documentHighlightProvider': {'workDoneProgress': True}, 'renameProvider': {'prepareProvider': True, 'workDoneProgress': True}, 'completionProvider': {'triggerCharacters': ['.', '[', '"', "'"], 'resolveProvider': True, 'workDoneProgress': True, 'completionItem': {'labelDetailsSupport': True}}, 'signatureHelpProvider': {'triggerCharacters': ['(', ',', ')'], 'workDoneProgress': True}, 'codeActionProvider': {'codeActionKinds': ['quickfix', 'source.organizeImports'], 'workDoneProgress': True}, 'executeCommandProvider': {'commands': [], 'workDoneProgress': True}, 'callHierarchyProvider': True, 'workspace': {'workspaceFolders': {'supported': True, 'changeNotifications': True}}, 'textDocumentSync': {'didOpen': {}, 'save': {}, 'didClose': {}, 'change': {'syncKind': 2}}}}
:: [21:22:43.072]  -> LSP-pyright initialized: {}
:: [21:22:43.073]  -> LSP-pyright workspace/didChangeConfiguration: {'settings': {'pyright': {'dev_environment': 'sublime_text_38', 'disableLanguageServices': False, 'disableOrganizeImports': False}, 'python': {'analysis': {'autoImportCompletions': True, 'autoSearchPaths': True, 'diagnosticMode': 'openFilesOnly', 'diagnosticSeverityOverrides': {'reportDuplicateImport': 'warning', 'reportImplicitStringConcatenation': 'warning', 'reportUnboundVariable': 'warning', 'reportUnusedClass': 'information', 'reportUnusedFunction': 'information', 'reportUnusedImport': 'information', 'reportUnusedVariable': 'information'}, 'extraPaths': ['/Applications/Sublime Text 4.app/Contents/MacOS/Lib/python38', '/Applications/Sublime Text 4.app/Contents/MacOS/Lib/python3', '/Users/username/Library/Application Support/Sublime Text/Lib/python38', '/Applications/Sublime Text 4.app/Contents/MacOS/Packages', '/Users/username/Library/Application Support/Sublime Text/Packages'], 'logLevel': 'Information', 'stubPath': './typings', 'typeCheckingMode': 'standard', 'typeshedPaths': [], 'useLibraryCodeForTypes': True}, 'pythonPath': '/usr/bin/python', 'venvPath': '/Users/username/miniconda3/envs/'}}}

The main section seems to be the last line, where venvPath has registered by pythonPath, which is left empty in all config, has defaulted to /usr/bin/python.

:: [21:22:43.073]  -> LSP-pyright workspace/didChangeConfiguration: {'settings': {'pyright': {'dev_environment': 'sublime_text_38', 'disableLanguageServices': False, 'disableOrganizeImports': False}, 'python': {'analysis': {'autoImportCompletions': True, 'autoSearchPaths': True, 'diagnosticMode': 'openFilesOnly', 'diagnosticSeverityOverrides': {'reportDuplicateImport': 'warning', 'reportImplicitStringConcatenation': 'warning', 'reportUnboundVariable': 'warning', 'reportUnusedClass': 'information', 'reportUnusedFunction': 'information', 'reportUnusedImport': 'information', 'reportUnusedVariable': 'information'}, 'extraPaths': ['/Applications/Sublime Text 4.app/Contents/MacOS/Lib/python38', '/Applications/Sublime Text 4.app/Contents/MacOS/Lib/python3', '/Users/username/Library/Application Support/Sublime Text/Lib/python38', '/Applications/Sublime Text 4.app/Contents/MacOS/Packages', '/Users/username/Library/Application Support/Sublime Text/Packages'], 'logLevel': 'Information', 'stubPath': './typings', 'typeCheckingMode': 'standard', 'typeshedPaths': [], 'useLibraryCodeForTypes': True}, 'pythonPath': '/usr/bin/python', 'venvPath': '/Users/username/miniconda3/envs/'}}}

In this case, there’s a pyrightconfig.json as described above.

0 Likes

#5

As of today I am new to pyright and LSP-pyright but I just went through configuration with the latest LSP update (which now uses Python 3.8). I had some trouble initially but was able to successfully configure so I’m just putting this here in case anyone else is having trouble:

There are a few things you can check:

  1. in pyrightconfig.json I made sure to explicitly state the pythonPath at the top of the file eg my file looks like this:
{
    "pythonPath": "/Users/name/miniconda3/bin/python",
    "venvPath": "/Users/name/miniconda3/envs",
    "venv": "envname"
}
  1. It’s possible that you’ve configured miniconda to initialize in the path through .zshrc. But SublimeText doesn’t read .zshrc, it reads .zprofile. Copy the conda path init block instead from .zshrc to .zprofile

This seemed to work for me and LSP-pyright is working on my system.

0 Likes

#6

Thanks!!

AFAIU, pythonPath is alone sufficient (provided the path is accurate). And using that is what got my setup working too.

My issue is that venvPath and venv, without pythonPath, should also be sufficient. But for some reason, this stopped working on my machine after the update.

The nice thing about using venvPath and venv is that you can set venvPath in the general settings for pyright, to your conda environments directory, and then simply create a pyrightconfig.json file, as you say, wherever you need it, and simply specify the conda environment you want to use with venv. This is why I’m keen to get that configuration pattern working again.

0 Likes

#7

Partial Solution

I did a quick test: I put a bad path into pythonPath (ie one that doesn’t point to any existing file, “xpythonx”).

  • From the autocomplete behaviour, it seems that the pyrightconfig settings are employed as desired.

    • IE: the LSP works and behaves as though it is aware of the environment I’ve pointed it to with the venv parameter. I altered said environment and import provided packages specific to that environment.
  • Removing the bad path in pythonPath, and leaving it with the default setting of "", reverted the behaviour to what I’ve seen so far: the LSP picking up the system python.

  • Then adding the path to the binary works as I’ve said above.

  • Curiously, the logs report LSP-pyright: INFO: Unable to get Python version from interpreter when the path in pythonPath is bad, even though the LSP works and is aware of packages in the environment specified by venv.

@jfcherng … from this I’d infer:

  • that the lsp-pyright mechanism of obeying pythonPath and searching for an interpreter is not correctly deferring to the venv parameters.
  • I’d also guess that the log above reporting an inability to get the python version from the interpreter is from a process acting directly on pythonPath?
    • Which may be a clue to what could be going wrong here, as it seems that thwarting pythonPath and what ever process responds to it allows the venv parameters and whatever pyright does with them to work.
0 Likes

#8

Does you project have any of the following file?

  • .pdm-python
  • .python-version
  • Pipfile
  • poetry.lock
1 Like

#9

nope.

Plus, this used to work with completely simple setups … IE a directory and a python file … just add the pyrightconfig.json with a venv parameter and the LSP would work.

0 Likes

#10

If your project doesn’t have those files, I don’t think LSP-pyright does something special to pythonPath at this moment.

0 Likes

#11

Another quick test … adding a pythonVersion parameter to pyrightconfig.json changes the behaviour.

The console still reports LSP-pyright: INFO: Using python path "/usr/bin/python".

But, with a "3.X", based on the autocomplete behaviour, the LSP appears to again use the venv parameters and provide appropriate autocomplete (I’m just testing with import statements and autocompleting available packages/modules).

I’d suspect a lot of that is coming from a cache though (I don’t know how pyright/lsp works in that regard)

0 Likes

#12

I think the issue has been expaned too wide. We have to debug from a “it used to work but now it doesn’t” setup.

That is,

{
	"venvPath": "/Users/username/miniconda3/envs",
	"venv": "general",
}

And post your LSP-pyright settings, messages in LSP log panel, messages in ST console.

0 Likes

#13

Fair! Though I suspect the junk pythonPath parameter experiment may be useful.

// Settings in here override those in "LSP-pyright/LSP-pyright.sublime-settings"

{
	"settings":
	{
		"python.venvPath": "/Users/username/miniconda3/envs/",
		"pyright.dev_environment": "sublime_text_38",
		// "python.pythonPath": "pythonx"
	},
}

And of course, the pyrightconfig.json you quote. As I said, previously this used to work in any directory+python file.

I’m wondering … how hard is it to get a separate sublime running on the same machine (just to test)?

1 Like

#14

Super easy. You can download a portable build from https://www.sublimetext.com/download, or creates your own. A portable build is basically having a Data/ directory put along with ST’s executable. Then ST will use it for everything related. That is, if Data/ is empty, your ST is brand-new.

2 Likes

#15

Interestingly … exactly the same behaviour. venv parameters have no effect but pythonPath works seamlessly. “Disrupting” pythonPath with a bad path also seemed to bring the venv parameters into effect, with changing venv to another environment enabling autocompletions specific to packages in that environment.

So I would think that begins to suggest it’s not really my particular setup (perhaps the latest version of pyright or a peculiarity of my conda envs?).

I had a fresh ST install, fresh LSP, lsp-pyright and lsp-file-watcher installs.

Then a new directory, with a python file and a pyrightconfig.json as above.

0 Likes

#16

I check LSP-pyright codes.

The python.pythonPath setting sent to the server is determined in the following order:

  1. python.pythonPath specified in LSP-pyright settings
  2. deduced from project files: .pdm-python / .python-version / Pipfile / poetry.lock
  3. $ which python
  4. $ which python3
  5. nothing. an empty string.

This order hasn’t been changed like since when it’s been written.

So LSP-pyright: INFO: Using python path "/usr/bin/python" is likely from “3. $ which python”. You said if you do “1.” then it works. So I guess that’s because /usr/bin/python doesn’t match the version of those venvs.

But this probably explains nothing since you said “it’s working before”.


As for pythonVersion in pyrightconfig.json, from the official docs,

  • pythonVersion [string, optional]: Specifies the version of Python that will be used to execute the source code. The version should be specified as a string in the format “M.m” where M is the major version and m is the minor (e.g. "3.0" or "3.6" ). If a version is provided, pyright will generate errors if the source code makes use of language features that are not supported in that version. It will also tailor its use of type stub files, which conditionalizes type definitions based on the version. If no version is specified, pyright will use the version of the current python interpreter, if one is present.

I don’t think it’s related to venv. But you reported after adding that it works. So I have no idea how it works. But in your case, if it’s not specified, it’s equivalent to the version of python.pythonPath (i.e., /usr/bin/python).

0 Likes

#17

My guess would be, you set this in LSP-pyright’s settings

{
	"settings":
	{
		"pyright.dev_environment": "sublime_text_38", // irrelevant to this issue
		"python.pythonPath": "/Users/name/miniconda3/bin/python",
	},
}

And then the old pyrightconfig.json should continue to work.

{
	"venvPath": "/Users/username/miniconda3/envs",
	"venv": "general",
}
0 Likes

#18

Another guess, you started ST in an activated venv so $ which python auto provides /Users/name/miniconda3/bin/python and so it’s set to python.pythonPath by LSP-pyright before.

Or, maybe there are other ways that make $ which python give /Users/name/miniconda3/bin/python rather than /usr/bin/python before.

0 Likes

#19

Thanks for all of this!

  • Using "python.pythonPath": "/Users/name/miniconda3/bin/python" doesn’t really help as that python is used (which is the base environment) and not the one specified by venv for the required environment
  • Using $ which python (number 3.) certainly seems to be the issue.
    • I don’t know what was “working” before the update, but I have seen many report using pythonPath to get it pyright working with conda envs, so maybe there was just some funny bug or behaviour that has now been “fixed”.
    • Though, you did report that simply using pyrightconfig.json seemed to work on your system … which is interesting. Is there a chance that there are some simple $PATH differences causing this?
    • In support of that, one thing that has changed from before with the update was that I had to install a new version of node, which I did manually (using npm -> install n -> install stable node). There’s a chance that some $PATH settings were reset or something that brought /usr/bin/python back within view while previously they were not.
    • I could be imagining this, but I’m not sure lsp-pyright ever found the system python on its own in the past.
    • Would it be possible to bar lsp-pyright from using /usr/bin for anything or relying on which python?
  • Presuming that there isn’t something wrong with my setup … and to the extent you’re interested in feedback:
    • Being able to prevent lsp-pyright from using a fallback like /usr/bin/python or which python might be useful
    • Simply using pythonPath to point to the conda env python binary works well enough, it’s just that you have to create project specific settings and then find the path etc. So maybe some UX that makes that easier (which I’d guess is what VS Code does).
    • Using $(which conda) env list to infer the existence of conda, any envs and their python paths and then exposing those to the user could probably go far??
0 Likes

#20

The auto detection python feature was referred from coc-pyright’s codes: https://github.com/fannheyward/coc-pyright/blob/f7d4881765edc0152c92cd7ed41b7b5ca11c4da9/src/configSettings.ts#L47.

Coc-pyright detects CONDA_PREFIX, but we decide not to use CONDA_PREFIX because users use nvim and ST in a different way. People tend to start a GUI editor instance (or say, process) and then use that instance for everything without closing the instance. Note that all windows are the same instance unless you deliberately start ST with --multiinstance cli argument. That means CONDA_PREFIX is a fixed constant since the editor instance starts. Using that fixed CONDA_PREFIX for everything makes no sense. With the same reason, we don’t read VIRTUAL_ENV. Related discussions are on https://github.com/sublimelsp/LSP-pyright/pull/183/files/6054d2f07f8fc449b34db894ef2b98f53ee26c16#r956775623


I have a vague memory about the following, but I can’t find a reference now…

Coc-pyright eventually fallback to python as well, while we use $ which python is basically the same. Pyright uses python as well if pythonPath is not provided.

0 Likes