Exception when hovering over a variable (Python LSP)

I am using NewType() from typing to define types - if I hover over a variable or parameter that uses one of the new types, there is an unhandled exception.
OmniSharp.Extensions.LanguageServer.Client.LspInvalidParametersException: 'Invalid parameters.'
Stack trace is too big to paste here so I cut out paths and a chunk from the middle. I can send the full thing over email if it is needed.
2020-06-09 10:25:54,548 UTC - ERROR - pyls_jsonrpc.endpoint - Failed to handle request 10
Traceback (most recent call last):
File "..\lib\site-packages\pyls_jsonrpc\endpoint.py", line 113, in consume
self._handle_request(message['id'], message['method'], message.get('params'))
File "..\lib\site-packages\pyls_jsonrpc\endpoint.py", line 182, in _handle_request
handler_result = handler(params)
File "..\lib\site-packages\pyls_jsonrpc\dispatchers.py", line 23, in handler
return method(**(params or {}))
File "..\lib\site-packages\pyls\python_ls.py", line 330, in m_text_document__hover
return self.hover(textDocument['uri'], position)
File "..\lib\site-packages\pyls\python_ls.py", line 264, in hover
return self._hook('pyls_hover', doc_uri, position=position) or {'contents': ''}
File "..\lib\site-packages\pyls\python_ls.py", line 155, in _hook
return hook_handlers(config=self.config, workspace=workspace, document=doc, **kwargs)
File "..\lib\site-packages\pluggy\hooks.py", line 286, in __call__
return self._hookexec(self, self.get_hookimpls(), kwargs)
File "..\lib\site-packages\pluggy\manager.py", line 92, in _hookexec
return self._inner_hookexec(hook, methods, kwargs)
File "..\lib\site-packages\pluggy\manager.py", line 335, in traced_hookexec
return outcome.get_result()
File "..\lib\site-packages\pluggy\callers.py", line 80, in get_result
raise ex[1].with_traceback(ex[2])
File "..\lib\site-packages\pluggy\callers.py", line 52, in from_call
result = func()
File "..\lib\site-packages\pluggy\manager.py", line 333, in
outcome = _Result.from_call(lambda: oldcall(hook, hook_impls, kwargs))
File "..\lib\site-packages\pluggy\manager.py", line 86, in
firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
File "..\lib\site-packages\pluggy\callers.py", line 208, in _multicall
return outcome.get_result()
File "..\lib\site-packages\pluggy\callers.py", line 80, in get_result
raise ex[1].with_traceback(ex[2])
File "..\lib\site-packages\pluggy\callers.py", line 187, in _multicall
res = hook_impl.function(*args)
File "..\lib\site-packages\pyls\plugins\hover.py", line 13, in pyls_hover
definitions = document.jedi_script().infer(**code_position)
File "..\lib\site-packages\jedi\api\helpers.py", line 465, in wrapper
return func(self, line, column, *args, **kwargs)
----
File "..\lib\site-packages\jedi\inference\signature.py", line 107, in
for executed_param_name in executed_param_names)
File "..\lib\site-packages\jedi\inference\param.py", line 34, in matches_signature
argument_values = self.infer().py__class__()
File "..\lib\site-packages\jedi\inference\base_value.py", line 376, in py__class__
return ValueSet(c.py__class__() for c in self._set)
File "..\lib\site-packages\jedi\common\value.py", line 53, in __init__
self._set = frozenset(iterable)
File "..\lib\site-packages\jedi\inference\base_value.py", line 376, in
return ValueSet(c.py__class__() for c in self._set)
AttributeError: 'NewType' object has no attribute 'py__class__'
Could you please post a piece of Python code to reproduce this?
I am trying it with this:
from typing import NewType
UserId = NewType('UserId', int)
some_id = UserId(524313)
def get_user_name(user_id: UserId) -> str:
return "
# typechecks
user_a = get_user_name(UserId(42351))
# does not typecheck; an int is not a UserId
user_b = get_user_name(-1)
- and get no exceptions.
I cannot duplicate it when everything is in the same file. It also seems like the metadata decorators are necessary.
You should see the exception when you are in the cash_deposit.py error, last line, hover over self.currency.
2 folders, 3 files.
***********************
In a folder named std:
***********************
------------------------
File : cash_deposit.py
------------------------
from dataclasses import dataclass
from typing import NewType, Tuple
__all__ = [
"Currency", "Date", "Tenor"
]
Currency = NewType("Currency", str)
Date = NewType("Date", str)
Tenor = NewType("Tenor", str)

------------------------
File: metadata.py
------------------------
from inspect import isclass, signature
__all__ = [
"input"
]
class Input:
def __init__(self,
name,
required=True,
category=None,
description=None,
types=None,
defaulter=None,
post_process=None,
validator=None,
def_name=None):
self.name = name
self.required = required
self.category = category
self.__doc__ = description
self.types = types
self.defaulter = defaulter
self.post_process = post_process
self.validator = validator
self.def_name = def_name
***************************
In a folder named examples:
***************************
------------------------
File : cash_deposit.py
------------------------
import typing
from dataclasses import dataclass

class CashDeposit2():
""Cash Deposit template.""
@std.input("Currency", required=False, types=std.Currency)
def currency(self):
""The currency.""
pass
@std.input("Maturity", types=typing.Union[std.Date, std.Tenor])
def maturity(self):
""The maturity for the deposit expressed as a base_date or a tenor.""
pass
@std.input("Notional", required=False, types=float, defaulter=1.0)
def notional(self):
""The notional value of the deposit.""
pass
def calculate(self, context, requests):
print(f'Calculate {self.currency} {self.maturity} {self.notional}')
I tried to reproduce this on your examples, but it doesn't throw such exceptions on my machine.
Since we have little control of the LSP server itself, and I think in this case we are not sending the requests plainly wrong, I would suggest to catch and ignore such LSP exceptions in operations like code completion, hover tooltip etc. E.g. when server is unable to provide the data for the hover tooltip, we can just ignore it.
Please use the following code to do this:
class MyPythonRepository : Alternet.Syntax.Parsers.Lsp.Python.PythonRepository
{
public MyPythonRepository(ILspDocumentProvider documentProvider, ISyntaxTree syntaxTree) : base(documentProvider, syntaxTree)
{
}

public override async Task CodeCompletion(Point position, CodeCompletionArgs e)
{
try
{
await base.CodeCompletion(position, e);
}
catch (LspException)
{
}
}
}

class MyPythonParser : Alternet.Syntax.Parsers.Lsp.Python.PythonParser
{
public override ICodeCompletionRepository CreateRepository()
{
return new MyPythonRepository(this, SyntaxTree);
}

In the upcoming release, we will also add similar exception checks, so it will not be needed to use the code above in an application.