Repository navigation
Took 2 minutes to respond to on_hover(), from 15:56:14 until 15:58:38 #257
Copy link
Copy link
Open
Description
Originally posted on: sublimelsp/LSP#255 python-language-server hanged Sublime Text by several seconds on file close event
@tomv564 sublimelsp/LSP#255 (comment) If it is the linter causing the slowness, I also don't believe that should stop pyls from responding to other requests.
This caused the LSP plugin for Sublime Text to hang completely for the 2 minutes the server did not responded to the on_hover request. I do not think there is an issue here if that is what does take to compute everything. Unless it doesn't.
This was the LSP for Sublime Text log. Sadly it does not have the timestamp. I am going to open a feature request for:
LSP: initialize on open 2 F:\SublimeText\Data\Packages\LSP\plugin\core\clients.py
LSP: initialize on open 2 F:\SublimeText\Data\Packages\LSP\plugin\core\clients.py
LSP: --> textDocument/hover
LSP: --> textDocument/didChange
LSP: --> textDocument/signatureHelp
LSP: --> textDocument/didChange
LSP: <-- textDocument/publishDiagnostics
LSP: --> textDocument/didChange
LSP: <-- textDocument/publishDiagnostics
LSP: --> textDocument/hover
LSP: initialize on open 2 F:\SublimeText\Data\Packages\LSP\plugin\core\clients.py
LSP: initialize on open 2 F:\SublimeText\Data\Packages\LSP\plugin\core\clients.py
LSP: --> textDocument/didChange
LSP: <-- textDocument/publishDiagnostics
LSP: --> textDocument/hover
LSP: --> textDocument/hover
LSP: --> textDocument/completion
LSP: --> textDocument/didChange
LSP: --> textDocument/hover
LSP: <-- textDocument/publishDiagnostics
LSP: initialize on open 2 F:\SublimeText\Data\Packages\LSP\plugin\core\clients.py
Log:
Details
2018-02-04 15:56:14,325 DEBUG pyls.config.config:processmessage:137 pyls_completions [hook]
config: Config. _root_path: f:\SublimeText\Data, _root_uri: file:///F:/SublimeText/Data, _init_opts: None, _settings: {'plugins': {'pydocstyle': {'enabled': True, 'ignore': ['D202', 'D208']}, 'rope': {'create_folder': False}, 'pycodestyle': {'enabled': False}}}, _plugin_settings: {'plugins': {'rope_completion': {'enabled': False}, 'pydocstyle': {'enabled': False}}}, _disabled_plugins: [<module 'pyls.plugins.pycodestyle_lint' from 'd:\\user\\dropbox\\softwareversioning\\python-language-server\\pyls\\plugins\\pycodestyle_lint.py'>], _config_sources(flake8): Flake8Config. root_path: f:\SublimeText\Data, is_windows: True, xdg_home: C:\Users\Professional/.config, _modified_times: {}, _config_sources(pycodestyle): PyCodeStyleConfig. root_path: f:\SublimeText\Data, is_windows: True, xdg_home: C:\Users\Professional/.config, _modified_times: {(): ()}, _configs_cache(()): []
workspace: Workspace. _root_path: f:\SublimeText\Data, _root_uri: file:///F:/SublimeText/Data, _root_uri_scheme: file, _lang_server: PythonLanguageServer. config: Config. _root_path: f:\SublimeText\Data, _root_uri: file:///F:/SublimeText/Data, _init_opts: None, _settings: {'plugins': {'pydocstyle': {'enabled': True, 'ignore': ['D202', 'D208']}, 'rope': {'create_folder': False}, 'pycodestyle': {'enabled': False}}}, _plugin_settings: {'plugins': {'rope_completion': {'enabled': False}, 'pydocstyle': {'enabled': False}}}, _disabled_plugins: [<module 'pyls.plugins.pycodestyle_lint' from 'd:\\user\\dropbox\\softwareversioning\\python-language-server\\pyls\\plugins\\pycodestyle_lint.py'>], _config_sources(flake8): Flake8Config. root_path: f:\SublimeText\Data, is_windows: True, xdg_home: C:\Users\Professional/.config, _modified_times: {}, _config_sources(pycodestyle): PyCodeStyleConfig. root_path: f:\SublimeText\Data, is_windows: True, xdg_home: C:\Users\Professional/.config, _modified_times: {(): ()}, _configs_cache(()): [], _dispatchers: [], __rope: Project. _address: f:\SublimeText\Data, _ropefolder_name: None, ignored: _ResourceMatcher. patterns: [], file_list: None, prefs: Prefs. {'extension_modules': ['numpy', 'os', 'array', 'audioop', 'binascii', 'cmath', 'collections', 'datetime', 'errno', 'gc', 'imp', 'itertools', 'marshal', 'math', 'mmap', 'msvcrt', 'nt', 'operator', 'parser', 'signal', 'sys', 'time', 'xxsubtype', 'zipimport', 'zlib']}, callbacks: {'ignored_resources': <bound method _ResourceMatcher.set_patterns of <rope.base.resources._ResourceMatcher object at 0x00000208BD610A90>>}, _docs(file:///F:/SublimeText/Data/Packages/LSP/plugin/core/clients.py): Document. uri: file:///F:/SublimeText/Data/Packages/LSP/plugin/core/clients.py, version: 4, path: f:\SublimeText\Data\Packages\LSP\plugin\core\clients.py, filename: clients.py, _local: True, _extra_sys_path: [], _rope_project: Project. _address: f:\SublimeText\Data, _ropefolder_name: None, ignored: _ResourceMatcher. patterns: [], file_list: None, prefs: Prefs. {'extension_modules': ['numpy', 'os', 'array', 'audioop', 'binascii', 'cmath', 'collections', 'datetime', 'errno', 'gc', 'imp', 'itertools', 'marshal', 'math', 'mmap', 'msvcrt', 'nt', 'operator', 'parser', 'signal', 'sys', 'time', 'xxsubtype', 'zipimport', 'zlib']}, callbacks: {'ignored_resources': <bound method _ResourceMatcher.set_patterns of <rope.base.resources._ResourceMatcher object at 0x00000208BD610A90>>}
document: Document. uri: file:///F:/SublimeText/Data/Packages/LSP/plugin/core/clients.py, version: 4, path: f:\SublimeText\Data\Packages\LSP\plugin\core\clients.py, filename: clients.py, _local: True, _extra_sys_path: [], _rope_project: Project. _address: f:\SublimeText\Data, _ropefolder_name: None, ignored: _ResourceMatcher. patterns: [], file_list: None, prefs: Prefs. {'extension_modules': ['numpy', 'os', 'array', 'audioop', 'binascii', 'cmath', 'collections', 'datetime', 'errno', 'gc', 'imp', 'itertools', 'marshal', 'math', 'mmap', 'msvcrt', 'nt', 'operator', 'parser', 'signal', 'sys', 'time', 'xxsubtype', 'zipimport', 'zlib']}, callbacks: {'ignored_resources': <bound method _ResourceMatcher.set_patterns of <rope.base.resources._ResourceMatcher object at 0x00000208BD610A90>>}
position: {'line': 49, 'character': 20}
2018-02-04 15:58:37,344 DEBUG pyls.config.config:processmessage:137 finish pyls_completions --> [[{'label': 'self', 'kind': 18, 'detail': 'local self', 'documentation': '', 'sortText': 'aself'}, {'label': 'set_config_ready', 'kind': 3, 'detail': 'global set_config_ready', 'documentation': '', 'sortText': 'aset_config_ready'}, {'label': 'set_config_starting', 'kind': 3, 'detail': 'global set_config_starting', 'documentation': '', 'sortText': 'aset_config_starting'}, {'label': 'set_config_stopping', 'kind': 3, 'detail': 'global set_config_stopping', 'documentation': '', 'sortText': 'aset_config_stopping'}, {'label': 'sublime', 'kind': 9, 'detail': 'imported sublime', 'documentation': '', 'sortText': 'asublime'}, {'label': 'set', 'kind': 7, 'detail': 'builtin set', 'documentation': 'set() -> new empty set object\nset(iterable) -> new set object\n\nBuild an unordered collection of unique elements.', 'sortText': 'yset'}, {'label': 'slice', 'kind': 7, 'detail': 'builtin slice', 'documentation': 'slice(stop)\nslice(start, stop[, step])\n\nCreate a slice object. This is used for extended slicing (e.g. a[0:10:2]).', 'sortText': 'yslice'}, {'label': 'staticmethod', 'kind': 7, 'detail': 'builtin staticmethod', 'documentation': 'staticmethod(function) -> method\n\nConvert a function to be a static method.\n\nA static method does not receive an implicit first argument.\nTo declare a static method, use this idiom:\n\n class C:\n @staticmethod\n def f(arg1, arg2, ...):\n ...\n\nIt can be called either on the class (e.g. C.f()) or on an instance\n(e.g. C().f()). The instance is ignored except for its class.\n\nStatic methods in Python are similar to those found in Java or C++.\nFor a more advanced concept, see the classmethod builtin.', 'sortText': 'ystaticmethod'}, {'label': 'str', 'kind': 7, 'detail': 'builtin str', 'documentation': "str(object='') -> str\nstr(bytes_or_buffer[, encoding[, errors]]) -> str\n\nCreate a new string object from the given object. If encoding or\nerrors is specified, then the object must expose a data buffer\nthat will be decoded using the given encoding and error handler.\nOtherwise, returns the result of object.__str__() (if defined)\nor repr(object).\nencoding defaults to sys.getdefaultencoding().\nerrors defaults to 'strict'.", 'sortText': 'ystr'}, {'label': 'setattr', 'kind': 3, 'detail': 'builtin setattr', 'documentation': "Sets the named attribute on the given object to the specified value.\n\nsetattr(x, 'y', v) is equivalent to ``x.y = v''", 'sortText': 'ysetattr'}, {'label': 'sorted', 'kind': 3, 'detail': 'builtin sorted', 'documentation': 'Return a new list containing all items from the iterable in ascending order.\n\nA custom key function can be supplied to customize the sort order, and the\nreverse flag can be set to request the result in descending order.', 'sortText': 'ysorted'}, {'label': 'sum', 'kind': 3, 'detail': 'builtin sum', 'documentation': "Return the sum of a 'start' value (default: 0) plus an iterable of numbers\n\nWhen the iterable is empty, return the start value.\nThis function is intended specifically for use with numeric values and may\nreject non-numeric types.", 'sortText': 'ysum'}, {'label': 'super', 'kind': 3, 'detail': 'builtin super', 'documentation': 'super() -> same as super(__class__, <first argument>)\nsuper(type) -> unbound super object\nsuper(type, obj) -> bound super object; requires isinstance(obj, type)\nsuper(type, type2) -> bound super object; requires issubclass(type2, type)\nTypical use to call a cooperative superclass method:\nclass C(B):\n def meth(self, arg):\n super().meth(arg)\nThis works for class methods too:\nclass C(B):\n @classmethod\n def cmeth(cls, arg):\n super().cmeth(arg)\n', 'sortText': 'ysuper'}], [{'label': 'self', 'kind': 6, 'detail': '__main__.has_client_with_capability', 'documentation': "LspTextCommand(self, view, capability='')\n\n", 'sortText': 'aself', 'insertText': 'self'}, {'label': 'Set', 'kind': 7, 'detail': '__main__', 'documentation': '', 'sortText': 'aSet', 'insertText': 'Set'}, {'label': 'set', 'kind': 7, 'detail': '', 'documentation': 'set() -> new empty set object\nset(iterable) -> new set object\n\nBuild an unordered collection of unique elements.', 'sortText': 'aset', 'insertText': 'set'}, {'label': 'set_config_ready(window, config_name, client)', 'kind': 3, 'detail': '__main__', 'documentation': "set_config_ready(window: sublime.Window, config_name: str, client:\n'Client')\n\n", 'sortText': 'aset_config_ready', 'insertText': 'set_config_ready'}, {'label': 'set_config_starting(window, config_name)', 'kind': 3, 'detail': '__main__', 'documentation': 'set_config_starting(window: sublime.Window, config_name: str)\n\n', 'sortText': 'aset_config_starting', 'insertText': 'set_config_starting'}, {'label': 'set_config_stopping(window, config_name)', 'kind': 3, 'detail': '__main__', 'documentation': 'set_config_stopping(window: sublime.Window, config_name: str)\n\n', 'sortText': 'aset_config_stopping', 'insertText': 'set_config_stopping'}, {'label': 'setattr(obj, name, value)', 'kind': 3, 'detail': '', 'documentation': "Sets the named attribute on the given object to the specified value.\n\nsetattr(x, 'y', v) is equivalent to ``x.y = v''", 'sortText': 'asetattr', 'insertText': 'setattr'}, {'label': 'slice', 'kind': 7, 'detail': '', 'documentation': 'slice(stop)\nslice(start, stop[, step])\n\nCreate a slice object.\xa0\xa0This is used for extended slicing (e.g. a[0:10:2]).', 'sortText': 'aslice', 'insertText': 'slice'}, {'label': 'sorted(iterable, cmp, key, reverse)', 'kind': 3, 'detail': '', 'documentation': "sorted(iterable, cmp=None, key=None, reverse=False)\n\nBuilt-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", 'sortText': 'asorted', 'insertText': 'sorted'}, {'label': 'staticmethod', 'kind': 7, 'detail': '', 'documentation': 'staticmethod(function) -> method\n\nConvert a function to be a static method.\n\nA static method does not receive an implicit first argument.\nTo declare a static method, use this idiom:\n\n\xa0\xa0\xa0\xa0 class C:\n\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0 @staticmethod\n\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0 def f(arg1, arg2, ...):\n\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0 ...\n\nIt can be called either on the class (e.g. C.f()) or on an instance\n(e.g. C().f()).\xa0\xa0The instance is ignored except for its class.\n\nStatic methods in Python are similar to those found in Java or C++.\nFor a more advanced concept, see the classmethod builtin.', 'sortText': 'astaticmethod', 'insertText': 'staticmethod'}, {'label': 'StopAsyncIteration', 'kind': 7, 'detail': '', 'documentation': 'Signal the end from iterator.__anext__().', 'sortText': 'aStopAsyncIteration', 'insertText': 'StopAsyncIteration'}, {'label': 'StopIteration', 'kind': 7, 'detail': '', 'documentation': 'Signal the end from iterator.__next__().', 'sortText': 'aStopIteration', 'insertText': 'StopIteration'}, {'label': 'str', 'kind': 7, 'detail': '', 'documentation': "str(object='') -> str\nstr(bytes_or_buffer[, encoding[, errors]]) -> str\n\nCreate a new string object from the given object. If encoding or\nerrors is specified, then the object must expose a data buffer\nthat will be decoded using the given encoding and error handler.\nOtherwise, returns the result of object.__str__() (if defined)\nor repr(object).\nencoding defaults to sys.getdefaultencoding().\nerrors defaults to 'strict'.", 'sortText': 'astr', 'insertText': 'str'}, {'label': 'sublime', 'kind': 9, 'detail': '__main__', 'documentation': '', 'sortText': 'asublime', 'insertText': 'sublime'}, {'label': 'sum(iterable, start)', 'kind': 3, 'detail': '', 'documentation': "Return the sum of a 'start' value (default: 0) plus an iterable of numbers\n\nWhen the iterable is empty, return the start value.\nThis function is intended specifically for use with numeric values and may\nreject non-numeric types.", 'sortText': 'asum', 'insertText': 'sum'}, {'label': 'super', 'kind': 7, 'detail': '', 'documentation': 'super() -> same as super(__class__, <first argument>)\nsuper(type) -> unbound super object\nsuper(type, obj) -> bound super object; requires isinstance(obj, type)\nsuper(type, type2) -> bound super object; requires issubclass(type2, type)\nTypical use to call a cooperative superclass method:\nclass C(B):\n\xa0\xa0\xa0\xa0def meth(self, arg):\n\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0super().meth(arg)\nThis works for class methods too:\nclass C(B):\n\xa0\xa0\xa0\xa0@classmethod\n\xa0\xa0\xa0\xa0def cmeth(cls, arg):\n\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0super().cmeth(arg)', 'sortText': 'asuper', 'insertText': 'super'}, {'label': 'SyntaxError', 'kind': 7, 'detail': '', 'documentation': 'Invalid syntax.', 'sortText': 'aSyntaxError', 'insertText': 'SyntaxError'}, {'label': 'SyntaxWarning', 'kind': 7, 'detail': '', 'documentation': 'Base class for warnings about dubious syntax.', 'sortText': 'aSyntaxWarning', 'insertText': 'SyntaxWarning'}, {'label': 'SystemError', 'kind': 7, 'detail': '', 'documentation': 'Internal error in the Python interpreter.\n\nPlease report this to the Python maintainer, along with the traceback,\nthe Python version, and the hardware/OS platform and version.', 'sortText': 'aSystemError', 'insertText': 'SystemError'}, {'label': 'SystemExit', 'kind': 7, 'detail': '', 'documentation': 'Request to exit from the interpreter.', 'sortText': 'aSystemExit', 'insertText': 'SystemExit'}]] [hook]
2018-02-04 15:58:37,349 DEBUG pyls.server:handle:35 Got message: b'{"jsonrpc": "2.0", "method": "textDocument/didChange", "params": {"textDocument": {"uri": "file:///F:/SublimeText/Data/Packages/LSP/plugin/core/clients.py", "version": 5}, "contentChanges": [{"text": "import sublime\\n\\nfrom sublime_plugin import TextCommand\\n\\nfrom .logging import debug, exception_log\\nfrom .configurations import config_for_scope, is_supported_view\\nfrom .protocol import Request\\nfrom .workspace import get_project_path\\n\\n# typing only\\nfrom .rpc import Client\\nfrom .settings import ClientConfig\\nassert Client and ClientConfig\\n\\n\\ntry:\\n from typing import Any, List, Dict, Tuple, Callable, Optional, Set\\n assert Any and List and Dict and Tuple and Callable and Optional and Set\\nexcept ImportError:\\n pass\\n\\n\\nclients_by_window = {} # type: Dict[int, Dict[str, ConfigState]]\\n\\n\\nclass ClientStates(object):\\n STARTING = 0\\n READY = 1\\n STOPPING = 2\\n\\n\\nclass ConfigState(object):\\n\\n def __init__(self, state=ClientStates.STARTING, client=None):\\n self.state = state\\n self.client = client\\n\\n\\nclass LspTextCommand(TextCommand):\\n def __init__(self, view, capability=\'\'):\\n super().__init__(view)\\n self.capability = capability\\n\\n def is_visible(self):\\n return is_supported_view(self.view)\\n\\n def has_client_with_capability(self):\\n client = client_for_view(self.view)\\n if client and client.has_capability(self.capability):\\n return tr\\n return False\\n\\n\\ndef window_configs(window: sublime.Window) -> \'Dict[str, ConfigState]\':\\n if window.id() in clients_by_window:\\n return clients_by_window[window.id()]\\n else:\\n # debug(\\"no configs found for window\\", window.id())\\n return {}\\n\\n\\ndef is_ready_window_config(window: sublime.Window, config_name: str):\\n configs = window_configs(window)\\n\\n if config_name not in configs:\\n return False\\n\\n if configs[config_name].state == ClientStates.READY:\\n return True\\n\\n return False\\n\\n\\n# Startup\\n\\ndef can_start_config(window: sublime.Window, config_name: str):\\n return config_name not in window_configs(window)\\n\\n\\ndef set_config_starting(window: sublime.Window, config_name: str):\\n clients_by_window.setdefault(window.id(), {})[config_name] = ConfigState()\\n\\n\\ndef clear_config_state(window: sublime.Window, config_name: str):\\n configs = window_configs(window)\\n del configs[config_name]\\n\\n\\ndef set_config_ready(window: sublime.Window, config_name: str, client: \'Client\'):\\n window_configs(window)[config_name] = ConfigState(ClientStates.READY, client)\\n debug(\\"{} client registered for window {}\\".format(config_name, window.id()))\\n\\n\\ndef set_config_stopping(window: sublime.Window, config_name: str):\\n window_configs(window)[config_name].state = ClientStates.STOPPING\\n\\n\\ndef client_for_closed_view(view: sublime.View) -> \'Optional[Client]\':\\n return _client_for_view_and_window(view, sublime.active_window())\\n\\n\\ndef client_for_view(view: sublime.View) -> \'Optional[Client]\':\\n return _client_for_view_and_window(view, view.window())\\n\\n\\ndef _client_for_view_and_window(view: sublime.View, window: \'Optional[sublime.Window]\') -> \'Optional[Client]\':\\n if not window:\\n debug(\\"no window for view\\", view.file_name())\\n return None\\n\\n config = config_for_scope(view)\\n if not config:\\n debug(\\"config not available for view\\", view.file_name())\\n return None\\n\\n window_config_states = window_configs(window)\\n if config.name not in window_config_states:\\n debug(config.name, \\"not available for view\\",\\n view.file_name(), \\"in window\\", window.id())\\n return None\\n else:\\n config_state = window_config_states[config.name]\\n if config_state.client:\\n return config_state.client\\n else:\\n debug(config.name, \\"in state\\", config_state.state, \\" for view\\",\\n view.file_name(), \\"in window\\", window.id())\\n return None\\n\\n\\n# Shutdown\\n\\ndef remove_window_client(window: sublime.Window, config_name: str):\\n del clients_by_window[window.id()][config_name]\\n\\n\\ndef unload_all_clients():\\n for window in sublime.windows():\\n for config_name, config_state in window_configs(window).items():\\n if config_state.client:\\n if config_state.state == ClientStates.STARTING:\\n unload_client(config_state.client, window.id(), config_name)\\n else:\\n debug(\'ignoring unload of config in state\', config_state.state)\\n else:\\n debug(\'ignoring unload of config without client\')\\n\\n\\nclosing_window_ids = set() # type: Set[int]\\n\\n\\ndef check_window_unloaded():\\n global clients_by_window\\n open_window_ids = list(window.id() for window in sublime.windows())\\n iterable_clients_by_window = clients_by_window.copy()\\n for id, window_clients in iterable_clients_by_window.items():\\n if id not in open_window_ids and window_clients:\\n if id not in closing_window_ids:\\n closing_window_ids.add(id)\\n debug(\\"window closed\\", id)\\n for closed_window_id in closing_window_ids:\\n unload_window_clients(closed_window_id)\\n closing_window_ids.clear()\\n\\n\\ndef unload_window_clients(window_id: int):\\n if window_id in clients_by_window:\\n window_configs = clients_by_window[window_id]\\n for config_name, state in window_configs.items():\\n window_configs[config_name].state = ClientStates.STOPPING\\n debug(\\"unloading client\\", config_name, state.client)\\n unload_client(state.client, window_id, config_name)\\n\\n\\ndef unload_old_clients(window: sublime.Window):\\n project_path = get_project_path(window)\\n configs = window_configs(window)\\n clients_to_unload = {}\\n for config_name, state in configs.items():\\n if state.client and state.state == ClientStates.READY and state.client.get_project_path() != project_path:\\n debug(\'unload\', config_name, \'project path changed from\',\\n state.client.get_project_path(), \'to\', project_path)\\n clients_to_unload[config_name] = state.client\\n\\n for config_name, client in clients_to_unload.items():\\n set_config_stopping(window, config_name)\\n unload_client(client, window.id(), config_name)\\n\\n\\nclients_unloaded_handler = None # type: Optional[Callable]\\n\\n\\ndef register_clients_unloaded_handler(handler: \'Callable\'):\\n global clients_unloaded_handler\\n clients_unloaded_handler = handler\\n\\n\\ndef on_shutdown(client: Client, window_id: int, config_name: str, response):\\n try:\\n client.exit()\\n del clients_by_window[window_id][config_name]\\n\\n if not clients_by_window[window_id]:\\n debug(\\"all clients unloaded\\")\\n if clients_unloaded_handler:\\n clients_unloaded_handler(window_id)\\n\\n except Exception as err:\\n exception_log(\\"Error exiting server\\", err)\\n\\n\\ndef unload_client(client: Client, window_id: int, config_name: str):\\n client.send_request(Request.shutdown(), lambda response: on_shutdown(client, window_id, config_name, response))\\n"}]}}'
2018-02-04 15:58:37,364 DEBUG pyls.server:handle:35 Got message: b'{"jsonrpc": "2.0", "id": 25, "method": "textDocument/hover", "params": {"textDocument": {"uri": "file:///F:/SublimeText/Data/Packages/LSP/plugin/core/clients.py"}, "position": {"line": 48, "character": 11}}}'
2018-02-04 15:58:37,368 DEBUG pyls.python_ls:_hook:48 PythonLanguageServer, self.config: Config. _root_path: f:\SublimeText\Data, _root_uri: file:///F:/SublimeText/Data, _init_opts: None, _settings: {'plugins': {'pydocstyle': {'enabled': True, 'ignore': ['D202', 'D208']}, 'rope': {'create_folder': False}, 'pycodestyle': {'enabled': False}}}, _plugin_settings: {'plugins': {'rope_completion': {'enabled': False}, 'pydocstyle': {'enabled': False}}}, _disabled_plugins: [<module 'pyls.plugins.pycodestyle_lint' from 'd:\\user\\dropbox\\softwareversioning\\python-language-server\\pyls\\plugins\\pycodestyle_lint.py'>], _config_sources(flake8): Flake8Config. root_path: f:\SublimeText\Data, is_windows: True, xdg_home: C:\Users\Professional/.config, _modified_times: {}, _config_sources(pycodestyle): PyCodeStyleConfig. root_path: f:\SublimeText\Data, is_windows: True, xdg_home: C:\Users\Professional/.config, _modified_times: {(): ()}, _configs_cache(()): []
2018-02-04 15:58:37,376 DEBUG pyls.config.config:processmessage:137 pyls_hover [hook]
config: Config. _root_path: f:\SublimeText\Data, _root_uri: file:///F:/SublimeText/Data, _init_opts: None, _settings: {'plugins': {'pydocstyle': {'enabled': True, 'ignore': ['D202', 'D208']}, 'rope': {'create_folder': False}, 'pycodestyle': {'enabled': False}}}, _plugin_settings: {'plugins': {'rope_completion': {'enabled': False}, 'pydocstyle': {'enabled': False}}}, _disabled_plugins: [<module 'pyls.plugins.pycodestyle_lint' from 'd:\\user\\dropbox\\softwareversioning\\python-language-server\\pyls\\plugins\\pycodestyle_lint.py'>], _config_sources(flake8): Flake8Config. root_path: f:\SublimeText\Data, is_windows: True, xdg_home: C:\Users\Professional/.config, _modified_times: {}, _config_sources(pycodestyle): PyCodeStyleConfig. root_path: f:\SublimeText\Data, is_windows: True, xdg_home: C:\Users\Professional/.config, _modified_times: {(): ()}, _configs_cache(()): []
workspace: Workspace. _root_path: f:\SublimeText\Data, _root_uri: file:///F:/SublimeText/Data, _root_uri_scheme: file, _lang_server: PythonLanguageServer. config: Config. _root_path: f:\SublimeText\Data, _root_uri: file:///F:/SublimeText/Data, _init_opts: None, _settings: {'plugins': {'pydocstyle': {'enabled': True, 'ignore': ['D202', 'D208']}, 'rope': {'create_folder': False}, 'pycodestyle': {'enabled': False}}}, _plugin_settings: {'plugins': {'rope_completion': {'enabled': False}, 'pydocstyle': {'enabled': False}}}, _disabled_plugins: [<module 'pyls.plugins.pycodestyle_lint' from 'd:\\user\\dropbox\\softwareversioning\\python-language-server\\pyls\\plugins\\pycodestyle_lint.py'>], _config_sources(flake8): Flake8Config. root_path: f:\SublimeText\Data, is_windows: True, xdg_home: C:\Users\Professional/.config, _modified_times: {}, _config_sources(pycodestyle): PyCodeStyleConfig. root_path: f:\SublimeText\Data, is_windows: True, xdg_home: C:\Users\Professional/.config, _modified_times: {(): ()}, _configs_cache(()): [], _dispatchers: [], __rope: Project. _address: f:\SublimeText\Data, _ropefolder_name: None, ignored: _ResourceMatcher. patterns: [], file_list: None, prefs: Prefs. {'extension_modules': ['numpy', 'os', 'array', 'audioop', 'binascii', 'cmath', 'collections', 'datetime', 'errno', 'gc', 'imp', 'itertools', 'marshal', 'math', 'mmap', 'msvcrt', 'nt', 'operator', 'parser', 'signal', 'sys', 'time', 'xxsubtype', 'zipimport', 'zlib']}, callbacks: {'ignored_resources': <bound method _ResourceMatcher.set_patterns of <rope.base.resources._ResourceMatcher object at 0x00000208BD610A90>>}, _docs(file:///F:/SublimeText/Data/Packages/LSP/plugin/core/clients.py): Document. uri: file:///F:/SublimeText/Data/Packages/LSP/plugin/core/clients.py, version: 5, path: f:\SublimeText\Data\Packages\LSP\plugin\core\clients.py, filename: clients.py, _local: True, _extra_sys_path: [], _rope_project: Project. _address: f:\SublimeText\Data, _ropefolder_name: None, ignored: _ResourceMatcher. patterns: [], file_list: None, prefs: Prefs. {'extension_modules': ['numpy', 'os', 'array', 'audioop', 'binascii', 'cmath', 'collections', 'datetime', 'errno', 'gc', 'imp', 'itertools', 'marshal', 'math', 'mmap', 'msvcrt', 'nt', 'operator', 'parser', 'signal', 'sys', 'time', 'xxsubtype', 'zipimport', 'zlib']}, callbacks: {'ignored_resources': <bound method _ResourceMatcher.set_patterns of <rope.base.resources._ResourceMatcher object at 0x00000208BD610A90>>}
document: Document. uri: file:///F:/SublimeText/Data/Packages/LSP/plugin/core/clients.py, version: 5, path: f:\SublimeText\Data\Packages\LSP\plugin\core\clients.py, filename: clients.py, _local: True, _extra_sys_path: [], _rope_project: Project. _address: f:\SublimeText\Data, _ropefolder_name: None, ignored: _ResourceMatcher. patterns: [], file_list: None, prefs: Prefs. {'extension_modules': ['numpy', 'os', 'array', 'audioop', 'binascii', 'cmath', 'collections', 'datetime', 'errno', 'gc', 'imp', 'itertools', 'marshal', 'math', 'mmap', 'msvcrt', 'nt', 'operator', 'parser', 'signal', 'sys', 'time', 'xxsubtype', 'zipimport', 'zlib']}, callbacks: {'ignored_resources': <bound method _ResourceMatcher.set_patterns of <rope.base.resources._ResourceMatcher object at 0x00000208BD610A90>>}
position: {'line': 48, 'character': 11}
2018-02-04 15:58:37,392 DEBUG parso.python.diff:update:121 diff parser start
2018-02-04 15:58:37,397 DEBUG parso.python.diff:update:132 diff parser calculated
2018-02-04 15:58:37,410 DEBUG parso.python.diff:update:133 diff: line_lengths old: 214, new: 214
2018-02-04 15:58:37,414 DEBUG parso.python.diff:update:137 diff equal old[1:49] new[1:49]
2018-02-04 15:58:37,418 DEBUG parso.python.diff:_copy_from_old_parser:208 diff actually copy 1 to 48
2018-02-04 15:58:37,441 DEBUG parso.python.diff:_parse:257 parse_part from 49 to 51 (to 51 in part parser)
2018-02-04 15:58:37,445 DEBUG parso.python.diff:update:137 diff replace old[50:50] new[50:50]
2018-02-04 15:58:37,447 DEBUG parso.python.diff:update:137 diff equal old[51:214] new[51:214]
2018-02-04 15:58:37,459 DEBUG parso.python.diff:_copy_from_old_parser:208 diff actually copy 52 to 213
2018-02-04 15:58:37,463 DEBUG parso.python.diff:update:166 diff parser end
2018-02-04 15:58:37,874 DEBUG pyls.python_ls:_hook:48 PythonLanguageServer, self.config: Config. _root_path: f:\SublimeText\Data, _root_uri: file:///F:/SublimeText/Data, _init_opts: None, _settings: {'plugins': {'pydocstyle': {'enabled': True, 'ignore': ['D202', 'D208']}, 'rope': {'create_folder': False}, 'pycodestyle': {'enabled': False}}}, _plugin_settings: {'plugins': {'rope_completion': {'enabled': False}, 'pydocstyle': {'enabled': False}}}, _disabled_plugins: [<module 'pyls.plugins.pycodestyle_lint' from 'd:\\user\\dropbox\\softwareversioning\\python-language-server\\pyls\\plugins\\pycodestyle_lint.py'>], _config_sources(flake8): Flake8Config. root_path: f:\SublimeText\Data, is_windows: True, xdg_home: C:\Users\Professional/.config, _modified_times: {}, _config_sources(pycodestyle): PyCodeStyleConfig. root_path: f:\SublimeText\Data, is_windows: True, xdg_home: C:\Users\Professional/.config, _modified_times: {(): ()}, _configs_cache(()): []
2018-02-04 15:58:37,883 DEBUG pyls.config.config:processmessage:137 pyls_lint [hook]
config: Config. _root_path: f:\SublimeText\Data, _root_uri: file:///F:/SublimeText/Data, _init_opts: None, _settings: {'plugins': {'pydocstyle': {'enabled': True, 'ignore': ['D202', 'D208']}, 'rope': {'create_folder': False}, 'pycodestyle': {'enabled': False}}}, _plugin_settings: {'plugins': {'rope_completion': {'enabled': False}, 'pydocstyle': {'enabled': False}}}, _disabled_plugins: [<module 'pyls.plugins.pycodestyle_lint' from 'd:\\user\\dropbox\\softwareversioning\\python-language-server\\pyls\\plugins\\pycodestyle_lint.py'>], _config_sources(flake8): Flake8Config. root_path: f:\SublimeText\Data, is_windows: True, xdg_home: C:\Users\Professional/.config, _modified_times: {}, _config_sources(pycodestyle): PyCodeStyleConfig. root_path: f:\SublimeText\Data, is_windows: True, xdg_home: C:\Users\Professional/.config, _modified_times: {(): ()}, _configs_cache(()): []
workspace: Workspace. _root_path: f:\SublimeText\Data, _root_uri: file:///F:/SublimeText/Data, _root_uri_scheme: file, _lang_server: PythonLanguageServer. config: Config. _root_path: f:\SublimeText\Data, _root_uri: file:///F:/SublimeText/Data, _init_opts: None, _settings: {'plugins': {'pydocstyle': {'enabled': True, 'ignore': ['D202', 'D208']}, 'rope': {'create_folder': False}, 'pycodestyle': {'enabled': False}}}, _plugin_settings: {'plugins': {'rope_completion': {'enabled': False}, 'pydocstyle': {'enabled': False}}}, _disabled_plugins: [<module 'pyls.plugins.pycodestyle_lint' from 'd:\\user\\dropbox\\softwareversioning\\python-language-server\\pyls\\plugins\\pycodestyle_lint.py'>], _config_sources(flake8): Flake8Config. root_path: f:\SublimeText\Data, is_windows: True, xdg_home: C:\Users\Professional/.config, _modified_times: {}, _config_sources(pycodestyle): PyCodeStyleConfig. root_path: f:\SublimeText\Data, is_windows: True, xdg_home: C:\Users\Professional/.config, _modified_times: {(): ()}, _configs_cache(()): [], _dispatchers: [], __rope: Project. _address: f:\SublimeText\Data, _ropefolder_name: None, ignored: _ResourceMatcher. patterns: [], file_list: None, prefs: Prefs. {'extension_modules': ['numpy', 'os', 'array', 'audioop', 'binascii', 'cmath', 'collections', 'datetime', 'errno', 'gc', 'imp', 'itertools', 'marshal', 'math', 'mmap', 'msvcrt', 'nt', 'operator', 'parser', 'signal', 'sys', 'time', 'xxsubtype', 'zipimport', 'zlib']}, callbacks: {'ignored_resources': <bound method _ResourceMatcher.set_patterns of <rope.base.resources._ResourceMatcher object at 0x00000208BD610A90>>}, _docs(file:///F:/SublimeText/Data/Packages/LSP/plugin/core/clients.py): Document. uri: file:///F:/SublimeText/Data/Packages/LSP/plugin/core/clients.py, version: 5, path: f:\SublimeText\Data\Packages\LSP\plugin\core\clients.py, filename: clients.py, _local: True, _extra_sys_path: [], _rope_project: Project. _address: f:\SublimeText\Data, _ropefolder_name: None, ignored: _ResourceMatcher. patterns: [], file_list: None, prefs: Prefs. {'extension_modules': ['numpy', 'os', 'array', 'audioop', 'binascii', 'cmath', 'collections', 'datetime', 'errno', 'gc', 'imp', 'itertools', 'marshal', 'math', 'mmap', 'msvcrt', 'nt', 'operator', 'parser', 'signal', 'sys', 'time', 'xxsubtype', 'zipimport', 'zlib']}, callbacks: {'ignored_resources': <bound method _ResourceMatcher.set_patterns of <rope.base.resources._ResourceMatcher object at 0x00000208BD610A90>>}
document: Document. uri: file:///F:/SublimeText/Data/Packages/LSP/plugin/core/clients.py, version: 5, path: f:\SublimeText\Data\Packages\LSP\plugin\core\clients.py, filename: clients.py, _local: True, _extra_sys_path: [], _rope_project: Project. _address: f:\SublimeText\Data, _ropefolder_name: None, ignored: _ResourceMatcher. patterns: [], file_list: None, prefs: Prefs. {'extension_modules': ['numpy', 'os', 'array', 'audioop', 'binascii', 'cmath', 'collections', 'datetime', 'errno', 'gc', 'imp', 'itertools', 'marshal', 'math', 'mmap', 'msvcrt', 'nt', 'operator', 'parser', 'signal', 'sys', 'time', 'xxsubtype', 'zipimport', 'zlib']}, callbacks: {'ignored_resources': <bound method _ResourceMatcher.set_patterns of <rope.base.resources._ResourceMatcher object at 0x00000208BD610A90>>}
2018-02-04 15:58:38,271 DEBUG pyls.config.config:processmessage:137 finish pyls_hover --> [hook]
contents:
2018-02-04 15:58:38,375 DEBUG pyls.plugins.pydocstyle_lint:pyls_lint:46 Got pydocstyle errors: [{'source': 'pydocstyle', 'code': 'D100', 'message': 'D100: Missing docstring in public module', 'severity': 2, 'range': {'start': {'line': 0, 'character': 0}, 'end': {'line': 0, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D101', 'message': 'D101: Missing docstring in public class', 'severity': 2, 'range': {'start': {'line': 25, 'character': 0}, 'end': {'line': 25, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D101', 'message': 'D101: Missing docstring in public class', 'severity': 2, 'range': {'start': {'line': 31, 'character': 0}, 'end': {'line': 31, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D107', 'message': 'D107: Missing docstring in __init__', 'severity': 2, 'range': {'start': {'line': 33, 'character': 0}, 'end': {'line': 33, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D101', 'message': 'D101: Missing docstring in public class', 'severity': 2, 'range': {'start': {'line': 38, 'character': 0}, 'end': {'line': 38, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D107', 'message': 'D107: Missing docstring in __init__', 'severity': 2, 'range': {'start': {'line': 39, 'character': 0}, 'end': {'line': 39, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D102', 'message': 'D102: Missing docstring in public method', 'severity': 2, 'range': {'start': {'line': 43, 'character': 0}, 'end': {'line': 43, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D102', 'message': 'D102: Missing docstring in public method', 'severity': 2, 'range': {'start': {'line': 46, 'character': 0}, 'end': {'line': 46, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 53, 'character': 0}, 'end': {'line': 53, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 61, 'character': 0}, 'end': {'line': 61, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 75, 'character': 0}, 'end': {'line': 75, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 79, 'character': 0}, 'end': {'line': 79, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 83, 'character': 0}, 'end': {'line': 83, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 88, 'character': 0}, 'end': {'line': 88, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 93, 'character': 0}, 'end': {'line': 93, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 97, 'character': 0}, 'end': {'line': 97, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 101, 'character': 0}, 'end': {'line': 101, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 132, 'character': 0}, 'end': {'line': 132, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 136, 'character': 0}, 'end': {'line': 136, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 151, 'character': 0}, 'end': {'line': 151, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 165, 'character': 0}, 'end': {'line': 165, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 174, 'character': 0}, 'end': {'line': 174, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 192, 'character': 0}, 'end': {'line': 192, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 197, 'character': 0}, 'end': {'line': 197, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 211, 'character': 0}, 'end': {'line': 211, 'character': 15}}}]
2018-02-04 15:58:38,381 DEBUG pyls.config.source:read_config_from_files:52 Using cached configuration for ()
2018-02-04 15:58:38,409 DEBUG pyls.config.config:settings:87 Got user config from PyCodeStyleConfig: {}
2018-02-04 15:58:38,412 DEBUG pyls.config.config:settings:89 With user configuration: {}
2018-02-04 15:58:38,423 DEBUG pyls.config.config:settings:92 With plugin configuration: {'plugins': {'rope_completion': {'enabled': False}, 'pydocstyle': {'enabled': False}}}
2018-02-04 15:58:38,427 DEBUG pyls.config.config:settings:95 With lsp configuration: {'plugins': {'rope': {'create_folder': False}, 'rope_completion': {'enabled': False}, 'pycodestyle': {'enabled': False}, 'pydocstyle': {'ignore': ['D202', 'D208'], 'enabled': True}}}
2018-02-04 15:58:38,440 DEBUG pyls.config.source:read_config_from_files:52 Using cached configuration for ()
2018-02-04 15:58:38,447 DEBUG pyls.config.config:settings:100 Got project config from PyCodeStyleConfig: {}
2018-02-04 15:58:38,460 DEBUG pyls.config.config:settings:102 With project configuration: {'plugins': {'rope': {'create_folder': False}, 'rope_completion': {'enabled': False}, 'pycodestyle': {'enabled': False}, 'pydocstyle': {'ignore': ['D202', 'D208'], 'enabled': True}}}
2018-02-04 15:58:38,466 DEBUG pyls.plugins.mccabe_lint:pyls_lint:16 Running mccabe lint with threshold: 15
2018-02-04 15:58:38,508 DEBUG pyls.config.config:processmessage:137 finish pyls_lint --> [[{'source': 'pyflakes', 'range': {'start': {'line': 49, 'character': 19}, 'end': {'line': 49, 'character': 22}}, 'message': "undefined name 'tr'", 'severity': 2}], [{'source': 'pydocstyle', 'code': 'D100', 'message': 'D100: Missing docstring in public module', 'severity': 2, 'range': {'start': {'line': 0, 'character': 0}, 'end': {'line': 0, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D101', 'message': 'D101: Missing docstring in public class', 'severity': 2, 'range': {'start': {'line': 25, 'character': 0}, 'end': {'line': 25, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D101', 'message': 'D101: Missing docstring in public class', 'severity': 2, 'range': {'start': {'line': 31, 'character': 0}, 'end': {'line': 31, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D107', 'message': 'D107: Missing docstring in __init__', 'severity': 2, 'range': {'start': {'line': 33, 'character': 0}, 'end': {'line': 33, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D101', 'message': 'D101: Missing docstring in public class', 'severity': 2, 'range': {'start': {'line': 38, 'character': 0}, 'end': {'line': 38, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D107', 'message': 'D107: Missing docstring in __init__', 'severity': 2, 'range': {'start': {'line': 39, 'character': 0}, 'end': {'line': 39, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D102', 'message': 'D102: Missing docstring in public method', 'severity': 2, 'range': {'start': {'line': 43, 'character': 0}, 'end': {'line': 43, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D102', 'message': 'D102: Missing docstring in public method', 'severity': 2, 'range': {'start': {'line': 46, 'character': 0}, 'end': {'line': 46, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 53, 'character': 0}, 'end': {'line': 53, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 61, 'character': 0}, 'end': {'line': 61, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 75, 'character': 0}, 'end': {'line': 75, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 79, 'character': 0}, 'end': {'line': 79, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 83, 'character': 0}, 'end': {'line': 83, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 88, 'character': 0}, 'end': {'line': 88, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 93, 'character': 0}, 'end': {'line': 93, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 97, 'character': 0}, 'end': {'line': 97, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 101, 'character': 0}, 'end': {'line': 101, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 132, 'character': 0}, 'end': {'line': 132, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 136, 'character': 0}, 'end': {'line': 136, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 151, 'character': 0}, 'end': {'line': 151, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 165, 'character': 0}, 'end': {'line': 165, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 174, 'character': 0}, 'end': {'line': 174, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 192, 'character': 0}, 'end': {'line': 192, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 197, 'character': 0}, 'end': {'line': 197, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 211, 'character': 0}, 'end': {'line': 211, 'character': 15}}}], []] [hook]
2018-02-04 15:58:38,512 DEBUG pyls.server:notify:81 Sending notification textDocument/publishDiagnostics: {'uri': 'file:///F:/SublimeText/Data/Packages/LSP/plugin/core/clients.py', 'diagnostics': [{'source': 'pyflakes', 'range': {'start': {'line': 49, 'character': 19}, 'end': {'line': 49, 'character': 22}}, 'message': "undefined name 'tr'", 'severity': 2}, {'source': 'pydocstyle', 'code': 'D100', 'message': 'D100: Missing docstring in public module', 'severity': 2, 'range': {'start': {'line': 0, 'character': 0}, 'end': {'line': 0, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D101', 'message': 'D101: Missing docstring in public class', 'severity': 2, 'range': {'start': {'line': 25, 'character': 0}, 'end': {'line': 25, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D101', 'message': 'D101: Missing docstring in public class', 'severity': 2, 'range': {'start': {'line': 31, 'character': 0}, 'end': {'line': 31, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D107', 'message': 'D107: Missing docstring in __init__', 'severity': 2, 'range': {'start': {'line': 33, 'character': 0}, 'end': {'line': 33, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D101', 'message': 'D101: Missing docstring in public class', 'severity': 2, 'range': {'start': {'line': 38, 'character': 0}, 'end': {'line': 38, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D107', 'message': 'D107: Missing docstring in __init__', 'severity': 2, 'range': {'start': {'line': 39, 'character': 0}, 'end': {'line': 39, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D102', 'message': 'D102: Missing docstring in public method', 'severity': 2, 'range': {'start': {'line': 43, 'character': 0}, 'end': {'line': 43, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D102', 'message': 'D102: Missing docstring in public method', 'severity': 2, 'range': {'start': {'line': 46, 'character': 0}, 'end': {'line': 46, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 53, 'character': 0}, 'end': {'line': 53, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 61, 'character': 0}, 'end': {'line': 61, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 75, 'character': 0}, 'end': {'line': 75, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 79, 'character': 0}, 'end': {'line': 79, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 83, 'character': 0}, 'end': {'line': 83, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 88, 'character': 0}, 'end': {'line': 88, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 93, 'character': 0}, 'end': {'line': 93, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 97, 'character': 0}, 'end': {'line': 97, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 101, 'character': 0}, 'end': {'line': 101, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 132, 'character': 0}, 'end': {'line': 132, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 136, 'character': 0}, 'end': {'line': 136, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 151, 'character': 0}, 'end': {'line': 151, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 165, 'character': 0}, 'end': {'line': 165, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 174, 'character': 0}, 'end': {'line': 174, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 192, 'character': 0}, 'end': {'line': 192, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 197, 'character': 0}, 'end': {'line': 197, 'character': 15}}}, {'source': 'pydocstyle', 'code': 'D103', 'message': 'D103: Missing docstring in public function', 'severity': 2, 'range': {'start': {'line': 211, 'character': 0}, 'end': {'line': 211, 'character': 15}}}]}
Reacted by Boris Feld and ayang
Metadata
Metadata
Assignees
Labels
No labels
Activity
[-]Took 2 minutes to respond to on_hover()[/-][+]Took 2 minutes to respond to on_hover(), from 15:56:14 until 15:58:38[/+]ferozco commentedon Feb 22, 2018
@evandrocoan are you still seeing this issue?
evandrocoan commentedon Feb 22, 2018
Yes. But now it is so frequently that I just kill the language server process and do not start it anymore. I cannot have my work stopping randomly and frequently for such long periods.
In my opinion the worst part of this issue is the LSP plugin for Sublime Text completely freeze the Sublime Text Graphical User Interface (other times not the User Interface but all Sublime Text Async Tasks running in the background) until the language server respond.
ferozco commentedon Feb 22, 2018
i'm sorry to hear that! I think theres two problems to address here.
Blocking behaviour in pyls: We can solve this somewhat easily by augmenting the hover endpoint to support async callbacks and by changing https://github.com/palantir/python-language-server/blob/develop/pyls/plugins/hover.py#L9 to be an async handler
Blocking behaviour in Sublime: Need to get the client to support asynchronous, out of order delivery of responses. I don't know the solution to that. Honestly, this hinders any performance improvements you would see from async pyls and it might make it worse in some cases
What are your thoughts? Would you be interested in tackling either of those?
evandrocoan commentedon Feb 23, 2018
My first though would be to understand:
why pyls would take so long to respond to a request?I do not think it is a big problem taking long as 2 minutes to answer a request, as long as
pylsis performing useful work, instead of being locked in some kind ofwhile Trueperforming nothing useful.My first approach to solve this will be updating my fork of LSP to time out the requests after something like
0.1seconds, perhaps0.3seconds. Just because it is unacceptable to block my work because something could go wrong or take a big time. Ifpylsor any other language server do not respond after this timeout, consider the answer as not found or inexistente.After solving this on the LSP plugin, I would dig in into what the
pylsis doing and taking so long.I am not sure about what are the implications of an async hover call backs. How would they respond accordingly to the time out I am implementing on the LSP plugin? If I understand correctly, currently
pylswill not accept any otherhovercalls until the first one have been answered. This have some fallbacks on the LSP timeout because:pylsserver respond, the answer will be invalid and rejected by LSP due the timeout.pylsis accepting async hover calls, LSP can start doing several hover requests and:i. If each one of these requests take 2 minutes long.
ii. Or if several of these requests are the same request and take 2 minutes long.
All requests are going to be invalid due the LSP timeout of
0.3, and they will exhaust the server CPU by creating several different threads into doing the same thing. Or by just by doing discarded work by the LSP plugin timeout of0.3.However, it can be actually required by the
pylsserver to take 2 minutes long to process the first hover request. Therefore, we cannot implement async hover request because this will only cause the LSP plugin into creating several hovers requests, which will take 2 minutes long, i.e., several thread eating my computer CPU doing the same thing.This is very similar to this problem on the
languagetoolserver:I would suggest to not implement async hover requests, before investigate what is causing or can cause to a request take so long to be finished. After learning this, we can correctly think about a implementation strategy to correctly create async hover requests, without:
0.3seconds.0.3seconds.Hence, if the server implements async hover requests:
0.3seconds. Unless the server need to do some extra job before, like caching the hover results. Then, only then the server can continue working.The solution to this, is to implement async requests on the LSP plugin. But first, fix it blocking the Sublime Text interface. Adding support to async requests is also on the way of fixing LSP. If the LSP plugin is doing and receiving async requests, it should be able to not block Sublime Text until some request being completed after they being created.
Even with an async LSP plugin, there will be still existing discarded requests after the time out. For example, the LSP plugin does the request A, and do not wait for its answer, it starts doing other stuff. Then when the requests A timeout comes, and the request A have not yet being fulfilled, then it considers it invalid or not found and display to the user this result.
ferozco commentedon Mar 14, 2018
Hey sorry for the slow response!
With regards to the LSP changes: As a quick fix to get things running it seems reasonable. But as a long term solution I don't think the approach is correct. Clients should not
droprequests. The approach I would recommend is to do something similar to what I did for pyls and make the message handling async. This would make the client robust to slow networks and misbehaving servers. I'm not familiar with the implementation of LSP, but in an async world you could enforce your timeout through the use of cancel messages,pyls hover: Sure, perhaps making it async isn't a complete solution to your problem but I do think that it is the correct thing to do long term. Since a client can cancel a hover request we are basically using users patience as an upper bound on computation time. Furthermore, it adds overall responsiveness to the server. Also important to note, the async requests may operate on multiple
threadswithin the python interpreter but the entire language server will only execute on a single OS level thread.gatesn commentedon Mar 25, 2018
@evandrocoan can you paste the output of
pip list? I've seen similar slow behaviour when using jedi-vim (not pyls) when importing large modules. Albeit never as long as 2 minutes.I agree that async might not be the correct answer here, as we'll very quickly just end up starving the executor pool and blocking all requests! Let's try and find the root cause.
Would be happy to add some log lines into the hover provider to help with timings.
evandrocoan commentedon Mar 25, 2018
My computer is like 5 times slower than the usual, then we could recude these 2 minutes to 24 seconds on today's machines.
Details
But my
pylshas a large data base beyond these default modules, because I include on it all my Sublime Text packages which are about 200Details