From 0fabb7d5d61037581efaa17eec3c584990e64a9b Mon Sep 17 00:00:00 2001 From: jwortmann Date: Sat, 20 Apr 2024 19:59:30 +0200 Subject: [PATCH] Use variable annotations instead of type comments on Python 3.8 (#2450) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * "Add .python-version file" * remove pathlib from dependencies * change import * Revert "change import" (: This reverts commit c70cd57055ddeb8ca0b4ff36acb8531dd81a6e07. * Fix failing unittests on MacOS (#2436) This commit adopts `unittesting.ViewTestCase` to run view related test cases. ViewTestCase ... 1. provides `view` and `window` members pointing to a dedicated view, being created for testing. 2. ensures not to close empty windows, which was probably the most likely reason for unittests failing before on MacOS. * keep the same order as before * rchlint * add release notes * tweak release message * Be more descriptive of what the user expect, or what the user can do if things go wrong * tweak words * Use variable annotations instead of type comments --------- Co-authored-by: Предраг Николић Co-authored-by: Rafal Chlodnicki Co-authored-by: deathaxe Co-authored-by: Raoul Wols --- boot.py | 2 +- plugin/code_actions.py | 22 +++--- plugin/code_lens.py | 8 +-- plugin/color.py | 6 +- plugin/completion.py | 20 +++--- plugin/core/active_request.py | 2 +- plugin/core/collections.py | 6 +- plugin/core/configurations.py | 8 +-- plugin/core/constants.py | 28 ++++---- plugin/core/css.py | 2 +- plugin/core/diagnostics_storage.py | 2 +- plugin/core/edit.py | 2 +- plugin/core/file_watcher.py | 4 +- plugin/core/input_handlers.py | 4 +- plugin/core/message_request_handler.py | 8 +-- plugin/core/open.py | 4 +- plugin/core/panels.py | 2 +- plugin/core/progress.py | 4 +- plugin/core/promise.py | 6 +- plugin/core/protocol.py | 2 +- plugin/core/registry.py | 2 +- plugin/core/sessions.py | 96 +++++++++++++------------- plugin/core/settings.py | 14 ++-- plugin/core/signature_help.py | 6 +- plugin/core/transports.py | 10 +-- plugin/core/tree_view.py | 8 +-- plugin/core/types.py | 24 +++---- plugin/core/views.py | 28 ++++---- plugin/core/windows.py | 47 ++++++------- plugin/core/workspace.py | 8 +-- plugin/diagnostics.py | 2 +- plugin/documents.py | 56 +++++++-------- plugin/edit.py | 2 +- plugin/execute_command.py | 4 +- plugin/folding_range.py | 10 +-- plugin/formatting.py | 2 +- plugin/goto_diagnostic.py | 12 ++-- plugin/hover.py | 28 ++++---- plugin/locationpicker.py | 2 +- plugin/references.py | 4 +- plugin/rename.py | 8 +-- plugin/save_command.py | 6 +- plugin/selection_range.py | 2 +- plugin/session_buffer.py | 38 +++++----- plugin/session_view.py | 16 ++--- plugin/symbols.py | 14 ++-- plugin/tooling.py | 16 ++--- tests/server.py | 4 +- tests/test_code_actions.py | 6 +- tests/test_completion.py | 48 ++++++------- tests/test_edit.py | 38 +++++----- tests/test_file_watcher.py | 2 +- tests/test_mocks.py | 2 +- tests/test_protocol.py | 6 +- tests/test_server_notifications.py | 4 +- tests/test_types.py | 2 +- tests/test_views.py | 8 +-- 57 files changed, 363 insertions(+), 364 deletions(-) diff --git a/boot.py b/boot.py index e86454de7..65baf6f42 100644 --- a/boot.py +++ b/boot.py @@ -98,7 +98,7 @@ def _get_final_subclasses(derived: List[Type], results: List[Type]) -> None: def _register_all_plugins() -> None: - plugin_classes = [] # type: List[Type[AbstractPlugin]] + plugin_classes: List[Type[AbstractPlugin]] = [] _get_final_subclasses(AbstractPlugin.__subclasses__(), plugin_classes) for plugin_class in plugin_classes: try: diff --git a/plugin/code_actions.py b/plugin/code_actions.py index 2bd13d7db..ad9b96649 100644 --- a/plugin/code_actions.py +++ b/plugin/code_actions.py @@ -37,10 +37,10 @@ class CodeActionsManager: """Manager for per-location caching of code action responses.""" def __init__(self) -> None: - self._response_cache = None # type: Optional[Tuple[str, Promise[List[CodeActionsByConfigName]]]] - self.menu_actions_cache_key = None # type: Optional[str] - self.refactor_actions_cache = [] # type: List[Tuple[str, CodeAction]] - self.source_actions_cache = [] # type: List[Tuple[str, CodeAction]] + self._response_cache: Optional[Tuple[str, Promise[List[CodeActionsByConfigName]]]] = None + self.menu_actions_cache_key: Optional[str] = None + self.refactor_actions_cache: List[Tuple[str, CodeAction]] = [] + self.source_actions_cache: List[Tuple[str, CodeAction]] = [] def request_for_region_async( self, @@ -74,7 +74,7 @@ def request_for_region_async( self.source_actions_cache.clear() def request_factory(sb: SessionBufferProtocol) -> Optional[Request]: - diagnostics = [] # type: List[Diagnostic] + diagnostics: List[Diagnostic] = [] for diag_sb, diags in session_buffer_diagnostics: if diag_sb == sb: diagnostics = diags @@ -122,7 +122,7 @@ def request_factory(sb: SessionBufferProtocol) -> Optional[Request]: matching_kinds = get_matching_on_save_kinds(on_save_actions, session_kinds) if not matching_kinds: return None - diagnostics = [] # type: List[Diagnostic] + diagnostics: List[Diagnostic] = [] for diag_sb, diags in session_buffer_diagnostics: if diag_sb == sb: diagnostics = diags @@ -155,13 +155,13 @@ def on_response( actions = response_filter(sb, response) return (sb.session.config.name, actions) - tasks = [] # type: List[Promise[CodeActionsByConfigName]] + tasks: List[Promise[CodeActionsByConfigName]] = [] for sb in listener.session_buffers_async('codeActionProvider'): session = sb.session request = request_factory(sb) if request: response_handler = partial(on_response, sb) - task = session.send_request_task(request) # type: Promise[Optional[List[CodeActionOrCommand]]] + task: Promise[Optional[List[CodeActionOrCommand]]] = session.send_request_task(request) tasks.append(task.then(response_handler)) # Return only results for non-empty lists. return Promise.all(tasks) \ @@ -172,7 +172,7 @@ def on_response( def get_session_kinds(sb: SessionBufferProtocol) -> List[CodeActionKind]: - session_kinds = sb.get_capability('codeActionProvider.codeActionKinds') # type: Optional[List[CodeActionKind]] + session_kinds: Optional[List[CodeActionKind]] = sb.get_capability('codeActionProvider.codeActionKinds') return session_kinds or [] @@ -254,7 +254,7 @@ def _handle_response_async(self, responses: List[CodeActionsByConfigName]) -> No if self._cancelled: return view = self._task_runner.view - tasks = [] # type: List[Promise] + tasks: List[Promise] = [] for config_name, code_actions in responses: session = self._task_runner.session_by_name(config_name, 'codeActionProvider') if session: @@ -308,7 +308,7 @@ def _run_async(self, only_kinds: Optional[List[CodeActionKind]] = None) -> None: def _handle_code_actions(self, response: List[CodeActionsByConfigName], run_first: bool = False) -> None: # Flatten response to a list of (config_name, code_action) tuples. - actions = [] # type: List[Tuple[ConfigName, CodeActionOrCommand]] + actions: List[Tuple[ConfigName, CodeActionOrCommand]] = [] for config_name, session_actions in response: actions.extend([(config_name, action) for action in session_actions]) if actions: diff --git a/plugin/code_lens.py b/plugin/code_lens.py index af006b299..cd6ccef78 100644 --- a/plugin/code_lens.py +++ b/plugin/code_lens.py @@ -108,7 +108,7 @@ def __init__(self, view: sublime.View) -> None: self.view = view self._init = False self._phantom = sublime.PhantomSet(view, self.CODE_LENS_KEY) - self._code_lenses = {} # type: Dict[Tuple[int, int], List[CodeLensData]] + self._code_lenses: Dict[Tuple[int, int], List[CodeLensData]] = {} def clear(self) -> None: self._code_lenses.clear() @@ -134,10 +134,10 @@ def handle_response(self, session_name: str, response: List[CodeLens]) -> None: self._init = True responses = [CodeLensData(data, self.view, session_name) for data in response] responses.sort(key=lambda c: c.region) - result = { + result: Dict[Tuple[int, int], List[CodeLensData]] = { region.to_tuple(): list(groups) for region, groups in itertools.groupby(responses, key=lambda c: c.region) - } # type: Dict[Tuple[int, int], List[CodeLensData]] + } # Fast path: no extra work to do if self.is_empty(): @@ -215,7 +215,7 @@ def run(self, edit: sublime.Edit) -> None: listener = windows.listener_for_view(self.view) if not listener: return - code_lenses = [] # type: List[CodeLensExtended] + code_lenses: List[CodeLensExtended] = [] for region in self.view.sel(): for sv in listener.session_views_async(): code_lenses.extend(sv.get_resolved_code_lenses_for_region(region)) diff --git a/plugin/color.py b/plugin/color.py index c629c01df..88d964cef 100644 --- a/plugin/color.py +++ b/plugin/color.py @@ -19,11 +19,11 @@ def run(self, edit: sublime.Edit, color_information: ColorInformation) -> None: if session: self._version = self.view.change_count() self._range = color_information['range'] - params = { + params: ColorPresentationParams = { 'textDocument': text_document_identifier(self.view), 'color': color_information['color'], 'range': self._range - } # type: ColorPresentationParams + } session.send_request_async(Request.colorPresentation(params, self.view), self._handle_response_async) def want_event(self) -> bool: @@ -38,7 +38,7 @@ def _handle_response_async(self, response: List[ColorPresentation]) -> None: if self._version != self.view.change_count(): return old_text = self.view.substr(range_to_region(self._range, self.view)) - self._filtered_response = [] # type: List[ColorPresentation] + self._filtered_response: List[ColorPresentation] = [] for item in response: # Filter out items that would apply no change text_edit = item.get('textEdit') diff --git a/plugin/completion.py b/plugin/completion.py index 77d919d41..4e8825bfb 100644 --- a/plugin/completion.py +++ b/plugin/completion.py @@ -56,7 +56,7 @@ def format_completion( lsp_detail = (item.get('detail') or "").replace("\n", " ") completion_kind = item.get('kind') kind = COMPLETION_KINDS.get(completion_kind, sublime.KIND_AMBIGUOUS) if completion_kind else sublime.KIND_AMBIGUOUS - details = [] # type: List[str] + details: List[str] = [] if can_resolve_completion_items or item.get('documentation'): # Not using "make_command_link" in a hot path to avoid slow json.dumps. args = '{{"view_id":{},"command":"lsp_resolve_docs","args":{{"index":{},"session_name":"{}"}}}}'.format( @@ -132,7 +132,7 @@ def completion_with_defaults(item: CompletionItem, item_defaults: CompletionItem """ Currently supports defaults for: ["editRange", "insertTextFormat", "data"] """ if not item_defaults: return item - default_text_edit = None # type: Optional[Union[TextEdit, InsertReplaceEdit]] + default_text_edit: Optional[Union[TextEdit, InsertReplaceEdit]] = None edit_range = item_defaults.get('editRange') if edit_range: # If textEditText is not provided and a list's default range is provided @@ -182,7 +182,7 @@ def __init__( self._triggered_manually = triggered_manually self._on_done_async = on_done_async self._resolved = False - self._pending_completion_requests = {} # type: Dict[int, weakref.ref[Session]] + self._pending_completion_requests: Dict[int, weakref.ref[Session]] = {} def query_completions_async(self, sessions: List[Session]) -> None: promises = [self._create_completion_request_async(session) for session in sessions] @@ -206,10 +206,10 @@ def _resolve_completions_async(self, responses: List[ResolvedCompletions]) -> No if self._resolved: return LspSelectCompletionCommand.completions = {} - items = [] # type: List[sublime.CompletionItem] - item_defaults = {} # type: CompletionItemDefaults - errors = [] # type: List[Error] - flags = 0 # int + items: List[sublime.CompletionItem] = [] + item_defaults: CompletionItemDefaults = {} + errors: List[Error] = [] + flags = 0 prefs = userprefs() if prefs.inhibit_snippet_completions: flags |= sublime.INHIBIT_EXPLICIT_COMPLETIONS @@ -225,7 +225,7 @@ def _resolve_completions_async(self, responses: List[ResolvedCompletions]) -> No session = weak_session() if not session: continue - response_items = [] # type: List[CompletionItem] + response_items: List[CompletionItem] = [] if isinstance(response, dict): response_items = response["items"] or [] item_defaults = response.get('itemDefaults') or {} @@ -291,7 +291,7 @@ def _handle_resolve_response_async(self, language_map: Optional[MarkdownLangMap] detail = self._format_documentation(item.get('detail') or "", language_map) documentation = self._format_documentation(item.get("documentation") or "", language_map) if not documentation: - markdown = {"kind": MarkupKind.Markdown, "value": "*No documentation available.*"} # type: MarkupContent + markdown: MarkupContent = {"kind": MarkupKind.Markdown, "value": "*No documentation available.*"} # No need for a language map here documentation = self._format_documentation(markdown, None) minihtml_content = "" @@ -337,7 +337,7 @@ def run(self, edit: sublime.Edit, event: Optional[dict] = None) -> None: class LspSelectCompletionCommand(LspTextCommand): - completions = {} # type: Dict[SessionName, CompletionsStore] + completions: Dict[SessionName, CompletionsStore] = {} def run(self, edit: sublime.Edit, index: int, session_name: str) -> None: items, item_defaults = LspSelectCompletionCommand.completions[session_name] diff --git a/plugin/core/active_request.py b/plugin/core/active_request.py index bdd39c9e7..af56c0ac9 100644 --- a/plugin/core/active_request.py +++ b/plugin/core/active_request.py @@ -18,7 +18,7 @@ def __init__(self, sv: SessionViewProtocol, request_id: int, request: Request) - self.weaksv = ref(sv) self.request_id = request_id self.request = request - self.progress = None # type: Optional[ProgressReporter] + self.progress: Optional[ProgressReporter] = None # `request.progress` is either a boolean or a string. If it's a boolean, then that signals that the server does # not support client-initiated progress. However, for some requests we still want to notify some kind of # progress to the end-user. This is communicated by the boolean value being "True". diff --git a/plugin/core/collections.py b/plugin/core/collections.py index 3e6c4b41e..c3b2ebca1 100644 --- a/plugin/core/collections.py +++ b/plugin/core/collections.py @@ -16,7 +16,7 @@ def __init__(self, d: Optional[Dict[str, Any]] = None) -> None: :param d: An existing dictionary. """ - self._d = {} # type: Dict[str, Any] + self._d: Dict[str, Any] = {} if d is not None: self.update(d) @@ -40,7 +40,7 @@ def get(self, path: Optional[str] = None) -> Any: """ if path is None: return self._d - current = self._d # type: Any + current: Any = self._d keys = path.split('.') for key in keys: if isinstance(current, dict): @@ -50,7 +50,7 @@ def get(self, path: Optional[str] = None) -> Any: return current def walk(self, path: str) -> Generator[Any, None, None]: - current = self._d # type: Any + current: Any = self._d keys = path.split('.') for key in keys: if isinstance(current, dict): diff --git a/plugin/core/configurations.py b/plugin/core/configurations.py index 1232de31b..d8e2dc929 100644 --- a/plugin/core/configurations.py +++ b/plugin/core/configurations.py @@ -28,10 +28,10 @@ class WindowConfigManager(object): def __init__(self, window: sublime.Window, global_configs: Dict[str, ClientConfig]) -> None: self._window = window self._global_configs = global_configs - self._disabled_for_session = set() # type: Set[str] - self._crashes = {} # type: Dict[str, Deque[datetime]] - self.all = {} # type: Dict[str, ClientConfig] - self._change_listeners = WeakSet() # type: WeakSet[WindowConfigChangeListener] + self._disabled_for_session: Set[str] = set() + self._crashes: Dict[str, Deque[datetime]] = {} + self.all: Dict[str, ClientConfig] = {} + self._change_listeners: WeakSet[WindowConfigChangeListener] = WeakSet() self._reload_configs(notify_listeners=False) def add_change_listener(self, listener: WindowConfigChangeListener) -> None: diff --git a/plugin/core/constants.py b/plugin/core/constants.py index e8a84f34e..c60fae826 100644 --- a/plugin/core/constants.py +++ b/plugin/core/constants.py @@ -71,7 +71,7 @@ KIND_REFACTOR = (sublime.KIND_ID_COLOR_CYANISH, "r", "Refactor") KIND_SOURCE = (sublime.KIND_ID_COLOR_PURPLISH, "s", "Source") -COMPLETION_KINDS = { +COMPLETION_KINDS: Dict[CompletionItemKind, SublimeKind] = { CompletionItemKind.Text: KIND_TEXT, CompletionItemKind.Method: KIND_METHOD, CompletionItemKind.Function: KIND_FUNCTION, @@ -97,9 +97,9 @@ CompletionItemKind.Event: KIND_EVENT, CompletionItemKind.Operator: KIND_OPERATOR, CompletionItemKind.TypeParameter: KIND_TYPEPARAMETER -} # type: Dict[CompletionItemKind, SublimeKind] +} -SYMBOL_KINDS = { +SYMBOL_KINDS: Dict[SymbolKind, SublimeKind] = { SymbolKind.File: KIND_FILE, SymbolKind.Module: KIND_MODULE, SymbolKind.Namespace: KIND_NAMESPACE, @@ -126,31 +126,31 @@ SymbolKind.Event: KIND_EVENT, SymbolKind.Operator: KIND_OPERATOR, SymbolKind.TypeParameter: KIND_TYPEPARAMETER -} # type: Dict[SymbolKind, SublimeKind] +} -DIAGNOSTIC_KINDS = { +DIAGNOSTIC_KINDS: Dict[DiagnosticSeverity, SublimeKind] = { DiagnosticSeverity.Error: KIND_ERROR, DiagnosticSeverity.Warning: KIND_WARNING, DiagnosticSeverity.Information: KIND_INFORMATION, DiagnosticSeverity.Hint: KIND_HINT -} # type: Dict[DiagnosticSeverity, SublimeKind] +} -CODE_ACTION_KINDS = { +CODE_ACTION_KINDS: Dict[CodeActionKind, SublimeKind] = { CodeActionKind.QuickFix: KIND_QUICKFIX, CodeActionKind.Refactor: KIND_REFACTOR, CodeActionKind.Source: KIND_SOURCE -} # type: Dict[CodeActionKind, SublimeKind] +} -DOCUMENT_HIGHLIGHT_KIND_NAMES = { +DOCUMENT_HIGHLIGHT_KIND_NAMES: Dict[DocumentHighlightKind, str] = { DocumentHighlightKind.Text: "text", DocumentHighlightKind.Read: "read", DocumentHighlightKind.Write: "write" -} # type: Dict[DocumentHighlightKind, str] +} # Symbol scope to kind mapping, based on https://github.com/sublimetext-io/docs.sublimetext.io/issues/30 -SUBLIME_KIND_SCOPES = { +SUBLIME_KIND_SCOPES: Dict[SublimeKind, str] = { sublime.KIND_KEYWORD: "keyword | storage.modifier | storage.type | keyword.declaration | variable.language | constant.language", # noqa: E501 sublime.KIND_TYPE: "entity.name.type | entity.name.class | entity.name.enum | entity.name.trait | entity.name.struct | entity.name.impl | entity.name.interface | entity.name.union | support.type | support.class", # noqa: E501 sublime.KIND_FUNCTION: "entity.name.function | entity.name.method | entity.name.macro | meta.method entity.name.function | support.function | meta.function-call variable.function | meta.function-call support.function | support.method | meta.method-call variable.function", # noqa: E501 @@ -158,13 +158,13 @@ sublime.KIND_NAVIGATION: "entity.name.definition | entity.name.label | entity.name.section", sublime.KIND_MARKUP: "entity.other.attribute-name | entity.name.tag | meta.toc-list.id.html", sublime.KIND_VARIABLE: "entity.name.constant | constant.other | support.constant | variable.other | variable.parameter | variable.other.member | variable.other.readwrite.member" # noqa: E501 -} # type: Dict[SublimeKind, str] +} -DOCUMENT_HIGHLIGHT_KIND_SCOPES = { +DOCUMENT_HIGHLIGHT_KIND_SCOPES: Dict[DocumentHighlightKind, str] = { DocumentHighlightKind.Text: "region.bluish markup.highlight.text.lsp", DocumentHighlightKind.Read: "region.greenish markup.highlight.read.lsp", DocumentHighlightKind.Write: "region.yellowish markup.highlight.write.lsp" -} # type: Dict[DocumentHighlightKind, str] +} SEMANTIC_TOKENS_MAP = { "namespace": "variable.other.namespace.lsp", diff --git a/plugin/core/css.py b/plugin/core/css.py index 737f05d9a..737804e11 100644 --- a/plugin/core/css.py +++ b/plugin/core/css.py @@ -15,7 +15,7 @@ def __init__(self) -> None: self.annotations_classname = "lsp_annotation" -_css = None # type: Optional[CSS] +_css: Optional[CSS] = None def load() -> None: diff --git a/plugin/core/diagnostics_storage.py b/plugin/core/diagnostics_storage.py index 776f8937d..fe5c602bd 100644 --- a/plugin/core/diagnostics_storage.py +++ b/plugin/core/diagnostics_storage.py @@ -45,7 +45,7 @@ def filter_map_diagnostics_async( not more than once. Items and results are ordered as they came in from the server. """ for uri, diagnostics in self.items(): - results = list(filter(None, map(functools.partial(f, uri), filter(pred, diagnostics)))) # type: List[T] + results: List[T] = list(filter(None, map(functools.partial(f, uri), filter(pred, diagnostics)))) if results: yield uri, results diff --git a/plugin/core/edit.py b/plugin/core/edit.py index 48e509dfa..92a6bcf57 100644 --- a/plugin/core/edit.py +++ b/plugin/core/edit.py @@ -11,7 +11,7 @@ def parse_workspace_edit(workspace_edit: WorkspaceEdit) -> WorkspaceChanges: - changes = {} # type: WorkspaceChanges + changes: WorkspaceChanges = {} document_changes = workspace_edit.get('documentChanges') if isinstance(document_changes, list): for document_change in document_changes: diff --git a/plugin/core/file_watcher.py b/plugin/core/file_watcher.py index f4fa103a4..840db8bbf 100644 --- a/plugin/core/file_watcher.py +++ b/plugin/core/file_watcher.py @@ -12,7 +12,7 @@ def lsp_watch_kind_to_file_watcher_event_types(kind: WatchKind) -> List[FileWatcherEventType]: - event_types = [] # type: List[FileWatcherEventType] + event_types: List[FileWatcherEventType] = [] if kind & WatchKind.Create: event_types.append('create') if kind & WatchKind.Change: @@ -78,7 +78,7 @@ def destroy(self) -> None: pass -watcher_implementation = None # type: Optional[Type[FileWatcher]] +watcher_implementation: Optional[Type[FileWatcher]] = None def register_file_watcher_implementation(file_watcher: Type[FileWatcher]) -> None: diff --git a/plugin/core/input_handlers.py b/plugin/core/input_handlers.py index 8a3b9fdef..234c1d933 100644 --- a/plugin/core/input_handlers.py +++ b/plugin/core/input_handlers.py @@ -106,8 +106,8 @@ def __init__(self, command: sublime_plugin.WindowCommand, args: Dict[str, Any]) self.command = command self.args = args self.text = getattr(command, '_text', '') - self.listener = None # type: Optional[sublime_plugin.TextChangeListener] - self.input_view = None # type: Optional[sublime.View] + self.listener: Optional[sublime_plugin.TextChangeListener] = None + self.input_view: Optional[sublime.View] = None def attach_listener(self) -> None: for buffer in sublime._buffers(): # type: ignore diff --git a/plugin/core/message_request_handler.py b/plugin/core/message_request_handler.py index 8c6fb1677..9b1ac6b54 100644 --- a/plugin/core/message_request_handler.py +++ b/plugin/core/message_request_handler.py @@ -8,12 +8,12 @@ import sublime -ICONS = { +ICONS: Dict[MessageType, str] = { MessageType.Error: '❗', MessageType.Warning: '⚠️', MessageType.Info: 'ℹ️', MessageType.Log: '📝' -} # type: Dict[MessageType, str] +} class MessageRequestHandler(): @@ -31,12 +31,12 @@ def __init__( self.source = source def show(self) -> None: - formatted = [] # type: List[str] + formatted: List[str] = [] formatted.append("

{}

".format(self.source)) icon = ICONS.get(self.message_type, '') formatted.append("
{} {}
".format(icon, text2html(self.message))) if self.action_titles: - buttons = [] # type: List[str] + buttons: List[str] = [] for idx, title in enumerate(self.action_titles): buttons.append("{}".format(idx, text2html(title))) formatted.append("
" + " ".join(buttons) + "
") diff --git a/plugin/core/open.py b/plugin/core/open.py index dd22a946e..b23503f77 100644 --- a/plugin/core/open.py +++ b/plugin/core/open.py @@ -18,14 +18,14 @@ import webbrowser -opening_files = {} # type: Dict[str, Tuple[Promise[Optional[sublime.View]], ResolveFunc[Optional[sublime.View]]]] +opening_files: Dict[str, Tuple[Promise[Optional[sublime.View]], ResolveFunc[Optional[sublime.View]]]] = {} FRAGMENT_PATTERN = re.compile(r'^L?(\d+)(?:,(\d+))?(?:-L?(\d+)(?:,(\d+))?)?') def lsp_range_from_uri_fragment(fragment: str) -> Optional[Range]: match = FRAGMENT_PATTERN.match(fragment) if match: - selection = {'start': {'line': 0, 'character': 0}, 'end': {'line': 0, 'character': 0}} # type: Range + selection: Range = {'start': {'line': 0, 'character': 0}, 'end': {'line': 0, 'character': 0}} # Line and column numbers in the fragment are assumed to be 1-based and need to be converted to 0-based # numbers for the LSP Position structure. start_line, start_column, end_line, end_column = [max(0, int(g) - 1) if g else None for g in match.groups()] diff --git a/plugin/core/panels.py b/plugin/core/panels.py index 58a5190a1..d4dfd7f1d 100644 --- a/plugin/core/panels.py +++ b/plugin/core/panels.py @@ -38,7 +38,7 @@ class PanelName: class PanelManager: def __init__(self, window: sublime.Window) -> None: self._window = window - self._rename_panel_buttons = None # type: Optional[sublime.PhantomSet] + self._rename_panel_buttons: Optional[sublime.PhantomSet] = None def destroy_output_panels(self) -> None: for field in filter(lambda a: not a.startswith('__'), PanelName.__dict__.keys()): diff --git a/plugin/core/progress.py b/plugin/core/progress.py index 482e0f463..22ec4482d 100644 --- a/plugin/core/progress.py +++ b/plugin/core/progress.py @@ -6,8 +6,8 @@ class ProgressReporter: def __init__(self, title: str) -> None: self.title = title - self._message = None # type: Optional[str] - self._percentage = None # type: Union[None, int, float] + self._message: Optional[str] = None + self._percentage: Union[None, int, float] = None def __del__(self) -> None: pass diff --git a/plugin/core/promise.py b/plugin/core/promise.py index 4e68b400b..fa6ca782a 100644 --- a/plugin/core/promise.py +++ b/plugin/core/promise.py @@ -87,12 +87,12 @@ class Executor(Generic[TExecutor]): __slots__ = ("resolver",) def __init__(self) -> None: - self.resolver = None # type: Optional[ResolveFunc[TExecutor]] + self.resolver: Optional[ResolveFunc[TExecutor]] = None def __call__(self, resolver: ResolveFunc[TExecutor]) -> None: self.resolver = resolver - executor = Executor() # type: Executor[S] + executor: Executor[S] = Executor() promise = Promise(executor) assert callable(executor.resolver) return promise, executor.resolver @@ -139,7 +139,7 @@ def __init__(self, executor_func: ExecutorFunc[T]) -> None: """ self.resolved = False self.mutex = threading.Lock() - self.callbacks = [] # type: List[ResolveFunc[T]] + self.callbacks: List[ResolveFunc[T]] = [] executor_func(lambda resolve_value=None: self._do_resolve(resolve_value)) def __repr__(self) -> str: diff --git a/plugin/core/protocol.py b/plugin/core/protocol.py index 25d4b8eb8..21cefb7d3 100644 --- a/plugin/core/protocol.py +++ b/plugin/core/protocol.py @@ -6030,7 +6030,7 @@ def __init__( self.method = method self.params = params self.view = view - self.progress = progress # type: Union[bool, str] + self.progress: Union[bool, str] = progress self.partial_results = partial_results @classmethod diff --git a/plugin/core/registry.py b/plugin/core/registry.py index c1708f3d9..5f6b48f69 100644 --- a/plugin/core/registry.py +++ b/plugin/core/registry.py @@ -238,7 +238,7 @@ def navigate_diagnostics(view: sublime.View, point: Optional[int], forward: bool wm = windows.lookup(view.window()) if not wm: return - diagnostics = [] # type: List[Diagnostic] + diagnostics: List[Diagnostic] = [] for session in wm.get_sessions(): diagnostics.extend(session.diagnostics.diagnostics_by_document_uri(uri)) if not diagnostics: diff --git a/plugin/core/sessions.py b/plugin/core/sessions.py index 8bb621295..b9f615b1b 100644 --- a/plugin/core/sessions.py +++ b/plugin/core/sessions.py @@ -256,7 +256,7 @@ def get_initialize_params(variables: Dict[str, str], workspace_folders: List[Wor semantic_token_types.append(token_type) semantic_token_modifiers = cast(List[str], _enum_like_class_to_list(SemanticTokenModifiers)) first_folder = workspace_folders[0] if workspace_folders else None - general_capabilities = { + general_capabilities: GeneralClientCapabilities = { # https://microsoft.github.io/language-server-protocol/specification#regExp "regularExpressions": { # https://www.sublimetext.com/docs/completions.html#ver-dev @@ -270,8 +270,8 @@ def get_initialize_params(variables: Dict[str, str], workspace_folders: List[Wor "parser": "Python-Markdown", "version": mdpopups.markdown.__version__ # type: ignore } - } # type: GeneralClientCapabilities - text_document_capabilities = { + } + text_document_capabilities: TextDocumentClientCapabilities = { "synchronization": { "dynamicRegistration": True, # exceptional "didSave": True, @@ -451,8 +451,8 @@ def get_initialize_params(variables: Dict[str, str], workspace_folders: List[Wor "typeHierarchy": { "dynamicRegistration": True } - } # type: TextDocumentClientCapabilities - workspace_capabilites = { + } + workspace_capabilites: WorkspaceClientCapabilities = { "applyEdit": True, "didChangeConfiguration": { "dynamicRegistration": True @@ -488,8 +488,8 @@ def get_initialize_params(variables: Dict[str, str], workspace_folders: List[Wor "diagnostics": { "refreshSupport": True } - } # type: WorkspaceClientCapabilities - window_capabilities = { + } + window_capabilities: WindowClientCapabilities = { "showDocument": { "support": True }, @@ -499,13 +499,13 @@ def get_initialize_params(variables: Dict[str, str], workspace_folders: List[Wor } }, "workDoneProgress": True - } # type: WindowClientCapabilities - capabilities = { + } + capabilities: ClientCapabilities = { "general": general_capabilities, "textDocument": text_document_capabilities, "workspace": workspace_capabilites, "window": window_capabilities, - } # type: ClientCapabilities + } if config.experimental_capabilities is not None: capabilities['experimental'] = cast(LSPObject, config.experimental_capabilities) if get_file_watcher_implementation(): @@ -1067,7 +1067,7 @@ def on_session_end_async(self, exit_code: Optional[int], exception: Optional[Exc pass -_plugins = {} # type: Dict[str, Tuple[Type[AbstractPlugin], SettingsRegistration]] +_plugins: Dict[str, Tuple[Type[AbstractPlugin], SettingsRegistration]] = {} def _register_plugin_impl(plugin: Type[AbstractPlugin], notify_listener: bool) -> None: @@ -1217,7 +1217,7 @@ def __init__( document_selector = [] self.selector = DocumentSelector(document_selector) self.options = options - self.session_buffers = WeakSet() # type: WeakSet[SessionBufferProtocol] + self.session_buffers: WeakSet[SessionBufferProtocol] = WeakSet() def __del__(self) -> None: for sb in self.session_buffers: @@ -1241,11 +1241,11 @@ class Session(TransportCallbacks): def __init__(self, manager: Manager, logger: Logger, workspace_folders: List[WorkspaceFolder], config: ClientConfig, plugin_class: Optional[Type[AbstractPlugin]]) -> None: - self.transport = None # type: Optional[Transport] - self.working_directory = None # type: Optional[str] + self.transport: Optional[Transport] = None + self.working_directory: Optional[str] = None self.request_id = 0 # Our request IDs are always integers. self._logger = logger - self._response_handlers = {} # type: Dict[int, Tuple[Request, Callable, Optional[Callable[[Any], None]]]] + self._response_handlers: Dict[int, Tuple[Request, Callable, Optional[Callable[[Any], None]]]] = {} self.config = config self.config_status_message = '' self.manager = weakref.ref(manager) @@ -1253,23 +1253,23 @@ def __init__(self, manager: Manager, logger: Logger, workspace_folders: List[Wor self.state = ClientStates.STARTING self.capabilities = Capabilities() self.diagnostics = DiagnosticsStorage() - self.diagnostics_result_ids = {} # type: Dict[DocumentUri, Optional[str]] - self.workspace_diagnostics_pending_response = None # type: Optional[int] + self.diagnostics_result_ids: Dict[DocumentUri, Optional[str]] = {} + self.workspace_diagnostics_pending_response: Optional[int] = None self.exiting = False - self._registrations = {} # type: Dict[str, _RegistrationData] - self._init_callback = None # type: Optional[InitCallback] - self._initialize_error = None # type: Optional[Tuple[int, Optional[Exception]]] + self._registrations: Dict[str, _RegistrationData] = {} + self._init_callback: Optional[InitCallback] = None + self._initialize_error: Optional[Tuple[int, Optional[Exception]]] = None self._views_opened = 0 self._workspace_folders = workspace_folders - self._session_views = WeakSet() # type: WeakSet[SessionViewProtocol] - self._session_buffers = WeakSet() # type: WeakSet[SessionBufferProtocol] - self._progress = {} # type: Dict[ProgressToken, Optional[WindowProgressReporter]] + self._session_views: WeakSet[SessionViewProtocol] = WeakSet() + self._session_buffers: WeakSet[SessionBufferProtocol] = WeakSet() + self._progress: Dict[ProgressToken, Optional[WindowProgressReporter]] = {} self._watcher_impl = get_file_watcher_implementation() - self._static_file_watchers = [] # type: List[FileWatcher] - self._dynamic_file_watchers = {} # type: Dict[str, List[FileWatcher]] + self._static_file_watchers: List[FileWatcher] = [] + self._dynamic_file_watchers: Dict[str, List[FileWatcher]] = {} self._plugin_class = plugin_class - self._plugin = None # type: Optional[AbstractPlugin] - self._status_messages = {} # type: Dict[str, str] + self._plugin: Optional[AbstractPlugin] = None + self._status_messages: Dict[str, str] = {} self._semantic_tokens_map = get_semantic_tokens_map(config.semantic_tokens) def __getattr__(self, name: str) -> Any: @@ -1447,7 +1447,7 @@ def should_notify_did_close(self) -> bool: # --- FileWatcherProtocol ------------------------------------------------------------------------------------------ def on_file_event_async(self, events: List[FileWatcherEvent]) -> None: - changes = [] # type: List[FileEvent] + changes: List[FileEvent] = [] for event in events: event_type, filepath = event changes.append({ @@ -1481,12 +1481,12 @@ def update_folders(self, folders: List[WorkspaceFolder]) -> None: if self.should_notify_did_change_workspace_folders(): added, removed = diff(self._workspace_folders, folders) if added or removed: - params = { + params: DidChangeWorkspaceFoldersParams = { "event": { "added": [a.to_lsp() for a in added], "removed": [r.to_lsp() for r in removed] } - } # type: DidChangeWorkspaceFoldersParams + } self.send_notification(Notification.didChangeWorkspaceFolders(params)) if self._supports_workspace_folders(): self._workspace_folders = folders @@ -1598,7 +1598,7 @@ def execute_command( ) -> Promise: """Run a command from any thread. Your .then() continuations will run in Sublime's worker thread.""" if self._plugin: - task = Promise.packaged_task() # type: PackagedTask[None] + task: PackagedTask[None] = Promise.packaged_task() promise, resolve = task if self._plugin.on_pre_server_command(command, lambda: resolve(None)): return promise @@ -1637,7 +1637,7 @@ def run_code_action_async( if isinstance(command, str): code_action = cast(Command, code_action) # This is actually a command. - command_params = {'command': command} # type: ExecuteCommandParams + command_params: ExecuteCommandParams = {'command': command} arguments = code_action.get('arguments', None) if isinstance(arguments, list): command_params['arguments'] = arguments @@ -1688,7 +1688,7 @@ def _open_file_uri_async( flags: int = 0, group: int = -1 ) -> Promise[Optional[sublime.View]]: - result = Promise.packaged_task() # type: PackagedTask[Optional[sublime.View]] + result: PackagedTask[Optional[sublime.View]] = Promise.packaged_task() def handle_continuation(view: Optional[sublime.View]) -> None: if view and r: @@ -1707,11 +1707,11 @@ def _open_uri_with_plugin_async( group: int, ) -> Optional[Promise[Optional[sublime.View]]]: # I cannot type-hint an unpacked tuple - pair = Promise.packaged_task() # type: PackagedTask[Tuple[str, str, str]] + pair: PackagedTask[Tuple[str, str, str]] = Promise.packaged_task() # It'd be nice to have automatic tuple unpacking continuations callback = lambda a, b, c: pair[1]((a, b, c)) # noqa: E731 if plugin.on_open_uri_async(uri, callback): - result = Promise.packaged_task() # type: PackagedTask[Optional[sublime.View]] + result: PackagedTask[Optional[sublime.View]] = Promise.packaged_task() def open_scratch_buffer(title: str, content: str, syntax: str) -> None: if group > -1: @@ -1769,9 +1769,9 @@ def _apply_code_action_async( promise = self.apply_workspace_edit_async(edit) if edit else Promise.resolve(None) command = code_action.get("command") if command is not None: - execute_command = { + execute_command: ExecuteCommandParams = { "command": command["command"], - } # type: ExecuteCommandParams + } arguments = command.get("arguments") if arguments is not None: execute_command['arguments'] = arguments @@ -1788,7 +1788,7 @@ def apply_workspace_edit_async(self, edit: WorkspaceEdit) -> Promise[None]: def apply_parsed_workspace_edits(self, changes: WorkspaceChanges) -> Promise[None]: active_sheet = self.window.active_sheet() selected_sheets = self.window.selected_sheets() - promises = [] # type: List[Promise[None]] + promises: List[Promise[None]] = [] for uri, (edits, view_version) in changes.items(): promises.append( self.open_uri_async(uri).then(functools.partial(self._apply_text_edits, edits, view_version, uri)) @@ -1824,9 +1824,9 @@ def decode_semantic_token( types_legend, modifiers_legend, self._semantic_tokens_map, token_type_encoded, token_modifiers_encoded) def session_views_by_visibility(self) -> Tuple[Set[SessionViewProtocol], Set[SessionViewProtocol]]: - visible_session_views = set() # type: Set[SessionViewProtocol] - not_visible_session_views = set() # type: Set[SessionViewProtocol] - selected_sheets = set() # type: Set[sublime.Sheet] + visible_session_views: Set[SessionViewProtocol] = set() + not_visible_session_views: Set[SessionViewProtocol] = set() + selected_sheets: Set[sublime.Sheet] = set() for group in range(self.window.num_groups()): selected_sheets = selected_sheets.union(self.window.selected_sheets_in_group(group)) for sheet in self.window.sheets(): @@ -1849,11 +1849,11 @@ def do_workspace_diagnostics_async(self) -> None: # The server is probably leaving the request open intentionally, in order to continuously stream updates via # $/progress notifications. return - previous_result_ids = [ + previous_result_ids: List[PreviousResultId] = [ {'uri': uri, 'value': result_id} for uri, result_id in self.diagnostics_result_ids.items() if result_id is not None - ] # type: List[PreviousResultId] - params = {'previousResultIds': previous_result_ids} # type: WorkspaceDiagnosticParams + ] + params: WorkspaceDiagnosticParams = {'previousResultIds': previous_result_ids} identifier = self.get_capability("diagnosticProvider.identifier") if identifier: params['identifier'] = identifier @@ -1932,7 +1932,7 @@ def m_workspace_workspaceFolders(self, _: Any, request_id: Any) -> None: def m_workspace_configuration(self, params: Dict[str, Any], request_id: Any) -> None: """handles the workspace/configuration request""" - items = [] # type: List[Any] + items: List[Any] = [] requested_items = params.get("items") or [] for requested_item in requested_items: configuration = self.config.settings.copy(requested_item.get('section') or None) @@ -2031,7 +2031,7 @@ def m_client_registerCapability(self, params: RegistrationParams, request_id: An sublime.set_timeout_async(inform) if self._watcher_impl and capability_path == "didChangeWatchedFilesProvider": capability_options = cast(DidChangeWatchedFilesRegistrationOptions, options) - file_watchers = [] # type: List[FileWatcher] + file_watchers: List[FileWatcher] = [] for config in capability_options.get("watchers", []): pattern = config.get("globPattern", '') if not isinstance(pattern, str): @@ -2248,13 +2248,13 @@ def send_request( sublime.set_timeout_async(functools.partial(self.send_request_async, request, on_result, on_error)) def send_request_task(self, request: Request) -> Promise: - task = Promise.packaged_task() # type: PackagedTask[Any] + task: PackagedTask[Any] = Promise.packaged_task() promise, resolver = task self.send_request_async(request, resolver, lambda x: resolver(Error.from_lsp(x))) return promise def send_request_task_2(self, request: Request) -> Tuple[Promise, int]: - task = Promise.packaged_task() # type: PackagedTask[Any] + task: PackagedTask[Any] = Promise.packaged_task() promise, resolver = task request_id = self.send_request_async(request, resolver, lambda x: resolver(Error.from_lsp(x))) return (promise, request_id) diff --git a/plugin/core/settings.py b/plugin/core/settings.py index 319de6e55..92b2a81d7 100644 --- a/plugin/core/settings.py +++ b/plugin/core/settings.py @@ -12,9 +12,9 @@ class ClientConfigs: def __init__(self) -> None: - self.all = {} # type: Dict[str, ClientConfig] - self.external = {} # type: Dict[str, ClientConfig] - self._listener = None # type: Optional[Callable[[Optional[str]], None]] + self.all: Dict[str, ClientConfig] = {} + self.external: Dict[str, ClientConfig] = {} + self._listener: Optional[Callable[[Optional[str]], None]] = None def _notify_listener(self, config_name: Optional[str] = None) -> None: if callable(self._listener): @@ -107,10 +107,10 @@ def set_listener(self, recipient: Callable[[Optional[str]], None]) -> None: self._listener = recipient -_settings_obj = None # type: Optional[sublime.Settings] -_settings = None # type: Optional[Settings] -_settings_registration = None # type: Optional[SettingsRegistration] -_global_settings = None # type: Optional[sublime.Settings] +_settings_obj: Optional[sublime.Settings] = None +_settings: Optional[Settings] = None +_settings_registration: Optional[SettingsRegistration] = None +_global_settings: Optional[sublime.Settings] = None client_configs = ClientConfigs() diff --git a/plugin/core/signature_help.py b/plugin/core/signature_help.py index a15e2e499..1bb7545b6 100644 --- a/plugin/core/signature_help.py +++ b/plugin/core/signature_help.py @@ -70,7 +70,7 @@ def render(self, view: sublime.View) -> str: signature = self._signatures[self._active_signature_index] except IndexError: return "" - formatted = [] # type: List[str] + formatted: List[str] = [] if self.has_multiple_signatures(): formatted.append(self._render_intro()) self._function_color = view.style_for_scope("entity.name.function.sighelp.lsp")["foreground"] @@ -112,7 +112,7 @@ def _render_intro(self) -> str: ) def _render_label(self, signature: SignatureInformation) -> List[str]: - formatted = [] # type: List[str] + formatted: List[str] = [] # Note that this
class and the extra
 are copied from mdpopups' HTML output. When mdpopups changes
         # its output style, we must update this literal string accordingly.
         formatted.append('
')
@@ -150,7 +150,7 @@ def _render_label(self, signature: SignatureInformation) -> List[str]:
         return formatted
 
     def _render_docs(self, view: sublime.View, signature: SignatureInformation) -> List[str]:
-        formatted = []  # type: List[str]
+        formatted: List[str] = []
         docs = self._parameter_documentation(view, signature)
         if docs:
             formatted.append(docs)
diff --git a/plugin/core/transports.py b/plugin/core/transports.py
index f4740d105..52f4eeaa8 100644
--- a/plugin/core/transports.py
+++ b/plugin/core/transports.py
@@ -107,7 +107,7 @@ def __init__(self, name: str, process: Optional[subprocess.Popen], socket: Optio
         self._reader_thread = threading.Thread(target=self._read_loop, name='{}-reader'.format(name))
         self._writer_thread = threading.Thread(target=self._write_loop, name='{}-writer'.format(name))
         self._callback_object = weakref.ref(callback_object)
-        self._send_queue = Queue(0)  # type: Queue[Union[T, None]]
+        self._send_queue: Queue[Union[T, None]] = Queue(0)
         self._reader_thread.start()
         self._writer_thread.start()
         if stderr:
@@ -194,7 +194,7 @@ def invoke() -> None:
         self.close()
 
     def _write_loop(self) -> None:
-        exception = None  # type: Optional[Exception]
+        exception: Optional[Exception] = None
         try:
             while self._writer:
                 d = self._send_queue.get()
@@ -245,8 +245,8 @@ def create_transport(config: TransportConfig, cwd: Optional[str],
     else:
         stdout = subprocess.PIPE
         stdin = subprocess.PIPE
-    sock = None  # type: Optional[socket.socket]
-    process = None  # type: Optional[subprocess.Popen]
+    sock: Optional[socket.socket] = None
+    process: Optional[subprocess.Popen] = None
 
     def start_subprocess() -> subprocess.Popen:
         startupinfo = _fixup_startup_args(config.command)
@@ -281,7 +281,7 @@ def start_subprocess() -> subprocess.Popen:
         config.name, process, sock, reader, writer, stderr, json_rpc_processor, callback_object)  # type: ignore
 
 
-_subprocesses = weakref.WeakSet()  # type: weakref.WeakSet[subprocess.Popen]
+_subprocesses: 'weakref.WeakSet[subprocess.Popen]' = weakref.WeakSet()
 
 
 def kill_all_subprocesses() -> None:
diff --git a/plugin/core/tree_view.py b/plugin/core/tree_view.py
index 1a2030767..80783e296 100644
--- a/plugin/core/tree_view.py
+++ b/plugin/core/tree_view.py
@@ -102,7 +102,7 @@ def __init__(self, element: T, tree_item: TreeItem, indent_level: int = 0) -> No
         self.element = element
         self.tree_item = tree_item
         self.indent_level = indent_level
-        self.child_ids = []  # type: List[str]
+        self.child_ids: List[str] = []
         self.is_resolved = False
 
 
@@ -125,8 +125,8 @@ class TreeViewSheet(sublime.HtmlSheet):
 
     def __init__(self, id: int, name: str, data_provider: TreeDataProvider, header: str = "") -> None:
         super().__init__(id)
-        self.nodes = {}  # type: Dict[str, Node]
-        self.root_nodes = []  # type: List[str]
+        self.nodes: Dict[str, Node] = {}
+        self.root_nodes: List[str] = []
         self.name = name
         self.data_provider = data_provider
         self.header = header
@@ -145,7 +145,7 @@ def set_provider(self, data_provider: TreeDataProvider, header: str = "") -> Non
         self.data_provider.get_children(None).then(self._set_root_nodes)
 
     def _set_root_nodes(self, elements: List[T]) -> None:
-        promises = []  # type: List[Promise[None]]
+        promises: List[Promise[None]] = []
         for element in elements:
             tree_item = self.data_provider.get_tree_item(element)
             tree_item.collapsible_state = TreeItemCollapsibleState.EXPANDED
diff --git a/plugin/core/types.py b/plugin/core/types.py
index 06710a094..afd64a42e 100644
--- a/plugin/core/types.py
+++ b/plugin/core/types.py
@@ -356,7 +356,7 @@ def diagnostics_highlight_style_flags(self) -> List[Optional[int]]:
             # same style for all severity levels
             return [self._style_str_to_flag(self.diagnostics_highlight_style)] * 4
         elif isinstance(self.diagnostics_highlight_style, dict):
-            flags = []  # type: List[Optional[int]]
+            flags: List[Optional[int]] = []
             for sev in ("error", "warning", "info", "hint"):
                 user_style = self.diagnostics_highlight_style.get(sev)
                 if user_style is None:  # user did not provide a style
@@ -437,7 +437,7 @@ def matches(self, view: sublime.View) -> bool:
 
 # method -> (capability dotted path, optional registration dotted path)
 # these are the EXCEPTIONS. The general rule is: method foo/bar --> (barProvider, barProvider.id)
-_METHOD_TO_CAPABILITY_EXCEPTIONS = {
+_METHOD_TO_CAPABILITY_EXCEPTIONS: Dict[str, Tuple[str, Optional[str]]] = {
     'workspace/symbol': ('workspaceSymbolProvider', None),
     'workspace/didChangeWorkspaceFolders': ('workspace.workspaceFolders',
                                             'workspace.workspaceFolders.changeNotifications'),
@@ -449,7 +449,7 @@ def matches(self, view: sublime.View) -> bool:
     'textDocument/willSaveWaitUntil': ('textDocumentSync.willSaveWaitUntil', None),
     'textDocument/formatting': ('documentFormattingProvider', None),
     'textDocument/documentColor': ('colorProvider', None)
-}  # type: Dict[str, Tuple[str, Optional[str]]]
+}
 
 
 def method_to_capability(method: str) -> Tuple[str, str]:
@@ -477,9 +477,9 @@ def normalize_text_sync(textsync: Union[None, int, Dict[str, Any]]) -> Dict[str,
     """
     Brings legacy text sync capabilities to the most modern format
     """
-    result = {}  # type: Dict[str, Any]
+    result: Dict[str, Any] = {}
     if isinstance(textsync, int):
-        change = {"syncKind": textsync}  # type: Optional[Dict[str, Any]]
+        change: Optional[Dict[str, Any]] = {"syncKind": textsync}
         result["textDocumentSync"] = {"didOpen": {}, "save": {}, "didClose": {}, "change": change}
     elif isinstance(textsync, dict):
         new = {}
@@ -565,7 +565,7 @@ def should_notify_did_open(self) -> bool:
         return "textDocumentSync.didOpen" in self
 
     def text_sync_kind(self) -> TextDocumentSyncKind:
-        value = self.get("textDocumentSync.change.syncKind")  # type: TextDocumentSyncKind
+        value: TextDocumentSyncKind = self.get("textDocumentSync.change.syncKind")
         return value if isinstance(value, int) else TextDocumentSyncKind.None_
 
     def should_notify_did_change_workspace_folders(self) -> bool:
@@ -608,7 +608,7 @@ def __init__(self, local: str, remote: str) -> None:
     def parse(cls, json: Any) -> "Optional[List[PathMap]]":
         if not isinstance(json, list):
             return None
-        result = []  # type: List[PathMap]
+        result: List[PathMap] = []
         for path_map in json:
             if not isinstance(path_map, dict):
                 debug('path map entry is not an object')
@@ -680,7 +680,7 @@ def __init__(self,
         self.selector = selector
         self.priority_selector = priority_selector if priority_selector else self.selector
         if isinstance(schemes, list):
-            self.schemes = schemes  # type: List[str]
+            self.schemes: List[str] = schemes
         else:
             self.schemes = ["file"]
         if isinstance(command, list):
@@ -798,8 +798,8 @@ def from_config(cls, src_config: "ClientConfig", override: Dict[str, Any]) -> "C
         )
 
     def resolve_transport_config(self, variables: Dict[str, str]) -> TransportConfig:
-        tcp_port = None  # type: Optional[int]
-        listener_socket = None  # type: Optional[socket.socket]
+        tcp_port: Optional[int] = None
+        listener_socket: Optional[socket.socket] = None
         if self.tcp_port is not None:
             # < 0 means we're hosting a TCP server
             if self.tcp_port < 0:
@@ -878,14 +878,14 @@ def is_disabled_capability(self, capability_path: str) -> bool:
         return False
 
     def filter_out_disabled_capabilities(self, capability_path: str, options: Dict[str, Any]) -> Dict[str, Any]:
-        result = {}  # type: Dict[str, Any]
+        result: Dict[str, Any] = {}
         for k, v in options.items():
             if not self.is_disabled_capability("{}.{}".format(capability_path, k)):
                 result[k] = v
         return result
 
     def __repr__(self) -> str:
-        items = []  # type: List[str]
+        items: List[str] = []
         for k, v in self.__dict__.items():
             if not k.startswith("_"):
                 items.append("{}={}".format(k, repr(v)))
diff --git a/plugin/core/views.py b/plugin/core/views.py
index 327e1bb26..e928a4547 100644
--- a/plugin/core/views.py
+++ b/plugin/core/views.py
@@ -56,13 +56,13 @@
 _baseflags = sublime.DRAW_NO_FILL | sublime.DRAW_NO_OUTLINE | sublime.DRAW_EMPTY_AS_OVERWRITE | sublime.NO_UNDO
 _multilineflags = sublime.DRAW_NO_FILL | sublime.NO_UNDO
 
-DIAGNOSTIC_SEVERITY = [
+DIAGNOSTIC_SEVERITY: List[Tuple[str, str, str, str, int, int]] = [
     # Kind       CSS class   Scope for color                        Icon resource                    add_regions flags for single-line diagnostic  multi-line diagnostic   # noqa: E501
     ("error",   "errors",   "region.redish markup.error.lsp",      "Packages/LSP/icons/error.png",   _baseflags | sublime.DRAW_SQUIGGLY_UNDERLINE, _multilineflags),  # noqa: E501
     ("warning", "warnings", "region.yellowish markup.warning.lsp", "Packages/LSP/icons/warning.png", _baseflags | sublime.DRAW_SQUIGGLY_UNDERLINE, _multilineflags),  # noqa: E501
     ("info",    "info",     "region.bluish markup.info.lsp",       "Packages/LSP/icons/info.png",    _baseflags | sublime.DRAW_STIPPLED_UNDERLINE, _multilineflags),  # noqa: E501
     ("hint",    "hints",    "region.bluish markup.info.hint.lsp",  "",                               _baseflags | sublime.DRAW_STIPPLED_UNDERLINE, _multilineflags),  # noqa: E501
-]  # type: List[Tuple[str, str, str, str, int, int]]
+]
 
 
 class DiagnosticSeverityData:
@@ -70,9 +70,9 @@ class DiagnosticSeverityData:
     __slots__ = ('regions', 'regions_with_tag', 'annotations', 'scope', 'icon')
 
     def __init__(self, severity: int) -> None:
-        self.regions = []  # type: List[sublime.Region]
-        self.regions_with_tag = {}  # type: Dict[int, List[sublime.Region]]
-        self.annotations = []  # type: List[str]
+        self.regions: List[sublime.Region] = []
+        self.regions_with_tag: Dict[int, List[sublime.Region]] = {}
+        self.annotations: List[str] = []
         _, _, self.scope, self.icon, _, _ = DIAGNOSTIC_SEVERITY[severity - 1]
         if userprefs().diagnostics_gutter_marker != "sign":
             self.icon = "" if severity == DiagnosticSeverity.Hint else userprefs().diagnostics_gutter_marker
@@ -285,11 +285,11 @@ def render_text_change(change: sublime.TextChange) -> TextDocumentContentChangeE
 def did_change_text_document_params(
     view: sublime.View, version: int, changes: Optional[Iterable[sublime.TextChange]] = None
 ) -> DidChangeTextDocumentParams:
-    content_changes = []  # type: List[TextDocumentContentChangeEvent]
-    result = {
+    content_changes: List[TextDocumentContentChangeEvent] = []
+    result: DidChangeTextDocumentParams = {
         "textDocument": versioned_text_document_identifier(view, version),
         "contentChanges": content_changes
-    }  # type: DidChangeTextDocumentParams
+    }
     if changes is None:
         # TextDocumentSyncKind.Full
         content_changes.append({"text": entire_content(view)})
@@ -309,9 +309,9 @@ def will_save_text_document_params(
 def did_save_text_document_params(
     view: sublime.View, include_text: bool, uri: Optional[DocumentUri] = None
 ) -> DidSaveTextDocumentParams:
-    result = {
+    result: DidSaveTextDocumentParams = {
         "textDocument": text_document_identifier(uri if uri is not None else view)
-    }  # type: DidSaveTextDocumentParams
+    }
     if include_text:
         result["text"] = entire_content(view)
     return result
@@ -401,10 +401,10 @@ def text_document_code_action_params(
     only_kinds: Optional[List[CodeActionKind]] = None,
     manual: bool = False
 ) -> CodeActionParams:
-    context = {
+    context: CodeActionContext = {
         "diagnostics": diagnostics,
         "triggerKind": CodeActionTriggerKind.Invoked if manual else CodeActionTriggerKind.Automatic,
-    }  # type: CodeActionContext
+    }
     if only_kinds:
         context["only"] = only_kinds
     return {
@@ -619,7 +619,7 @@ def make_command_link(
 ) -> str:
     if view_id is not None:
         cmd = "lsp_run_text_command_helper"
-        args = {"view_id": view_id, "command": command, "args": command_args}  # type: Optional[Dict[str, Any]]
+        args: Optional[Dict[str, Any]] = {"view_id": view_id, "command": command, "args": command_args}
     else:
         cmd = command
         args = command_args
@@ -848,7 +848,7 @@ def format_diagnostic_for_html(config: ClientConfig, diagnostic: Diagnostic, bas
 def format_code_actions_for_quick_panel(
     session_actions: Iterable[Tuple[str, Union[CodeAction, Command]]]
 ) -> Tuple[List[sublime.QuickPanelItem], int]:
-    items = []  # type: List[sublime.QuickPanelItem]
+    items: List[sublime.QuickPanelItem] = []
     selected_index = -1
     for idx, (config_name, code_action) in enumerate(session_actions):
         lsp_kind = code_action.get("kind", "")
diff --git a/plugin/core/windows.py b/plugin/core/windows.py
index 662572e78..49853575e 100644
--- a/plugin/core/windows.py
+++ b/plugin/core/windows.py
@@ -74,17 +74,17 @@ class WindowManager(Manager, WindowConfigChangeListener):
     def __init__(self, window: sublime.Window, workspace: ProjectFolders, config_manager: WindowConfigManager) -> None:
         self._window = window
         self._config_manager = config_manager
-        self._sessions = WeakSet()  # type: WeakSet[Session]
+        self._sessions: WeakSet[Session] = WeakSet()
         self._workspace = workspace
-        self._pending_listeners = deque()  # type: Deque[AbstractViewListener]
-        self._listeners = WeakSet()  # type: WeakSet[AbstractViewListener]
-        self._new_listener = None  # type: Optional[AbstractViewListener]
-        self._new_session = None  # type: Optional[Session]
-        self._panel_code_phantoms = None  # type: Optional[sublime.PhantomSet]
-        self._server_log = []  # type: List[Tuple[str, str]]
-        self.panel_manager = PanelManager(self._window)  # type: Optional[PanelManager]
-        self.tree_view_sheets = {}  # type: Dict[str, TreeViewSheet]
-        self.formatters = {}  # type: Dict[str, str]
+        self._pending_listeners: Deque[AbstractViewListener] = deque()
+        self._listeners: WeakSet[AbstractViewListener] = WeakSet()
+        self._new_listener: Optional[AbstractViewListener] = None
+        self._new_session: Optional[Session] = None
+        self._panel_code_phantoms: Optional[sublime.PhantomSet] = None
+        self._server_log: List[Tuple[str, str]] = []
+        self.panel_manager: Optional[PanelManager] = PanelManager(self._window)
+        self.tree_view_sheets: Dict[str, TreeViewSheet] = {}
+        self.formatters: Dict[str, str] = {}
         self.suppress_sessions_restart_on_project_update = False
         self.total_error_count = 0
         self.total_warning_count = 0
@@ -151,7 +151,7 @@ def listener_for_view(self, view: sublime.View) -> Optional[AbstractViewListener
         return None
 
     def _dequeue_listener_async(self) -> None:
-        listener = None  # type: Optional[AbstractViewListener]
+        listener: Optional[AbstractViewListener] = None
         if self._new_listener is not None:
             listener = self._new_listener
             # debug("re-checking listener", listener)
@@ -251,7 +251,7 @@ def start_async(self, config: ClientConfig, initiating_view: sublime.View) -> No
             workspace_folders = sorted_workspace_folders(self._workspace.folders, file_path)
             plugin_class = get_plugin(config.name)
             variables = extract_variables(self._window)
-            cwd = None  # type: Optional[str]
+            cwd: Optional[str] = None
             if plugin_class is not None:
                 if plugin_class.needs_update_or_installation():
                     config.set_view_status(initiating_view, "installing...")
@@ -272,7 +272,7 @@ def start_async(self, config: ClientConfig, initiating_view: sublime.View) -> No
             config.set_view_status(initiating_view, "starting...")
             session = Session(self, self._create_logger(config.name), workspace_folders, config, plugin_class)
             if cwd:
-                transport_cwd = cwd  # type: Optional[str]
+                transport_cwd: Optional[str] = cwd
             else:
                 transport_cwd = workspace_folders[0].path if workspace_folders else None
             transport_config = config.resolve_transport_config(variables)
@@ -354,7 +354,7 @@ def _end_sessions_async(self, config_name: Optional[str] = None) -> None:
                 self._sessions.discard(session)
 
     def get_project_path(self, file_path: str) -> Optional[str]:
-        candidate = None  # type: Optional[str]
+        candidate: Optional[str] = None
         for folder in self._workspace.folders:
             if file_path.startswith(folder):
                 if candidate is None or len(folder) > len(candidate):
@@ -470,12 +470,11 @@ def on_diagnostics_updated(self) -> None:
             self.update_diagnostics_panel_async()
 
     def update_diagnostics_panel_async(self) -> None:
-        to_render = []  # type: List[str]
-        prephantoms = []  # type: List[Tuple[int, int, str, str]]
+        to_render: List[str] = []
+        prephantoms: List[Tuple[int, int, str, str]] = []
         row = 0
         max_severity = userprefs().diagnostics_panel_include_severity_level
-        contributions = OrderedDict(
-        )  # type: OrderedDict[str, List[Tuple[str, Optional[int], Optional[str], Optional[str]]]]
+        contributions: OrderedDict[str, List[Tuple[str, Optional[int], Optional[str], Optional[str]]]] = OrderedDict()
         for session in self._sessions:
             for (_, path), contribution in session.diagnostics.filter_map_diagnostics_async(
                     is_severity_included(max_severity), lambda _, diagnostic: format_diagnostic_for_panel(diagnostic)):
@@ -505,7 +504,7 @@ def _update_panel_main_thread(self, characters: str, prephantoms: List[Tuple[int
         panel.run_command("lsp_update_panel", {"characters": characters})
         if self._panel_code_phantoms is None:
             self._panel_code_phantoms = sublime.PhantomSet(panel, "hrefs")
-        phantoms = []  # type: List[sublime.Phantom]
+        phantoms: List[sublime.Phantom] = []
         for row, col, code, href in prephantoms:
             point = panel.text_point(row, col)
             region = sublime.Region(point, point)
@@ -521,7 +520,7 @@ def on_configs_changed(self, config_name: Optional[str] = None) -> None:
 class WindowRegistry:
     def __init__(self) -> None:
         self._enabled = False
-        self._windows = {}  # type: Dict[int, WindowManager]
+        self._windows: Dict[int, WindowManager] = {}
         client_configs.set_listener(self._on_client_config_updated)
 
     def _on_client_config_updated(self, config_name: Optional[str] = None) -> None:
@@ -569,7 +568,7 @@ def discard(self, window: sublime.Window) -> None:
 
 class RequestTimeTracker:
     def __init__(self) -> None:
-        self._start_times = {}  # type: Dict[int, float]
+        self._start_times: Dict[int, float] = {}
 
     def start_tracking(self, request_id: int) -> None:
         self._start_times[request_id] = perf_counter()
@@ -674,8 +673,8 @@ class RemoteLogger(Logger):
     PORT = 9981
     DIRECTION_OUTGOING = 1
     DIRECTION_INCOMING = 2
-    _ws_server = None  # type: Optional[WebsocketServer]
-    _ws_server_thread = None  # type: Optional[threading.Thread]
+    _ws_server: Optional[WebsocketServer] = None
+    _ws_server_thread: Optional[threading.Thread] = None
     _last_id = 0
 
     def __init__(self, manager: WindowManager, server_name: str) -> None:
@@ -809,7 +808,7 @@ def _broadcast_json(self, data: Dict[str, Any]) -> None:
 
 class RouterLogger(Logger):
     def __init__(self) -> None:
-        self._loggers = []  # type: List[Logger]
+        self._loggers: List[Logger] = []
 
     def append(self, logger: Logger) -> None:
         self._loggers.append(logger)
diff --git a/plugin/core/workspace.py b/plugin/core/workspace.py
index 018217060..67c216318 100644
--- a/plugin/core/workspace.py
+++ b/plugin/core/workspace.py
@@ -57,9 +57,9 @@ class ProjectFolders(object):
 
     def __init__(self, window: sublime.Window) -> None:
         self._window = window
-        self.folders = self._window.folders()  # type: List[str]
+        self.folders: List[str] = self._window.folders()
         # Per-folder ignore patterns. The list order matches the order of self.folders.
-        self._folders_exclude_patterns = []  # type: List[List[str]]
+        self._folders_exclude_patterns: List[List[str]] = []
         self._update_exclude_patterns(self.folders)
 
     def _update_exclude_patterns(self, folders: List[str]) -> None:
@@ -120,8 +120,8 @@ def get_workspace_folders(self) -> List[WorkspaceFolder]:
 
 
 def sorted_workspace_folders(folders: List[str], file_path: str) -> List[WorkspaceFolder]:
-    matching_paths = []  # type: List[str]
-    other_paths = []  # type: List[str]
+    matching_paths: List[str] = []
+    other_paths: List[str] = []
 
     for folder in folders:
         is_subpath = is_subpath_of(file_path, folder)
diff --git a/plugin/diagnostics.py b/plugin/diagnostics.py
index 8b6448a3a..343357ed7 100644
--- a/plugin/diagnostics.py
+++ b/plugin/diagnostics.py
@@ -30,7 +30,7 @@ def draw(self, diagnostics: List[Tuple[Diagnostic, sublime.Region]]) -> None:
         # most to the least severe.
         for severity in DIAGNOSTIC_KINDS.keys():
             if severity <= max_severity_level:
-                matching_diagnostics = ([], [])  # type: Tuple[List[Diagnostic], List[sublime.Region]]
+                matching_diagnostics: Tuple[List[Diagnostic], List[sublime.Region]] = ([], [])
                 for diagnostic, region in diagnostics:
                     if diagnostic_severity(diagnostic) != severity:
                         continue
diff --git a/plugin/documents.py b/plugin/documents.py
index 7f989153f..e2a3f92d5 100644
--- a/plugin/documents.py
+++ b/plugin/documents.py
@@ -91,7 +91,7 @@ def previous_non_whitespace_char(view: sublime.View, pt: int) -> str:
 
 class TextChangeListener(sublime_plugin.TextChangeListener):
 
-    ids_to_listeners = WeakValueDictionary()  # type: WeakValueDictionary[int, TextChangeListener]
+    ids_to_listeners: 'WeakValueDictionary[int, TextChangeListener]' = WeakValueDictionary()
 
     @classmethod
     def is_applicable(cls, buffer: sublime.Buffer) -> bool:
@@ -100,7 +100,7 @@ def is_applicable(cls, buffer: sublime.Buffer) -> bool:
 
     def __init__(self) -> None:
         super().__init__()
-        self.view_listeners = WeakSet()  # type: WeakSet[DocumentSyncListener]
+        self.view_listeners: WeakSet[DocumentSyncListener] = WeakSet()
 
     def attach(self, buffer: sublime.Buffer) -> None:
         super().attach(buffer)
@@ -168,8 +168,8 @@ def on_change() -> None:
         self._change_count_on_last_save = -1
         self._code_lenses_debouncer_async = DebouncerNonThreadSafe(async_thread=True)
         self._registration = SettingsRegistration(view.settings(), on_change=on_change)
-        self._completions_task = None  # type: Optional[QueryCompletionsTask]
-        self._stored_selection = []  # type: List[sublime.Region]
+        self._completions_task: Optional[QueryCompletionsTask] = None
+        self._stored_selection: List[sublime.Region] = []
         self._should_format_on_paste = False
         self.hover_provider_count = 0
         self._setup()
@@ -180,22 +180,22 @@ def __del__(self) -> None:
     def _setup(self) -> None:
         syntax = self.view.syntax()
         if syntax:
-            self._language_id = basescope2languageid(syntax.scope)  # type: str
+            self._language_id = basescope2languageid(syntax.scope)
         else:
             debug("view", self.view.id(), "has no syntax")
             self._language_id = ""
-        self._manager = None  # type: Optional[WindowManager]
-        self._session_views = {}  # type: Dict[str, SessionView]
+        self._manager: Optional[WindowManager] = None
+        self._session_views: Dict[str, SessionView] = {}
         self._stored_selection = []
-        self._sighelp = None  # type: Optional[SigHelp]
-        self._lightbulb_line = None  # type: Optional[int]
-        self._diagnostics_for_selection = []  # type: List[Tuple[SessionBufferProtocol, List[Diagnostic]]]
-        self._code_actions_for_selection = []  # type: List[CodeActionsByConfigName]
+        self._sighelp: Optional[SigHelp] = None
+        self._lightbulb_line: Optional[int] = None
+        self._diagnostics_for_selection: List[Tuple[SessionBufferProtocol, List[Diagnostic]]] = []
+        self._code_actions_for_selection: List[CodeActionsByConfigName] = []
         self._registered = False
 
     def _cleanup(self) -> None:
         settings = self.view.settings()
-        triggers = settings.get("auto_complete_triggers") or []  # type: List[Dict[str, str]]
+        triggers: List[Dict[str, str]] = settings.get("auto_complete_triggers") or []
         triggers = [trigger for trigger in triggers if 'server' not in trigger]
         settings.set("auto_complete_triggers", triggers)
         self._stored_selection = []
@@ -262,9 +262,9 @@ def diagnostics_intersecting_region_async(
         region: sublime.Region
     ) -> Tuple[List[Tuple[SessionBufferProtocol, List[Diagnostic]]], sublime.Region]:
         covering = sublime.Region(region.begin(), region.end())
-        result = []  # type: List[Tuple[SessionBufferProtocol, List[Diagnostic]]]
+        result: List[Tuple[SessionBufferProtocol, List[Diagnostic]]] = []
         for sb, diagnostics in self._diagnostics_async():
-            intersections = []  # type: List[Diagnostic]
+            intersections: List[Diagnostic] = []
             for diagnostic, candidate in diagnostics:
                 # Checking against points is inclusive unlike checking whether region intersects another region
                 # which is exclusive (at region end) and we want an inclusive behavior in this case.
@@ -281,9 +281,9 @@ def diagnostics_touching_point_async(
         max_diagnostic_severity_level: int = DiagnosticSeverity.Hint
     ) -> Tuple[List[Tuple[SessionBufferProtocol, List[Diagnostic]]], sublime.Region]:
         covering = sublime.Region(pt, pt)
-        result = []  # type: List[Tuple[SessionBufferProtocol, List[Diagnostic]]]
+        result: List[Tuple[SessionBufferProtocol, List[Diagnostic]]] = []
         for sb, diagnostics in self._diagnostics_async():
-            intersections = []  # type: List[Diagnostic]
+            intersections: List[Diagnostic] = []
             for diagnostic, candidate in diagnostics:
                 severity = diagnostic_severity(diagnostic)
                 if severity > max_diagnostic_severity_level:
@@ -352,7 +352,7 @@ def on_load_async(self) -> None:
         if initially_folded_kinds:
             session = self.session_async('foldingRangeProvider')
             if session:
-                params = {'textDocument': text_document_identifier(self.view)}  # type: FoldingRangeParams
+                params: FoldingRangeParams = {'textDocument': text_document_identifier(self.view)}
                 session.send_request_async(
                     Request.foldingRange(params, self.view),
                     partial(self._on_initial_folding_ranges, initially_folded_kinds))
@@ -492,8 +492,8 @@ def _on_hover_gutter_async(self, point: int) -> None:
         if self._lightbulb_line == self.view.rowcol(point)[0]:
             content += code_actions_content(self._code_actions_for_selection)
         if userprefs().show_diagnostics_severity_level:
-            diagnostics_with_config = []  # type: List[Tuple[ClientConfig, Diagnostic]]
-            diagnostics_by_session_buffer = []  # type: List[Tuple[SessionBufferProtocol, List[Diagnostic]]]
+            diagnostics_with_config: List[Tuple[ClientConfig, Diagnostic]] = []
+            diagnostics_by_session_buffer: List[Tuple[SessionBufferProtocol, List[Diagnostic]]] = []
             max_severity_level = min(userprefs().show_diagnostics_severity_level, DiagnosticSeverity.Information)
             if userprefs().diagnostics_gutter_marker:
                 diagnostics_by_session_buffer = self.diagnostics_intersecting_async(self.view.line(point))[0]
@@ -586,7 +586,7 @@ def do_signature_help_async(self, manual: bool) -> None:
         if not session or not self._stored_selection:
             return
         pos = self._stored_selection[0].a
-        triggers = []  # type: List[str]
+        triggers: List[str] = []
         if not manual:
             for sb in self.session_buffers_async():
                 if session == sb.session:
@@ -599,19 +599,19 @@ def do_signature_help_async(self, manual: bool) -> None:
             self.purge_changes_async()
             position_params = text_document_position_params(self.view, pos)
             trigger_kind = SignatureHelpTriggerKind.Invoked if manual else SignatureHelpTriggerKind.TriggerCharacter
-            context_params = {
+            context_params: SignatureHelpContext = {
                 'triggerKind': trigger_kind,
                 'isRetrigger': self._sighelp is not None,
-            }  # type: SignatureHelpContext
+            }
             if not manual:
                 context_params["triggerCharacter"] = last_char
             if self._sighelp:
                 context_params["activeSignatureHelp"] = self._sighelp.active_signature_help()
-            params = {
+            params: SignatureHelpParams = {
                 "textDocument": position_params["textDocument"],
                 "position": position_params["position"],
                 "context": context_params
-            }  # type: SignatureHelpParams
+            }
             language_map = session.markdown_language_id_to_st_syntax_map()
             request = Request.signatureHelp(params, self.view)
             session.send_request_async(request, lambda resp: self._on_signature_help(resp, pos, language_map))
@@ -793,10 +793,10 @@ def _clear_highlight_regions(self) -> None:
 
     def _is_in_higlighted_region(self, point: int) -> bool:
         for kind in [DocumentHighlightKind.Text, DocumentHighlightKind.Read, DocumentHighlightKind.Write]:
-            regions = itertools.chain(
+            regions: Iterable[sublime.Region] = itertools.chain(
                 self.view.get_regions(self._highlights_key(kind, False)),
                 self.view.get_regions(self._highlights_key(kind, True))
-            )  # type: Iterable[sublime.Region]
+            )
             if any(region.contains(point) for region in regions):
                 return True
         return False
@@ -815,7 +815,7 @@ def _do_highlights_async(self) -> None:
     def _on_highlights(self, response: Optional[List[DocumentHighlight]]) -> None:
         if not isinstance(response, list):
             response = []
-        kind2regions = {}  # type: Dict[Tuple[DocumentHighlightKind, bool], List[sublime.Region]]
+        kind2regions: Dict[Tuple[DocumentHighlightKind, bool], List[sublime.Region]] = {}
         for highlight in response:
             r = range_to_region(highlight["range"], self.view)
             multiline = len(self.view.split_by_newlines(r)) > 1
@@ -980,7 +980,7 @@ def _format_on_paste_async(self) -> None:
         split_clipboard_text = clipboard_text.split('\n')
         multi_cursor_paste = len(split_clipboard_text) == len(sel) and len(sel) > 1
         original_selection = list(sel)
-        regions_to_format = []  # type: List[sublime.Region]
+        regions_to_format: List[sublime.Region] = []
         pasted_text = clipboard_text
         # add regions to selection, in order for lsp_format_document_range to format those regions
         for index, region in enumerate(sel):
diff --git a/plugin/edit.py b/plugin/edit.py
index b22dcdac1..6ddcfdf06 100644
--- a/plugin/edit.py
+++ b/plugin/edit.py
@@ -60,7 +60,7 @@ def run(
             last_row, _ = self.view.rowcol_utf16(self.view.size())
             placeholder_region_count = 0
             for start, end, replacement in reversed(_sort_by_application_order(edits)):
-                placeholder_region = None  # type: Optional[Tuple[Tuple[int, int], Tuple[int, int]]]
+                placeholder_region: Optional[Tuple[Tuple[int, int], Tuple[int, int]]] = None
                 if process_placeholders and replacement:
                     parsed = self.parse_snippet(replacement)
                     if parsed:
diff --git a/plugin/execute_command.py b/plugin/execute_command.py
index cfad5d132..3609ab54b 100644
--- a/plugin/execute_command.py
+++ b/plugin/execute_command.py
@@ -24,7 +24,7 @@ def run(self,
             event: Optional[dict] = None) -> None:
         session = self.session_by_name(session_name if session_name else self.session_name)
         if session and command_name:
-            params = {"command": command_name}  # type: ExecuteCommandParams
+            params: ExecuteCommandParams = {"command": command_name}
             if command_args:
                 params["arguments"] = self._expand_variables(command_args)
 
@@ -59,7 +59,7 @@ def handle_error_async(self, error: Error, command_name: str) -> None:
         sublime.message_dialog("command {} failed. Reason: {}".format(command_name, str(error)))
 
     def _expand_variables(self, command_args: List[Any]) -> List[Any]:
-        view = self.view  # type: sublime.View
+        view = self.view
         region = first_selection_region(view)
         for i, arg in enumerate(command_args):
             if arg in ["$document_id", "${document_id}"]:
diff --git a/plugin/folding_range.py b/plugin/folding_range.py
index 5ab5b172a..141fb2bb5 100644
--- a/plugin/folding_range.py
+++ b/plugin/folding_range.py
@@ -54,9 +54,9 @@ class LspFoldCommand(LspTextCommand):
     """
 
     capability = 'foldingRangeProvider'
-    folding_ranges = []  # type: List[FoldingRange]
+    folding_ranges: List[FoldingRange] = []
     change_count = -1
-    folding_region = None  # type: Optional[sublime.Region]
+    folding_region: Optional[sublime.Region] = None
 
     def is_visible(
         self,
@@ -82,7 +82,7 @@ def is_visible(
             self.change_count = -1
             session = self.best_session(self.capability)
             if session:
-                params = {'textDocument': text_document_identifier(self.view)}  # type: FoldingRangeParams
+                params: FoldingRangeParams = {'textDocument': text_document_identifier(self.view)}
                 session.send_request_async(
                     Request.foldingRange(params, self.view),
                     partial(self._handle_response_async, view_change_count)
@@ -155,7 +155,7 @@ def run(
                 pt = selection[0].b
             session = self.best_session(self.capability)
             if session:
-                params = {'textDocument': text_document_identifier(self.view)}  # type: FoldingRangeParams
+                params: FoldingRangeParams = {'textDocument': text_document_identifier(self.view)}
                 session.send_request_async(
                     Request.foldingRange(params, self.view),
                     partial(self._handle_response_manual_async, pt, strict)
@@ -187,7 +187,7 @@ class LspFoldAllCommand(LspTextCommand):
     def run(self, edit: sublime.Edit, kind: Optional[str] = None, event: Optional[dict] = None) -> None:
         session = self.best_session(self.capability)
         if session:
-            params = {'textDocument': text_document_identifier(self.view)}  # type: FoldingRangeParams
+            params: FoldingRangeParams = {'textDocument': text_document_identifier(self.view)}
             session.send_request_async(
                 Request.foldingRange(params, self.view), partial(self._handle_response_async, kind))
 
diff --git a/plugin/formatting.py b/plugin/formatting.py
index 4259724f7..c9db6a950 100644
--- a/plugin/formatting.py
+++ b/plugin/formatting.py
@@ -57,7 +57,7 @@ def is_applicable(cls, view: sublime.View) -> bool:
 
     def __init__(self, task_runner: LspTextCommand, on_complete: Callable[[], None]) -> None:
         super().__init__(task_runner, on_complete)
-        self._session_iterator = None  # type: Optional[Iterator[Session]]
+        self._session_iterator: Optional[Iterator[Session]] = None
 
     def run_async(self) -> None:
         super().run_async()
diff --git a/plugin/goto_diagnostic.py b/plugin/goto_diagnostic.py
index aef65c8e9..19f864c3b 100644
--- a/plugin/goto_diagnostic.py
+++ b/plugin/goto_diagnostic.py
@@ -94,8 +94,8 @@ def input_description(self) -> str:
 
 
 class DiagnosticUriInputHandler(PreselectedListInputHandler):
-    _preview = None  # type: Optional[sublime.View]
-    uri = None  # Optional[DocumentUri]
+    _preview: Optional[sublime.View] = None
+    uri: Optional[DocumentUri] = None
 
     def __init__(self, window: sublime.Window, view: sublime.View, initial_value: Optional[DocumentUri] = None) -> None:
         super().__init__(window, initial_value)
@@ -108,8 +108,8 @@ def name(self) -> str:
     def get_list_items(self) -> Tuple[List[sublime.ListInputItem], int]:
         max_severity = userprefs().diagnostics_panel_include_severity_level
         # collect severities and location of first diagnostic per uri
-        severities_per_path = OrderedDict()  # type: OrderedDict[ParsedUri, List[DiagnosticSeverity]]
-        self.first_locations = dict()  # type: Dict[ParsedUri, Tuple[Session, Location]]
+        severities_per_path: OrderedDict[ParsedUri, List[DiagnosticSeverity]] = OrderedDict()
+        self.first_locations: Dict[ParsedUri, Tuple[Session, Location]] = dict()
         for session in get_sessions(self.window):
             for parsed_uri, severity in session.diagnostics.filter_map_diagnostics_flat_async(
                     is_severity_included(max_severity), lambda _, diagnostic: diagnostic_severity(diagnostic)):
@@ -184,7 +184,7 @@ def _project_path(self, parsed_uri: ParsedUri) -> str:
 
 
 class DiagnosticInputHandler(sublime_plugin.ListInputHandler):
-    _preview = None  # type: Optional[sublime.View]
+    _preview: Optional[sublime.View] = None
 
     def __init__(self, window: sublime.Window, view: sublime.View, uri: DocumentUri) -> None:
         self.window = window
@@ -196,7 +196,7 @@ def name(self) -> str:
         return "diagnostic"
 
     def list_items(self) -> List[sublime.ListInputItem]:
-        list_items = []  # type: List[sublime.ListInputItem]
+        list_items: List[sublime.ListInputItem] = []
         max_severity = userprefs().diagnostics_panel_include_severity_level
         for i, session in enumerate(self.sessions):
             for diagnostic in filter(is_severity_included(max_severity),
diff --git a/plugin/hover.py b/plugin/hover.py
index cde9540c6..6357fd5e8 100644
--- a/plugin/hover.py
+++ b/plugin/hover.py
@@ -51,7 +51,7 @@
 ResolvedHover = Union[Hover, Error]
 
 
-_test_contents = []  # type: List[str]
+_test_contents: List[str] = []
 
 
 class LinkKind:
@@ -104,7 +104,7 @@ class LspHoverCommand(LspTextCommand):
 
     def __init__(self, view: sublime.View) -> None:
         super().__init__(view)
-        self._base_dir = None   # type: Optional[str]
+        self._base_dir: Optional[str] = None
         self._image_resolver = None
 
     def run(
@@ -126,10 +126,10 @@ def run(
             return
         hover_point = temp_point
         self._base_dir = wm.get_project_path(self.view.file_name() or "")
-        self._hover_responses = []  # type: List[Tuple[Hover, Optional[MarkdownLangMap]]]
-        self._document_links = []  # type: List[DocumentLink]
-        self._actions_by_config = []  # type: List[CodeActionsByConfigName]
-        self._diagnostics_by_config = []  # type: Sequence[Tuple[SessionBufferProtocol, Sequence[Diagnostic]]]
+        self._hover_responses: List[Tuple[Hover, Optional[MarkdownLangMap]]] = []
+        self._document_links: List[DocumentLink] = []
+        self._actions_by_config: List[CodeActionsByConfigName] = []
+        self._diagnostics_by_config: Sequence[Tuple[SessionBufferProtocol, Sequence[Diagnostic]]] = []
         # TODO: For code actions it makes more sense to use the whole selection under mouse (if available)
         # rather than just the hover point.
 
@@ -153,8 +153,8 @@ def run_async() -> None:
         sublime.set_timeout_async(run_async)
 
     def request_symbol_hover_async(self, listener: AbstractViewListener, point: int) -> None:
-        hover_promises = []  # type: List[Promise[ResolvedHover]]
-        language_maps = []  # type: List[Optional[MarkdownLangMap]]
+        hover_promises: List[Promise[ResolvedHover]] = []
+        language_maps: List[Optional[MarkdownLangMap]] = []
         for session in listener.sessions_async('hoverProvider'):
             hover_promises.append(session.send_request_task(
                 Request("textDocument/hover", text_document_position_params(self.view, point), self.view)
@@ -169,8 +169,8 @@ def _on_all_settled(
         language_maps: List[Optional[MarkdownLangMap]],
         responses: List[ResolvedHover]
     ) -> None:
-        hovers = []  # type: List[Tuple[Hover, Optional[MarkdownLangMap]]]
-        errors = []  # type: List[Error]
+        hovers: List[Tuple[Hover, Optional[MarkdownLangMap]]] = []
+        errors: List[Error] = []
         for response, language_map in zip(responses, language_maps):
             if isinstance(response, Error):
                 errors.append(response)
@@ -184,7 +184,7 @@ def _on_all_settled(
         self.show_hover(listener, point, only_diagnostics=False)
 
     def request_document_link_async(self, listener: AbstractViewListener, point: int) -> None:
-        link_promises = []  # type: List[Promise[DocumentLink]]
+        link_promises: List[Promise[DocumentLink]] = []
         for sv in listener.session_views_async():
             if not sv.has_capability_async("documentLinkProvider"):
                 continue
@@ -251,7 +251,7 @@ def link_content_and_range(self) -> Tuple[str, Optional[sublime.Region]]:
     def diagnostics_content(self) -> str:
         formatted = []
         for sb, diagnostics in self._diagnostics_by_config:
-            by_severity = {}  # type: Dict[int, List[str]]
+            by_severity: Dict[int, List[str]] = {}
             formatted.append('
') for diagnostic in diagnostics: by_severity.setdefault(diagnostic_severity(diagnostic), []).append( @@ -366,8 +366,8 @@ def on_select(targets: List[str], idx: int) -> None: session_name, uri, row, col_utf16 = unpack_href_location(href) session = self.session_by_name(session_name) if session: - position = {"line": row, "character": col_utf16} # type: Position - r = {"start": position, "end": position} # type: Range + position: Position = {"line": row, "character": col_utf16} + r: Range = {"start": position, "end": position} sublime.set_timeout_async(partial(session.open_uri_async, uri, r)) elif parse_uri(href)[0].lower() in ("", "http", "https"): open_in_browser(href) diff --git a/plugin/locationpicker.py b/plugin/locationpicker.py index 8fb390cf3..f89c3b1d7 100644 --- a/plugin/locationpicker.py +++ b/plugin/locationpicker.py @@ -81,7 +81,7 @@ def __init__( self._force_group = force_group self._group = group self._items = locations - self._highlighted_view = None # type: Optional[sublime.View] + self._highlighted_view: Optional[sublime.View] = None manager = session.manager() base_dir = manager.get_project_path(view.file_name() or "") if manager else None self._window.focus_group(group) diff --git a/plugin/references.py b/plugin/references.py index 03f106deb..dcc96c4a5 100644 --- a/plugin/references.py +++ b/plugin/references.py @@ -196,7 +196,7 @@ def _show_references_in_output_panel(self, word: str, session: Session, location if not panel: return base_dir = wm.get_project_path(self.view.file_name() or "") - to_render = [] # type: List[str] + to_render: List[str] = [] references_count = 0 references_by_file = _group_locations_by_uri(wm.window, session.config, locations) for file, references in references_by_file.items(): @@ -236,7 +236,7 @@ def _group_locations_by_uri( locations: List[Location] ) -> Dict[str, List[Tuple[Point, str]]]: """Return a dictionary that groups locations by the URI it belongs.""" - grouped_locations = {} # type: Dict[str, List[Tuple[Point, str]]] + grouped_locations: Dict[str, List[Tuple[Point, str]]] = {} for location in locations: uri, position = get_uri_and_position_from_location(location) file_path = config.map_server_uri_to_client_path(uri) diff --git a/plugin/rename.py b/plugin/rename.py index 3acdbd626..e3864f55a 100644 --- a/plugin/rename.py +++ b/plugin/rename.py @@ -178,11 +178,11 @@ def _do_rename(self, position: int, new_name: str) -> None: if not session: return position_params = text_document_position_params(self.view, position) - params = { + params: RenameParams = { "textDocument": position_params["textDocument"], "position": position_params["position"], "newName": new_name, - } # type: RenameParams + } request = Request.rename(params, self.view, progress=True) session.send_request(request, partial(self._on_rename_result_async, session)) @@ -245,8 +245,8 @@ def _render_rename_panel( panel = pm.ensure_rename_panel() if not panel: return - to_render = [] # type: List[str] - reference_document = [] # type: List[str] + to_render: List[str] = [] + reference_document: List[str] = [] header_lines = "{} changes across {} files.\n".format(total_changes, file_count) to_render.append(header_lines) reference_document.append(header_lines) diff --git a/plugin/save_command.py b/plugin/save_command.py index 60d50fd4f..b877c7f46 100644 --- a/plugin/save_command.py +++ b/plugin/save_command.py @@ -68,7 +68,7 @@ def __init__( self._text_command = text_command self._tasks = tasks self._on_tasks_completed = on_complete - self._pending_tasks = [] # type: List[SaveTask] + self._pending_tasks: List[SaveTask] = [] self._canceled = False def run(self) -> None: @@ -107,7 +107,7 @@ class LspSaveCommand(LspTextCommand): A command used as a substitute for native save command. Runs code actions and document formatting before triggering the native save command. """ - _tasks = [] # type: List[Type[SaveTask]] + _tasks: List[Type[SaveTask]] = [] @classmethod def register_task(cls, task: Type[SaveTask]) -> None: @@ -116,7 +116,7 @@ def register_task(cls, task: Type[SaveTask]) -> None: def __init__(self, view: sublime.View) -> None: super().__init__(view) - self._save_tasks_runner = None # type: Optional[SaveTasksRunner] + self._save_tasks_runner: Optional[SaveTasksRunner] = None def run(self, edit: sublime.Edit, **kwargs: Dict[str, Any]) -> None: if self._save_tasks_runner: diff --git a/plugin/selection_range.py b/plugin/selection_range.py index d318a721b..dbc7882e4 100644 --- a/plugin/selection_range.py +++ b/plugin/selection_range.py @@ -14,7 +14,7 @@ class LspExpandSelectionCommand(LspTextCommand): def __init__(self, view: sublime.View) -> None: super().__init__(view) - self._regions = [] # type: List[sublime.Region] + self._regions: List[sublime.Region] = [] self._change_count = 0 def is_enabled(self, event: Optional[dict] = None, point: Optional[int] = None, fallback: bool = False) -> bool: diff --git a/plugin/session_buffer.py b/plugin/session_buffer.py index c4a6a317f..b71312ad5 100644 --- a/plugin/session_buffer.py +++ b/plugin/session_buffer.py @@ -85,13 +85,13 @@ class SemanticTokensData: 'data', 'result_id', 'active_region_keys', 'tokens', 'view_change_count', 'needs_refresh', 'pending_response') def __init__(self) -> None: - self.data = [] # type: List[int] - self.result_id = None # type: Optional[str] - self.active_region_keys = set() # type: Set[int] - self.tokens = [] # type: List[SemanticToken] + self.data: List[int] = [] + self.result_id: Optional[str] = None + self.active_region_keys: Set[int] = set() + self.tokens: List[SemanticToken] = [] self.view_change_count = 0 self.needs_refresh = False - self.pending_response = None # type: Optional[int] + self.pending_response: Optional[int] = None class SessionBuffer: @@ -109,25 +109,25 @@ def __init__(self, session_view: SessionViewProtocol, buffer_id: int, uri: Docum # Every SessionBuffer has its own personal capabilities due to "dynamic registration". self.capabilities = Capabilities() self._session = session_view.session - self._session_views = WeakSet() # type: WeakSet[SessionViewProtocol] + self._session_views: WeakSet[SessionViewProtocol] = WeakSet() self._session_views.add(session_view) self._last_known_uri = uri self._id = buffer_id - self._pending_changes = None # type: Optional[PendingChanges] - self.diagnostics = [] # type: List[Tuple[Diagnostic, sublime.Region]] + self._pending_changes: Optional[PendingChanges] = None + self.diagnostics: List[Tuple[Diagnostic, sublime.Region]] = [] self.diagnostics_version = -1 self.diagnostics_flags = 0 self._diagnostics_are_visible = False self.document_diagnostic_needs_refresh = False - self._document_diagnostic_pending_response = None # type: Optional[int] + self._document_diagnostic_pending_response: Optional[int] = None self._last_synced_version = 0 self._last_text_change_time = 0.0 self._diagnostics_debouncer_async = DebouncerNonThreadSafe(async_thread=True) self._workspace_diagnostics_debouncer_async = DebouncerNonThreadSafe(async_thread=True) self._color_phantoms = sublime.PhantomSet(view, "lsp_color") - self._document_links = [] # type: List[DocumentLink] + self._document_links: List[DocumentLink] = [] self.semantic_tokens = SemanticTokensData() - self._semantic_region_keys = {} # type: Dict[str, int] + self._semantic_region_keys: Dict[str, int] = {} self._last_semantic_region_key = 0 self._inlay_hints_phantom_set = sublime.PhantomSet(view, "lsp_inlay_hints") self.inlay_hints_needs_refresh = False @@ -228,7 +228,7 @@ def register_capability_async( options: Dict[str, Any] ) -> None: self.capabilities.register(registration_id, capability_path, registration_path, options) - view = None # type: Optional[sublime.View] + view: Optional[sublime.View] = None for sv in self.session_views: sv.on_capability_added_async(registration_id, capability_path, options) if view is None: @@ -461,7 +461,7 @@ def do_document_diagnostic_async(self, view: sublime.View, version: Optional[int if self.has_capability("diagnosticProvider"): if self._document_diagnostic_pending_response: self.session.cancel_request(self._document_diagnostic_pending_response) - params = {'textDocument': text_document_identifier(view)} # type: DocumentDiagnosticParams + params: DocumentDiagnosticParams = {'textDocument': text_document_identifier(view)} identifier = self.get_capability("diagnosticProvider.identifier") if identifier: params['identifier'] = identifier @@ -518,8 +518,8 @@ def on_diagnostics_async( if version != change_count: return diagnostics_version = version - diagnostics = [] # type: List[Tuple[Diagnostic, sublime.Region]] - data_per_severity = {} # type: Dict[Tuple[int, bool], DiagnosticSeverityData] + diagnostics: List[Tuple[Diagnostic, sublime.Region]] = [] + data_per_severity: Dict[Tuple[int, bool], DiagnosticSeverityData] = {} for diagnostic in raw_diagnostics: region = range_to_region(diagnostic["range"], view) severity = diagnostic_severity(diagnostic) @@ -574,7 +574,7 @@ def do_semantic_tokens_async(self, view: sublime.View, only_viewport: bool = Fal if self.semantic_tokens.pending_response: self.session.cancel_request(self.semantic_tokens.pending_response) self.semantic_tokens.view_change_count = view.change_count() - params = {"textDocument": text_document_identifier(view)} # type: Dict[str, Any] + params: Dict[str, Any] = {"textDocument": text_document_identifier(view)} if only_viewport and self.has_capability("semanticTokensProvider.range"): params["range"] = region_to_range(view, view.visible_region()) request = Request.semanticTokensRange(cast(SemanticTokensRangeParams, params), view) @@ -633,7 +633,7 @@ def _draw_semantic_tokens_async(self) -> None: if view is None: return self.semantic_tokens.tokens.clear() - scope_regions = dict() # type: Dict[int, Tuple[str, List[sublime.Region]]] + scope_regions: Dict[int, Tuple[str, List[sublime.Region]]] = dict() prev_line = 0 prev_col_utf16 = 0 types_legend = tuple(cast(List[str], self.get_capability('semanticTokensProvider.legend.tokenTypes'))) @@ -708,10 +708,10 @@ def do_inlay_hints_async(self, view: sublime.View) -> None: if not LspToggleInlayHintsCommand.are_enabled(view.window()): self.remove_all_inlay_hints() return - params = { + params: InlayHintParams = { "textDocument": text_document_identifier(view), "range": entire_content_range(view) - } # type: InlayHintParams + } self.session.send_request_async(Request.inlayHint(params, view), self._on_inlay_hints_async) def _on_inlay_hints_async(self, response: Union[List[InlayHint], None]) -> None: diff --git a/plugin/session_view.py b/plugin/session_view.py index 3736fe9a4..c593a09cd 100644 --- a/plugin/session_view.py +++ b/plugin/session_view.py @@ -27,7 +27,7 @@ import functools import sublime -DIAGNOSTIC_TAG_VALUES = [v for (k, v) in DiagnosticTag.__dict__.items() if not k.startswith('_')] # type: List[int] +DIAGNOSTIC_TAG_VALUES: List[int] = [v for (k, v) in DiagnosticTag.__dict__.items() if not k.startswith('_')] class TagData: @@ -50,14 +50,14 @@ class SessionView: TRIGGER_CHARACTERS_KEY = "completionProvider.triggerCharacters" CODE_ACTIONS_KEY = "lsp_code_action" - _session_buffers = WeakValueDictionary() # type: WeakValueDictionary[Tuple[int, int], SessionBuffer] + _session_buffers: 'WeakValueDictionary[Tuple[int, int], SessionBuffer]' = WeakValueDictionary() def __init__(self, listener: AbstractViewListener, session: Session, uri: DocumentUri) -> None: self._view = listener.view self._session = session self._diagnostic_annotations = DiagnosticsAnnotationsView(self._view, session.config.name) self._initialize_region_keys() - self._active_requests = {} # type: Dict[int, ActiveRequest] + self._active_requests: Dict[int, ActiveRequest] = {} self._listener = ref(listener) self._code_lenses = CodeLensView(self._view) self.code_lenses_needs_refresh = False @@ -81,7 +81,7 @@ def __init__(self, listener: AbstractViewListener, session: Session, uri: Docume self._setup_auto_complete_triggers(settings) def on_before_remove(self) -> None: - settings = self.view.settings() # type: sublime.Settings + settings: sublime.Settings = self.view.settings() self._clear_auto_complete_triggers(settings) self._code_lenses.clear_view() if self.session.has_capability(self.HOVER_PROVIDER_KEY): @@ -133,7 +133,7 @@ def _initialize_region_keys(self) -> None: - gutter icons from region keys which were initialized _first_ are drawn For more context, see https://github.com/sublimelsp/LSP/issues/1593. """ - keys = [] # type: List[str] + keys: List[str] = [] r = [sublime.Region(0, 0)] document_highlight_style = userprefs().document_highlight_style hover_highlight_style = userprefs().hover_highlight_style @@ -190,7 +190,7 @@ def _unregister_auto_complete_triggers(self, registration_id: str) -> None: settings = self.view.settings() triggers = settings.get(self.AC_TRIGGERS_KEY) if isinstance(triggers, list): - new_triggers = [] # type: List[Dict[str, str]] + new_triggers: List[Dict[str, str]] = [] name = self.session.config.name for trigger in triggers: if not isinstance(trigger, dict): @@ -223,7 +223,7 @@ def _apply_auto_complete_triggers( if isinstance(registration_id, str): # This key is not used by Sublime, but is used as a "breadcrumb" as well, for dynamic registrations. trigger["registration_id"] = registration_id - triggers = settings.get(self.AC_TRIGGERS_KEY) or [] # type: List[Dict[str, str]] + triggers: List[Dict[str, str]] = settings.get(self.AC_TRIGGERS_KEY) or [] triggers.append(trigger) settings.set(self.AC_TRIGGERS_KEY, triggers) @@ -404,7 +404,7 @@ def resolve_visible_code_lenses_async(self) -> None: return if self._code_lenses.is_empty(): return - promises = [Promise.resolve(None)] # type: List[Promise[None]] + promises: List[Promise[None]] = [Promise.resolve(None)] if self.get_capability_async('codeLensProvider.resolveProvider'): for code_lens in self._code_lenses.unresolved_visible_code_lenses(self.view.visible_region()): request = Request("codeLens/resolve", code_lens.data, self.view) diff --git a/plugin/symbols.py b/plugin/symbols.py index deec5c4c4..5f547ee14 100644 --- a/plugin/symbols.py +++ b/plugin/symbols.py @@ -28,7 +28,7 @@ SUPPRESS_INPUT_SETTING_KEY = 'lsp_suppress_input' -SYMBOL_KIND_NAMES = { +SYMBOL_KIND_NAMES: Dict[SymbolKind, str] = { SymbolKind.File: "File", SymbolKind.Module: "Module", SymbolKind.Namespace: "Namespace", @@ -55,7 +55,7 @@ SymbolKind.Event: "Event", SymbolKind.Operator: "Operator", SymbolKind.TypeParameter: "Type Parameter" -} # type: Dict[SymbolKind, str] +} DocumentSymbolValue = TypedDict('DocumentSymbolValue', { @@ -85,7 +85,7 @@ def symbol_to_list_input_item( name = item['name'] kind = item['kind'] st_kind = SYMBOL_KINDS.get(kind, sublime.KIND_AMBIGUOUS) - details = [] # type: List[str] + details: List[str] = [] deprecated = SymbolTag.Deprecated in (item.get('tags') or []) or item.get('deprecated', False) value = {'kind': kind, 'deprecated': deprecated} details_separator = " • " @@ -159,7 +159,7 @@ class LspDocumentSymbolsCommand(LspTextCommand): def __init__(self, view: sublime.View) -> None: super().__init__(view) - self.items = [] # type: List[sublime.ListInputItem] + self.items: List[sublime.ListInputItem] = [] self.kind = 0 self.cached = False self.has_matching_symbols = True @@ -183,7 +183,7 @@ def run( session = self.best_session(self.capability) if session: self.view.settings().set(SUPPRESS_INPUT_SETTING_KEY, True) - params = {"textDocument": text_document_identifier(self.view)} # type: DocumentSymbolParams + params: DocumentSymbolParams = {"textDocument": text_document_identifier(self.view)} session.send_request( Request.documentSymbols(params, self.view), self.handle_response_async, self.handle_response_error) @@ -374,7 +374,7 @@ def on_modified(self, text: str) -> None: return change_count = self.input_view.change_count() self.command = cast(LspWindowCommand, self.command) - promises = [] # type: List[Promise[List[sublime.ListInputItem]]] + promises: List[Promise[List[sublime.ListInputItem]]] = [] for session in self.command.sessions(): promises.append( session.send_request_task(Request.workspaceSymbol({"query": text})) @@ -388,7 +388,7 @@ def _handle_response_async( def _on_all_responses(self, change_count: int, item_lists: List[List[sublime.ListInputItem]]) -> None: if self.input_view and self.input_view.change_count() == change_count: - items = [] # type: List[sublime.ListInputItem] + items: List[sublime.ListInputItem] = [] for item_list in item_lists: items.extend(item_list) self.update(items) diff --git a/plugin/tooling.py b/plugin/tooling.py index 71592ad57..c428bd465 100644 --- a/plugin/tooling.py +++ b/plugin/tooling.py @@ -67,7 +67,7 @@ def _preprocess_properties(translations: Optional[Dict[str, str]], properties: D if not isinstance(enums, list): enums = v.get("markdownEnumDescriptions") if isinstance(enums, list): - new_enums = [] # type: List[str] + new_enums: List[str] = [] for descr in enums: descr, _ = _translate_description(translations, descr) new_enums.append(descr) @@ -108,7 +108,7 @@ def preview(self, text: str) -> str: class LspParseVscodePackageJson(sublime_plugin.ApplicationCommand): def __init__(self) -> None: - self.view = None # type: Optional[sublime.View] + self.view: Optional[sublime.View] = None def writeline(self, contents: str, indent: int = 0) -> None: if self.view is not None: @@ -326,7 +326,7 @@ def test_run_server_async(self, config: ClientConfig, window: sublime.Window, lambda resolved_command, output, exit_code: self.update_sheet( config, active_view, output_sheet, resolved_command, output, exit_code)) # Store the instance so that it's not GC'ed before it's finished. - self.test_runner = server # type: Optional[ServerTestRunner] + self.test_runner: Optional[ServerTestRunner] = server def update_sheet(self, config: ClientConfig, active_view: Optional[sublime.View], output_sheet: sublime.HtmlSheet, resolved_command: List[str], server_output: str, exit_code: int) -> None: @@ -493,9 +493,9 @@ def __init__( on_close: Callable[[List[str], str, int], None] ) -> None: self._on_close = on_close - self._transport = None # type: Optional[Transport] - self._resolved_command = [] # type: List[str] - self._stderr_lines = [] # type: List[str] + self._transport: Optional[Transport] = None + self._resolved_command: List[str] = [] + self._stderr_lines: List[str] = [] try: variables = extract_variables(window) plugin_class = get_plugin(config.name) @@ -539,8 +539,8 @@ def on_transport_close(self, exit_code: int, exception: Optional[Exception]) -> class LspOnDoubleClickCommand(sublime_plugin.TextCommand): click_count = 0 - prev_command = None # type: Optional[str] - prev_args = None # type: Optional[Dict[Any, Any]] + prev_command: Optional[str] = None + prev_args: Optional[Dict[Any, Any]] = None def run(self, edit: sublime.Edit, command: str, args: Dict[Any, Any]) -> None: if self.prev_command != command or self.prev_args != args: diff --git a/tests/server.py b/tests/server.py index db40af133..9db43a69d 100644 --- a/tests/server.py +++ b/tests/server.py @@ -145,8 +145,8 @@ class SimpleRequest(Request): def __init__(self) -> None: self.cv = asyncio.Condition() - self.result = None # type: PayloadLike - self.error = None # type: Optional[Error] + self.result: PayloadLike = None + self.error: Optional[Error] = None async def on_result(self, params: PayloadLike) -> None: self.result = params diff --git a/tests/test_code_actions.py b/tests/test_code_actions.py index e4231917e..48c99b8f8 100644 --- a/tests/test_code_actions.py +++ b/tests/test_code_actions.py @@ -38,7 +38,7 @@ def create_code_action_edit(view: sublime.View, version: int, edits: List[Tuple[ def create_command(command_name: str, command_args: Optional[List[Any]] = None) -> Dict[str, Any]: - result = {"command": command_name} # type: Dict[str, Any] + result: Dict[str, Any] = {"command": command_name} if command_args is not None: result["arguments"] = command_args return result @@ -233,7 +233,7 @@ def _setup_document_with_missing_semicolon(self) -> Generator: class CodeActionMatchingTestCase(unittest.TestCase): def test_does_not_match(self) -> None: actual = get_matching_on_save_kinds({'a.x': True}, ['a.b']) - expected = [] # type: List[str] + expected: List[str] = [] self.assertEquals(actual, expected) def test_matches_exact_action(self) -> None: @@ -248,7 +248,7 @@ def test_matches_more_specific_action(self) -> None: def test_does_not_match_disabled_action(self) -> None: actual = get_matching_on_save_kinds({'a.b': True, 'a.b.c': False}, ['a.b.c']) - expected = [] # type: List[str] + expected: List[str] = [] self.assertEquals(actual, expected) def test_kind_matching(self) -> None: diff --git a/tests/test_completion.py b/tests/test_completion.py index 06e50f8ca..ea27a23b4 100644 --- a/tests/test_completion.py +++ b/tests/test_completion.py @@ -642,20 +642,20 @@ def test_replace_insert_mode(self) -> 'Generator': self.assertEqual(self.read_file(), '{{ turtle }}') def test_show_deprecated_flag(self) -> None: - item_with_deprecated_flag = { + item_with_deprecated_flag: CompletionItem = { "label": 'hello', "kind": CompletionItemKind.Method, "deprecated": True - } # type: CompletionItem + } formatted_completion_item = format_completion(item_with_deprecated_flag, 0, False, "", {}, self.view.id()) self.assertIn("DEPRECATED", formatted_completion_item.annotation) def test_show_deprecated_tag(self) -> None: - item_with_deprecated_tags = { + item_with_deprecated_tags: CompletionItem = { "label": 'hello', "kind": CompletionItemKind.Method, "tags": [CompletionItemTag.Deprecated] - } # type: CompletionItem + } formatted_completion_item = format_completion(item_with_deprecated_tags, 0, False, "", {}, self.view.id()) self.assertIn("DEPRECATED", formatted_completion_item.annotation) @@ -688,7 +688,7 @@ def check( label: str, label_details: Optional[CompletionItemLabelDetails] ) -> None: - lsp = {"label": label, "filterText": "force_label_to_go_into_st_detail_field"} # type: CompletionItem + lsp: CompletionItem = {"label": label, "filterText": "force_label_to_go_into_st_detail_field"} if label_details is not None: lsp["labelDetails"] = label_details native = format_completion(lsp, 0, resolve_support, "", {}, self.view.id()) @@ -739,7 +739,7 @@ def check( label: str, label_details: Optional[CompletionItemLabelDetails] ) -> None: - lsp = {"label": label} # type: CompletionItem + lsp: CompletionItem = {"label": label} if label_details is not None: lsp["labelDetails"] = label_details native = format_completion(lsp, 0, resolve_support, "", {}, self.view.id()) @@ -804,18 +804,18 @@ def test_additional_edits_if_session_does_not_have_the_resolve_capability(self) class ItemDefaultTests(TestCase): def test_respects_defaults_for_completion(self): - item = { + item: CompletionItem = { 'label': 'Hello' - } # type: CompletionItem - item_defaults = { + } + item_defaults: CompletionItemDefaults = { 'editRange': { 'start': {'character': 0, 'line': 0}, 'end': {'character': 0, 'line': 0}, }, 'insertTextFormat': InsertTextFormat.PlainText, 'data': ['1', '2'] - } # type: CompletionItemDefaults - expected = { + } + expected: CompletionItem = { 'label': 'Hello', 'textEdit': { 'newText': 'Hello', @@ -826,11 +826,11 @@ def test_respects_defaults_for_completion(self): }, 'insertTextFormat': InsertTextFormat.PlainText, 'data': ['1', '2'] - } # type: CompletionItem + } self.assertEqual(completion_with_defaults(item, item_defaults), expected) def test_defaults_should_not_override_completion_fields_if_present(self): - item = { + item: CompletionItem = { 'label': 'Hello', 'textEdit': { 'newText': 'Hello', @@ -841,8 +841,8 @@ def test_defaults_should_not_override_completion_fields_if_present(self): }, 'insertTextFormat': InsertTextFormat.PlainText, 'data': ['1', '2'] - } # type: CompletionItem - item_defaults = { + } + item_defaults: CompletionItemDefaults = { 'editRange': { 'insert': { 'start': {'character': 0, 'line': 0}, @@ -855,8 +855,8 @@ def test_defaults_should_not_override_completion_fields_if_present(self): }, 'insertTextFormat': InsertTextFormat.Snippet, 'data': ['3', '4'] - } # type: CompletionItemDefaults - expected = { + } + expected: CompletionItem = { 'label': 'Hello', 'textEdit': { 'newText': 'Hello', @@ -867,15 +867,15 @@ def test_defaults_should_not_override_completion_fields_if_present(self): }, 'insertTextFormat': InsertTextFormat.PlainText, 'data': ['1', '2'] - } # type: CompletionItem + } self.assertEqual(completion_with_defaults(item, item_defaults), expected) def test_conversion_of_edit_range_to_text_edit_when_it_includes_insert_replace_fields(self): - item = { + item: CompletionItem = { 'label': 'Hello', 'textEditText': 'Text to insert' - } # type: CompletionItem - item_defaults = { + } + item_defaults: CompletionItemDefaults = { 'editRange': { 'insert': { 'start': {'character': 0, 'line': 0}, @@ -886,8 +886,8 @@ def test_conversion_of_edit_range_to_text_edit_when_it_includes_insert_replace_f 'end': {'character': 0, 'line': 0}, }, }, - } # type: CompletionItemDefaults - expected = { + } + expected: CompletionItem = { 'label': 'Hello', 'textEditText': 'Text to insert', 'textEdit': { @@ -901,7 +901,7 @@ def test_conversion_of_edit_range_to_text_edit_when_it_includes_insert_replace_f 'end': {'character': 0, 'line': 0}, }, } - } # type: CompletionItem + } self.assertEqual(completion_with_defaults(item, item_defaults), expected) diff --git a/tests/test_edit.py b/tests/test_edit.py index bd5d3b108..14782f84b 100644 --- a/tests/test_edit.py +++ b/tests/test_edit.py @@ -14,26 +14,26 @@ FILENAME = 'C:\\file.py' if sublime.platform() == "windows" else '/file.py' URI = filename_to_uri(FILENAME) -LSP_TEXT_EDIT = { +LSP_TEXT_EDIT: TextEdit = { 'newText': 'newText\r\n', 'range': LSP_RANGE -} # type: TextEdit +} -LSP_EDIT_CHANGES = { +LSP_EDIT_CHANGES: WorkspaceEdit = { 'changes': {URI: [LSP_TEXT_EDIT]} -} # type: WorkspaceEdit +} -LSP_TEXT_DOCUMENT_EDIT = { +LSP_TEXT_DOCUMENT_EDIT: TextDocumentEdit = { 'textDocument': {'uri': URI, 'version': None}, 'edits': [LSP_TEXT_EDIT] -} # type: TextDocumentEdit +} -LSP_EDIT_DOCUMENT_CHANGES = { +LSP_EDIT_DOCUMENT_CHANGES: WorkspaceEdit = { 'documentChanges': [LSP_TEXT_DOCUMENT_EDIT] -} # type: WorkspaceEdit +} # Check that processing document changes does not result in clobbering. -LSP_EDIT_DOCUMENT_CHANGES_2 = { +LSP_EDIT_DOCUMENT_CHANGES_2: WorkspaceEdit = { "documentChanges": [ { "edits": [ @@ -141,9 +141,9 @@ } } ] -} # type: WorkspaceEdit +} -LSP_EDIT_DOCUMENT_CHANGES_3 = { +LSP_EDIT_DOCUMENT_CHANGES_3: WorkspaceEdit = { 'changes': { "file:///asdf/foo/bar": [ {"newText": "hello there", "range": LSP_RANGE}, @@ -152,7 +152,7 @@ ] }, 'documentChanges': [LSP_TEXT_DOCUMENT_EDIT] -} # type: WorkspaceEdit +} class TextEditTests(unittest.TestCase): @@ -230,7 +230,7 @@ class ApplyDocumentEditTestCase(TextDocumentTestCase): def test_applies_text_edit(self) -> None: self.insert_characters('abc') - edits = [{ + edits: List[TextEdit] = [{ 'newText': 'x$0y', 'range': { 'start': { @@ -242,13 +242,13 @@ def test_applies_text_edit(self) -> None: 'character': 2, } } - }] # type: List[TextEdit] + }] apply_text_edits(self.view, edits) self.assertEquals(entire_content(self.view), 'ax$0yc') def test_applies_text_edit_with_placeholder(self) -> None: self.insert_characters('abc') - edits = [{ + edits: List[TextEdit] = [{ 'newText': 'x$0y', 'range': { 'start': { @@ -260,7 +260,7 @@ def test_applies_text_edit_with_placeholder(self) -> None: 'character': 2, } } - }] # type: List[TextEdit] + }] apply_text_edits(self.view, edits, process_placeholders=True) self.assertEquals(entire_content(self.view), 'axyc') self.assertEqual(len(self.view.sel()), 1) @@ -268,7 +268,7 @@ def test_applies_text_edit_with_placeholder(self) -> None: def test_applies_multiple_text_edits_with_placeholders(self) -> None: self.insert_characters('ab') - newline_edit = { + newline_edit: TextEdit = { 'newText': '\n$0', 'range': { 'start': { @@ -280,8 +280,8 @@ def test_applies_multiple_text_edits_with_placeholders(self) -> None: 'character': 1, } } - } # type: TextEdit - edits = [newline_edit, newline_edit] # type: List[TextEdit] + } + edits: List[TextEdit] = [newline_edit, newline_edit] apply_text_edits(self.view, edits, process_placeholders=True) self.assertEquals(entire_content(self.view), 'a\n\nb') self.assertEqual(len(self.view.sel()), 2) diff --git a/tests/test_file_watcher.py b/tests/test_file_watcher.py index b3281e3ee..70d7c88a4 100644 --- a/tests/test_file_watcher.py +++ b/tests/test_file_watcher.py @@ -32,7 +32,7 @@ def setup_workspace_folder() -> str: class TestFileWatcher(FileWatcher): # The list of watchers created by active sessions. - _active_watchers = [] # type: List[TestFileWatcher] + _active_watchers: List['TestFileWatcher'] = [] @classmethod def create( diff --git a/tests/test_mocks.py b/tests/test_mocks.py index 177c4f9a2..75c57a588 100644 --- a/tests/test_mocks.py +++ b/tests/test_mocks.py @@ -43,7 +43,7 @@ class MockSession(object): def __init__(self, async_response=None) -> None: self.responses = basic_responses - self._notifications = [] # type: List[Notification] + self._notifications: List[Notification] = [] self._async_response_callback = async_response def send_request(self, request: Request, on_success: Callable, on_error: Callable = None) -> None: diff --git a/tests/test_protocol.py b/tests/test_protocol.py index f2860e6b9..32b6ce538 100644 --- a/tests/test_protocol.py +++ b/tests/test_protocol.py @@ -3,9 +3,9 @@ import unittest -LSP_START_POSITION = {'line': 10, 'character': 4} # type: Position -LSP_END_POSITION = {'line': 11, 'character': 3} # type: Position -LSP_RANGE = {'start': LSP_START_POSITION, 'end': LSP_END_POSITION} # type: Range +LSP_START_POSITION: Position = {'line': 10, 'character': 4} +LSP_END_POSITION: Position = {'line': 11, 'character': 3} +LSP_RANGE: Range = {'start': LSP_START_POSITION, 'end': LSP_END_POSITION} class PointTests(unittest.TestCase): diff --git a/tests/test_server_notifications.py b/tests/test_server_notifications.py index e49d655c6..7b3e02d16 100644 --- a/tests/test_server_notifications.py +++ b/tests/test_server_notifications.py @@ -11,7 +11,7 @@ class ServerNotifications(TextDocumentTestCase): def test_publish_diagnostics(self) -> Generator: self.insert_characters("a b c\n") - params = { + params: PublishDiagnosticsParams = { 'uri': filename_to_uri(self.view.file_name() or ''), 'diagnostics': [ { @@ -34,7 +34,7 @@ def test_publish_diagnostics(self) -> Generator: 'tags': [DiagnosticTag.Unnecessary] } ] - } # type: PublishDiagnosticsParams + } yield from self.await_client_notification("textDocument/publishDiagnostics", params) errors_icon_regions = self.view.get_regions("lspTESTds1_icon") errors_underline_regions = self.view.get_regions("lspTESTds1_underline") diff --git a/tests/test_types.py b/tests/test_types.py index 5b1806cfd..244769412 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -44,7 +44,7 @@ def test_completely_new(self) -> None: class TestDocumentSelector(unittest.TestCase): def setUp(self) -> None: - self._opened_views = [] # type: List[sublime.View] + self._opened_views: List[sublime.View] = [] def tearDown(self) -> None: for view in self._opened_views: diff --git a/tests/test_views.py b/tests/test_views.py index 9b6780800..5302ecd60 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -342,7 +342,7 @@ def test_document_color_params(self) -> None: def test_text_document_code_action_params(self) -> None: self.view.settings().set("lsp_uri", filename_to_uri(self.mock_file_name)) - diagnostic = { + diagnostic: Diagnostic = { "message": "oops", "severity": DiagnosticSeverity.Error, "range": { @@ -355,7 +355,7 @@ def test_text_document_code_action_params(self) -> None: "line": 0 } } - } # type: Diagnostic + } self.view.run_command("append", {"characters": "a b c\n"}) params = text_document_code_action_params( view=self.view, @@ -366,7 +366,7 @@ def test_text_document_code_action_params(self) -> None: self.assertEqual(params["textDocument"], {"uri": filename_to_uri(self.mock_file_name)}) def test_format_diagnostic_for_html(self) -> None: - diagnostic1 = { + diagnostic1: Diagnostic = { "message": "oops", "severity": DiagnosticSeverity.Error, # The relatedInformation is present here, but it's an empty list. @@ -382,7 +382,7 @@ def test_format_diagnostic_for_html(self) -> None: "line": 0 } } - } # type: Diagnostic + } # Make the same diagnostic but without the relatedInformation diagnostic2 = deepcopy(diagnostic1) diagnostic2.pop("relatedInformation")