Issues with Pickling (likely cause: semantic tokens)
Are you please able to take a look: https://github.com/microsoft/vscode-python/issues/25003#issuecomment-2828140646
We are almost there with vscode aupport; hitting a couple of issues though
Originally posted by @rivershah in #336
@rivershah are you using notebook files, by any chance?
No, this was a standard *.py file
nvm, I can reproduce in neovim, so this will be easier for me to debug.
@seeM looks like this pickling error is starting with the notebook_utils file, any initial ideas on what the culprit could be?
File "[REDACTED]/notebook_utils.py", line 373, in wrapped
result = f(notebook_server, notebook_params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error log from neovim:
[START][2025-04-25 10:54:13] LSP logging initiated
[ERROR][2025-04-25 10:54:13] ...p/_transport.lua:36 "rpc" "jedi-language-server" "stderr" 'WARNING:pygls.protocol.json_rpc:Cancel notification for unknown message id "15"\n'
[ERROR][2025-04-25 10:54:13] ...p/_transport.lua:36 "rpc" "jedi-language-server" "stderr" "ERROR:pygls.protocol.json_rpc:Exception occurred for message \"15\": _pickle.UnpicklingError: invalid load key, ' '.\nNoneType: None\n"
[ERROR][2025-04-25 10:54:13] ...p/_transport.lua:36 "rpc" "jedi-language-server" "stderr" "ERROR:pygls.protocol.json_rpc:Exception occurred for message \"16\": _pickle.UnpicklingError: invalid load key, ' '.\nNoneType: None\n"
[ERROR][2025-04-25 10:54:13] ...p/_transport.lua:36 "rpc" "jedi-language-server" "stderr" "ERROR:pygls.protocol.json_rpc:Exception occurred for message \"17\": _pickle.UnpicklingError: invalid load key, ' '.\nNoneType: None\n"
[ERROR][2025-04-25 10:54:14] ...p/_transport.lua:36 "rpc" "jedi-language-server" "stderr" "ERROR:pygls.protocol.json_rpc:Exception occurred for message \"18\": _pickle.UnpicklingError: invalid load key, ' '.\nNoneType: None\n"
[ERROR][2025-04-25 10:54:16] ...p/_transport.lua:36 "rpc" "jedi-language-server" "stderr" "ERROR:pygls.protocol.json_rpc:Exception occurred for message \"19\": _pickle.UnpicklingError: invalid load key, ' '.\nNoneType: None\n"
[ERROR][2025-04-25 10:54:18] ...p/_transport.lua:36 "rpc" "jedi-language-server" "stderr" "ERROR:pygls.protocol.json_rpc:Failed to handle request 20 textDocument/hover HoverParams(text_document=TextDocumentIdentifier(uri='file:///home/sroeca/src/pappasam/jedi-language-server/jedi_language_server/server.py'), position=719:58, work_done_token=None)\nTraceback (most recent call last):\n File \"/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/pygls/protocol/json_rpc.py\", line 266, in _handle_request\n self._execute_request(msg_id, handler, params)\n File \"/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/pygls/protocol/json_rpc.py\", line 188, in _execute_request\n self._send_response(msg_id, handler(params))\n ^^^^^^^^^^^^^^^\n File \"/home/sroeca/src/pappasam/jedi-language-server/jedi_language_server/notebook_utils.py\", line 373, in wrapped\n result = f(notebook_server, notebook_params)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/sroeca/src/pappasam/jedi-language-server/jedi_language_server/server.py\", line 487, in hover\n jedi_script.help(*jedi_lines),\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/api/helpers.py\", line 487, in wrapper\n return func(self, line, column, *args, **kwargs)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/api/__init__.py\", line 372, in help\n definitions = self.goto(line, column, follow_imports=True)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/api/helpers.py\", line 487, in wrapper\n return func(self, line, column, *args, **kwargs)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/api/__init__.py\", line 300, in goto\n names = list(name.goto())\n ^^^^^^^^^^^\n File \"/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/names.py\", line 213, in goto\n return context.goto(name, position=stmt.start_pos)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/context.py\", line 34, in goto\n names = finder.filter_name(filters, name_or_str)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/finder.py\", line 35, in filter_name\n for filter in filters:\n ^^^^^^^\n File \"/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/context.py\", line 496, in get_global_filters\n b = next(base_context.inference_state.builtins_module.get_filters(), None)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/cache.py\", line 44, in wrapper\n rv = function(obj, *args, **kwargs)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/__init__.py\", line 129, in builtins_module\n builtins_module, = self.import_module((module_name,), sys_path=[])\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/__init__.py\", line 112, in import_module\n return imports.import_module_by_names(\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/imports.py\", line 377, in import_module_by_names\n import_module(\n File \"/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/plugins/__init__.py\", line 21, in wrapper\n return built_functions[public_name](*args, **kwargs)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/plugins/flask.py\", line 20, in wrapper\n return callback(inference_state, import_names, module_context, *args, **kwargs)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/gradual/typeshed.py\", line 115, in wrapper\n python_value_set = ValueSet.from_sets(\n ^^^^^^^^^^^^^^^^^^^\n File \"/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/base_value.py\", line 430, in from_sets\n for set_ in sets:\n ^^^^\n File \"/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/gradual/typeshed.py\", line 116, in <genexpr>\n func(inference_state, import_names, p, sys_path,)\n File \"/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/imports.py\", line 411, in import_module\n file_io_or_ns, is_pkg = inference_state.compiled_subprocess.get_module_info(\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/compiled/subprocess/__init__.py\", line 188, in wrapper\n result = self._compiled_subprocess.run(\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/compiled/subprocess/__init__.py\", line 296, in run\n return self._send(inference_state_id, function, args, kwargs)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/compiled/subprocess/__init__.py\", line 318, in _send\n is_exception, traceback, result = pickle_load(self._get_process().stdout)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/_compatibility.py\", line 25, in pickle_load\n return Unpickler(file).load()\n ^^^^^^^^^^^^^^^^^^^^^^\n_pickle.UnpicklingError: invalid load key, ' '.\n"
[ERROR][2025-04-25 10:54:18] .../vim/lsp/buf.lua:66 -32603 "_pickle.UnpicklingError: invalid load key, ' '."
[ERROR][2025-04-25 10:56:41] ...p/_transport.lua:36 "rpc" "jedi-language-server" "stderr" "ERROR:pygls.protocol.json_rpc:Exception occurred for message \"21\": _pickle.UnpicklingError: invalid load key, ' '.\nNoneType: None\n"
Formatted traceback:
ERROR:pygls.protocol.json_rpc:Failed to handle request 20 textDocument/hover HoverParams(text_document=TextDocumentIdentifier(uri='file:///home/sroeca/src/pappasam/jedi-language-server/jedi_language_server/server.py'), position=719:58, work_done_token=None)
Traceback (most recent call last):
File "/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/pygls/protocol/json_rpc.py", line 266, in _handle_request
self._execute_request(msg_id, handler, params)
File "/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/pygls/protocol/json_rpc.py", line 188, in _execute_request
self._send_response(msg_id, handler(params))
^^^^^^^^^^^^^^^
File "/home/sroeca/src/pappasam/jedi-language-server/jedi_language_server/notebook_utils.py", line 373, in wrapped
result = f(notebook_server, notebook_params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/sroeca/src/pappasam/jedi-language-server/jedi_language_server/server.py", line 487, in hover
jedi_script.help(*jedi_lines),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/api/helpers.py", line 487, in wrapper
return func(self, line, column, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/api/__init__.py", line 372, in help
definitions = self.goto(line, column, follow_imports=True)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/api/helpers.py", line 487, in wrapper
return func(self, line, column, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/api/__init__.py", line 300, in goto
names = list(name.goto())
^^^^^^^^^^^
File "/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/names.py", line 213, in goto
return context.goto(name, position=stmt.start_pos)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/context.py", line 34, in goto
names = finder.filter_name(filters, name_or_str)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/finder.py", line 35, in filter_name
for filter in filters:
^^^^^^^
File "/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/context.py", line 496, in get_global_filters
b = next(base_context.inference_state.builtins_module.get_filters(), None)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/cache.py", line 44, in wrapper
rv = function(obj, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/__init__.py", line 129, in builtins_module
builtins_module, = self.import_module((module_name,), sys_path=[])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/__init__.py", line 112, in import_module
return imports.import_module_by_names(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/imports.py", line 377, in import_module_by_names
import_module(
File "/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/plugins/__init__.py", line 21, in wrapper
return built_functions[public_name](*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/plugins/flask.py", line 20, in wrapper
return callback(inference_state, import_names, module_context, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/gradual/typeshed.py", line 115, in wrapper
python_value_set = ValueSet.from_sets(
^^^^^^^^^^^^^^^^^^^
File "/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/base_value.py", line 430, in from_sets
for set_ in sets:
^^^^
File "/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/gradual/typeshed.py", line 116, in <genexpr>
func(inference_state, import_names, p, sys_path,)
File "/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/imports.py", line 411, in import_module
file_io_or_ns, is_pkg = inference_state.compiled_subprocess.get_module_info(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/compiled/subprocess/__init__.py", line 188, in wrapper
result = self._compiled_subprocess.run(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/compiled/subprocess/__init__.py", line 296, in run
return self._send(inference_state_id, function, args, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/inference/compiled/subprocess/__init__.py", line 318, in _send
is_exception, traceback, result = pickle_load(self._get_process().stdout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/sroeca/src/pappasam/jedi-language-server/.venv/lib/python3.12/site-packages/jedi/_compatibility.py", line 25, in pickle_load
return Unpickler(file).load()
^^^^^^^^^^^^^^^^^^^^^^
_pickle.UnpicklingError: invalid load key, ' '.
What is workaround? Rollback to the previous release?
workaround is to just use the release prior to the landing of notebook support. If we can't figure this out soon, I'm just going to disable notebook support and make a new release.
I’m on vacation atm so unfortunately can’t guarantee I’ll be able to look at this soon.
What were the steps to repro this?
Does removing the notebook decorators fix it? They’re only first in the trace because of the decorator approach, but I’m not sure from the logs if that is the root cause.
@seeM the culprit appears to be semantic tokens, so feel free to ignore. Have a great vacation!
@daskol @rivershah disabling semantic tokens appears to prevent this issue from happening in practice, so I've disabled them by default in the latest release: https://github.com/pappasam/jedi-language-server/releases/tag/v0.45.1
@TechPizzaDev looks like semanticTokens wasn't quite ready for primetime after all. No rush (thanks to the toggle, semantic tokens were easy to disable by default), but figure this issue will be of interest to you if you've got some ideas about root causes / possible mitigation strategies.
I had constant pickling issues before I started writing the PR. I can look into it but I feel this was a problem already. Maybe the thread decorator makes the issue worse by desyncing the request ID?
Hmm, appreciate your observation! I'll look into that in a bit and see if I can determine a root cause. I always appreciate help if you have the time, but your comment has already been helpful
By simply removing SERVER.thread(), things appear to work fine (correctly, but slow on large files). @TechPizzaDev Any objections to removing this decorator?
I only added/copied that decorator since PR https://github.com/pappasam/jedi-language-server/pull/231 also had it. I had pickling issues with Intellisense hovers before I wrote this PR, but no other methods use Server.thread() so I'm not sure. I'd comment the decorator out with a note saying it's unstable for now.
Further work should probably go into Jedi itself, exposing a faster/specialized jedi_script.get_names method that only returns a specific range to make _semantic_tokens_range significantly faster.
Thanks for looking at this. Just so I am fully up to speed, now that the vscode devs have exposed the relevant settings for jedi-language-server for semantic highlight, we don't need to request any further refactors from them?
As we refactor here, it just flows through to vscode ms-python extension?
The activation settings seem to be hardcoded in vscode-python and as mentioned by https://github.com/microsoft/vscode-python/issues/25003#issuecomment-2828140646, jedi-language-server does not have config exposed i.e. semantic highlight is always enabled. Outside of that, changes should indeed flow with vscode-python releases AFAIK.
Hope this feature can be implemented soon. I am really looking forward to have semantic highlighting in my python script
The symptoms in my case was that the LSP features would work for a few seconds upon opening a project, then go into an infinite loading state upon clicking an xref after those few seconds. The debug console would indeed show the error mentioned in this thread. Restarting the Python LSP would make it work again for a few seconds, repeatably.
By simply removing
SERVER.thread(), things appear to work fine (correctly, but slow on large files). @TechPizzaDev Any objections to removing this decorator?
Gosh, thanks for this. This has been driving me insane for months. Simply killing the two instances of SERVER.thread() in ~/.vscode/extensions/ms-python.python-2025.10.0-linux-x64/python_files/lib/jedilsp/jedi_language_server/server.py made Python LSP work again.