sublimehq / sublime_text

Issue tracker for Sublime Text
https://www.sublimetext.com
812 stars 39 forks source link

Missing type hints in API class constructors' parameter lists #5587

Open deathaxe opened 2 years ago

deathaxe commented 2 years ago

Problem description

Recently realized pyright complaining about type mismatch in statements which create sublime.QuickPanalItem() objects.

grafik

Maybe I am missing something, but manually adding type hints to parameters of __init__() fixed the issue.

grafik

class QuickPanelItem:
    def __init__(
        self,
        trigger: str,
        details: str | list[str] | tuple[str]="",
        annotation: str="",
        kind: Kind=KIND_AMBIGUOUS
    ):
        self.trigger: str = trigger
        """ Text to match against user's input. """
        self.details: str | list[str] | tuple[str] = details
        """
        A `minihtml` string or list of strings displayed below the trigger.
        """
        self.annotation: str = annotation
        """ Hint to draw to the right-hand side of the row. """
        self.kind: Kind = kind
        """ The kind of the item. See `Kind`. """

Preferred solution

Add type hints to parameters of __init__() methods

Alternatives

??

Additional Information

Here's a patch of ST4136's python38/sublime.py

```patch diff --git a/python38/sublime.py b/python38/sublime.py index 499a7b6..b73674d 100644 --- a/python38/sublime.py +++ b/python38/sublime.py @@ -60,10 +60,12 @@ class HoverZone(enum.IntEnum): MARGIN = 3 """ The mouse is hovered in the white space to the right of a line. """ + HOVER_TEXT = HoverZone.TEXT HOVER_GUTTER = HoverZone.GUTTER HOVER_MARGIN = HoverZone.MARGIN + class NewFileFlags(enum.IntFlag): """ Flags for creating/opening files in various ways. @@ -130,6 +132,7 @@ class NewFileFlags(enum.IntFlag): .. :since:: next """ + ENCODED_POSITION = NewFileFlags.ENCODED_POSITION TRANSIENT = NewFileFlags.TRANSIENT FORCE_GROUP = NewFileFlags.FORCE_GROUP @@ -139,6 +142,7 @@ REPLACE_MRU = NewFileFlags.REPLACE_MRU CLEAR_TO_RIGHT = NewFileFlags.CLEAR_TO_RIGHT FORCE_CLONE = NewFileFlags.FORCE_CLONE + class FindFlags(enum.IntFlag): """ Flags for use when searching through a `View`. @@ -157,9 +161,11 @@ class FindFlags(enum.IntFlag): LITERAL = 1 """ Whether the find pattern should be matched literally or as a regex. """ + IGNORECASE = FindFlags.IGNORECASE LITERAL = FindFlags.LITERAL + class QuickPanelFlags(enum.IntFlag): """ Flags for use with a quick panel. @@ -185,10 +191,12 @@ class QuickPanelFlags(enum.IntFlag): .. since:: 4096 """ + MONOSPACE_FONT = QuickPanelFlags.MONOSPACE_FONT KEEP_OPEN_ON_FOCUS_LOST = QuickPanelFlags.KEEP_OPEN_ON_FOCUS_LOST WANT_EVENT = QuickPanelFlags.WANT_EVENT + class PopupFlags(enum.IntFlag): """ Flags for use with popups. @@ -226,6 +234,7 @@ class PopupFlags(enum.IntFlag): .. since:: 4057 """ + # Deprecated HTML = 1 COOPERATE_WITH_AUTO_COMPLETE = PopupFlags.COOPERATE_WITH_AUTO_COMPLETE @@ -234,6 +243,7 @@ HIDE_ON_MOUSE_MOVE_AWAY = PopupFlags.HIDE_ON_MOUSE_MOVE_AWAY KEEP_ON_SELECTION_MODIFIED = PopupFlags.KEEP_ON_SELECTION_MODIFIED HIDE_ON_CHARACTER_EVENT = PopupFlags.HIDE_ON_CHARACTER_EVENT + class RegionFlags(enum.IntFlag): """ Flags for use with added regions. See `View.add_regions`. @@ -268,6 +278,7 @@ class RegionFlags(enum.IntFlag): NO_UNDO = 8192 """ """ + DRAW_EMPTY = RegionFlags.DRAW_EMPTY HIDE_ON_MINIMAP = RegionFlags.HIDE_ON_MINIMAP DRAW_EMPTY_AS_OVERWRITE = RegionFlags.DRAW_EMPTY_AS_OVERWRITE @@ -282,6 +293,7 @@ DRAW_SQUIGGLY_UNDERLINE = RegionFlags.DRAW_SQUIGGLY_UNDERLINE NO_UNDO = RegionFlags.NO_UNDO HIDDEN = RegionFlags.HIDDEN + class QueryOperator(enum.IntEnum): """ Enumeration of operators able to be used when querying contexts. @@ -307,6 +319,7 @@ class QueryOperator(enum.IntEnum): NOT_REGEX_CONTAINS = 5 """ """ + OP_EQUAL = QueryOperator.EQUAL OP_NOT_EQUAL = QueryOperator.NOT_EQUAL OP_REGEX_MATCH = QueryOperator.REGEX_MATCH @@ -314,6 +327,7 @@ OP_NOT_REGEX_MATCH = QueryOperator.NOT_REGEX_MATCH OP_REGEX_CONTAINS = QueryOperator.REGEX_CONTAINS OP_NOT_REGEX_CONTAINS = QueryOperator.NOT_REGEX_CONTAINS + class PointClassification(enum.IntFlag): """ Flags that identify characteristics about a `Point` in a text sheet. See @@ -345,6 +359,7 @@ class PointClassification(enum.IntFlag): EMPTY_LINE = 256 """ The point is an empty line. """ + CLASS_WORD_START = PointClassification.WORD_START CLASS_WORD_END = PointClassification.WORD_END CLASS_PUNCTUATION_START = PointClassification.PUNCTUATION_START @@ -355,6 +370,7 @@ CLASS_LINE_START = PointClassification.LINE_START CLASS_LINE_END = PointClassification.LINE_END CLASS_EMPTY_LINE = PointClassification.EMPTY_LINE + class AutoCompleteFlags(enum.IntFlag): """ Flags controlling how asynchronous completions function. See @@ -390,18 +406,22 @@ class AutoCompleteFlags(enum.IntFlag): .. since:: 4074 """ + INHIBIT_WORD_COMPLETIONS = AutoCompleteFlags.INHIBIT_WORD_COMPLETIONS INHIBIT_EXPLICIT_COMPLETIONS = AutoCompleteFlags.INHIBIT_EXPLICIT_COMPLETIONS DYNAMIC_COMPLETIONS = AutoCompleteFlags.DYNAMIC_COMPLETIONS INHIBIT_REORDER = AutoCompleteFlags.INHIBIT_REORDER + class CompletionItemFlags(enum.IntFlag): """ :meta private: """ NONE = 0 KEEP_PREFIX = 1 + COMPLETION_FLAG_KEEP_PREFIX = CompletionItemFlags.KEEP_PREFIX + class DialogResult(enum.IntEnum): """ The result from a *yes / no / cancel* dialog. See `yes_no_cancel_dialog`. @@ -418,10 +438,12 @@ class DialogResult(enum.IntEnum): NO = 2 """ """ + DIALOG_CANCEL = DialogResult.CANCEL DIALOG_YES = DialogResult.YES DIALOG_NO = DialogResult.NO + class UIElement(enum.IntEnum): """ :meta private: """ SIDE_BAR = 1 @@ -431,6 +453,7 @@ class UIElement(enum.IntEnum): MENU = 16 OPEN_FILES = 32 + class PhantomLayout(enum.IntEnum): """ How a `Phantom` should be positioned. See `PhantomSet`. @@ -456,10 +479,12 @@ class PhantomLayout(enum.IntEnum): the line. """ + LAYOUT_INLINE = PhantomLayout.INLINE LAYOUT_BELOW = PhantomLayout.BELOW LAYOUT_BLOCK = PhantomLayout.BLOCK + class KindId(enum.IntEnum): """ For backwards compatibility these values are also available outside this @@ -509,6 +534,7 @@ class KindId(enum.IntEnum): COLOR_LIGHT = 18 """ """ + KIND_ID_AMBIGUOUS = KindId.AMBIGUOUS KIND_ID_KEYWORD = KindId.KEYWORD KIND_ID_TYPE = KindId.TYPE @@ -566,6 +592,7 @@ KIND_SNIPPET = (KindId.SNIPPET, "s", "Snippet") .. since:: 4052 """ + class SymbolSource(enum.IntEnum): """ See `Window.symbol_locations`. @@ -594,10 +621,12 @@ class SymbolSource(enum.IntEnum): .. since:: 4085 """ + SYMBOL_SOURCE_ANY = SymbolSource.ANY SYMBOL_SOURCE_INDEX = SymbolSource.INDEX SYMBOL_SOURCE_OPEN_FILES = SymbolSource.OPEN_FILES + class SymbolType(enum.IntEnum): """ See `Window.symbol_locations` and `View.indexed_symbol_regions`. @@ -625,10 +654,12 @@ class SymbolType(enum.IntEnum): .. since:: 4085 """ + SYMBOL_TYPE_ANY = SymbolType.ANY SYMBOL_TYPE_DEFINITION = SymbolType.DEFINITION SYMBOL_TYPE_REFERENCE = SymbolType.REFERENCE + class CompletionFormat(enum.IntEnum): """ The format completion text can be in. See `CompletionItem`. @@ -660,6 +691,7 @@ class CompletionFormat(enum.IntEnum): .. since:: 4050 """ + COMPLETION_FORMAT_TEXT = CompletionFormat.TEXT COMPLETION_FORMAT_SNIPPET = CompletionFormat.SNIPPET COMPLETION_FORMAT_COMMAND = CompletionFormat.COMMAND @@ -909,7 +941,7 @@ def command_url(cmd: str, args: CommandArgs = None) -> str: return f'subl:{html_format_command(cmd, args)}' -def get_clipboard_async(callback: Callable[[str], None], size_limit: int = 16777216): +def get_clipboard_async(callback: Callable[[str], None], size_limit=16777216): """ Get the contents of the clipboard in a callback. @@ -921,7 +953,7 @@ def get_clipboard_async(callback: Callable[[str], None], size_limit: int = 16777 sublime_api.get_clipboard_async(callback, size_limit) -def get_clipboard(size_limit: int = 16777216) -> str: +def get_clipboard(size_limit=16777216) -> str: """ Get the contents of the clipboard. @@ -1191,7 +1223,7 @@ def save_settings(base_name: str): sublime_api.save_settings(base_name) -def set_timeout(callback: Callable, delay: int = 0): +def set_timeout(callback: Callable, delay=0): """ Run the ``callback`` in the main thread after the given ``delay`` (in milliseconds). Callbacks with an equal delay will be run in the order @@ -1200,7 +1232,7 @@ def set_timeout(callback: Callable, delay: int = 0): sublime_api.set_timeout(callback, delay) -def set_timeout_async(callback: Callable, delay: int = 0): +def set_timeout_async(callback: Callable, delay=0): """ Runs the callback on an alternate thread after the given delay (in milliseconds). @@ -1291,7 +1323,12 @@ class Window: else: return View(view_id) - def new_html_sheet(self, name: str, contents: str, flags = NewFileFlags.NONE, group = -1) -> Sheet: + def new_html_sheet( + self, + name: str, + contents: str, + flags=NewFileFlags.NONE, + group=-1) -> Sheet: """ Construct a sheet with HTML contents rendered using `minihtml`. @@ -1314,7 +1351,7 @@ class Window: """ sublime_api.window_run_command(self.window_id, cmd, args) - def new_file(self, flags = NewFileFlags.NONE, syntax = "") -> View: + def new_file(self, flags=NewFileFlags.NONE, syntax="") -> View: """ Create a new empty file. @@ -1324,7 +1361,7 @@ class Window: """ return View(sublime_api.window_new_file(self.window_id, flags, syntax)) - def open_file(self, fname: str, flags = NewFileFlags.NONE, group = -1) -> View: + def open_file(self, fname: str, flags=NewFileFlags.NONE, group=-1) -> View: """ Open the named file. If the file is already opened, it will be brought to the front. Note that as file loading is asynchronous, operations on @@ -1337,7 +1374,7 @@ class Window: """ return View(sublime_api.window_open_file(self.window_id, fname, flags, group)) - def find_open_file(self, fname: str, group = -1) -> Optional[View]: + def find_open_file(self, fname: str, group=-1) -> Optional[View]: """ Find a opened file by file name. @@ -1437,7 +1474,7 @@ class Window: """ sublime_api.window_set_view_index(self.window_id, view.view_id, group, index) - def move_sheets_to_group(self, sheets: list[Sheet], group: int, insertion_idx = -1, select = True): + def move_sheets_to_group(self, sheets: list[Sheet], group: int, insertion_idx=-1, select=True): """ Moves all provided sheets to specified group at insertion index provided. If an index is not provided defaults to last index of the @@ -1621,10 +1658,13 @@ class Window: """ :deprecated: Use `create_output_panel` instead. """ return self.create_output_panel(name) - def show_input_panel(self, caption: str, initial_text: str, - on_done: Optional[Callable[[str], None]], - on_change: Optional[Callable[[str], None]], - on_cancel: Optional[Callable[[], None]]): + def show_input_panel( + self, + caption: str, + initial_text: str, + on_done: Optional[Callable[[str], None]], + on_change: Optional[Callable[[str], None]], + on_cancel: Optional[Callable[[], None]]): """ Shows the input panel, to collect a line of input from the user. @@ -1638,13 +1678,14 @@ class Window: return View(sublime_api.window_show_input_panel( self.window_id, caption, initial_text, on_done, on_change, on_cancel)) - def show_quick_panel(self, - items: list[str] | list[list[str]] | list[QuickPanelItem], - on_select: Callable[[int], None], - flags=QuickPanelFlags.NONE, - selected_index=-1, - on_highlight: Optional[Callable[[int], None]] = None, - placeholder: Optional[str] = None): + def show_quick_panel( + self, + items: list[str] | list[list[str]] | list[QuickPanelItem], + on_select: Callable[[int], None], + flags: QuickPanelFlags = QuickPanelFlags.NONE, + selected_index=-1, + on_highlight: Optional[Callable[[int], None]] = None, + placeholder: Optional[str] = None): """ Show a quick panel to select an item in a list. on_select will be called once, with the index of the selected item. If the quick panel was @@ -1805,12 +1846,13 @@ class Window: return self.template_settings_object - def symbol_locations(self, - sym: str, - source=SymbolSource.ANY, - type=SymbolType.ANY, - kind_id=KindId.AMBIGUOUS, - kind_letter='') -> list[SymbolLocation]: + def symbol_locations( + self, + sym: str, + source=SymbolSource.ANY, + type=SymbolType.ANY, + kind_id=KindId.AMBIGUOUS, + kind_letter='') -> list[SymbolLocation]: """ Find all locations where the symbol ``sym`` is located. @@ -1897,8 +1939,8 @@ class Edit: `View`, will cause the functions that require them to fail. """ - def __init__(self, token): - self.edit_token: int = token + def __init__(self, token: int): + self.edit_token = token def __repr__(self) -> str: return f'Edit({self.edit_token!r})' @@ -1920,14 +1962,14 @@ class Region: if b is None: b = a - self.a: Point = a + self.a = a """ The first end of the region. """ - self.b: Point = b + self.b = b """ The second end of the region. In a selection this is the location of the caret. May be less than ``a``. """ - self.xpos: DIP = xpos + self.xpos = xpos """ In a selection this is the target horizontal position of the region. This affects behavior when pressing the up or down keys. Use ``-1`` if @@ -2070,20 +2112,20 @@ class HistoricPosition: __slots__ = ['pt', 'row', 'col', 'col_utf16', 'col_utf8'] - def __init__(self, pt, row, col, col_utf16, col_utf8): - self.pt: Point = pt + def __init__(self, pt: Point, row: int, col: int, col_utf16: int, col_utf8: int): + self.pt = pt """ The offset from the beginning of the `View`. """ - self.row: int = row + self.row = row """ The row the ``.py`` was in when the `HistoricPosition` was recorded. """ - self.col: int = col + self.col = col """ The column the ``.py`` was in when the `HistoricPosition` was recorded, in Unicode characters. """ - self.col_utf16: int = col_utf16 + self.col_utf16 = col_utf16 """ The value of ``.col``, but in UTF-16 code units. .. since:: 4075 """ - self.col_utf8: int = col_utf8 + self.col_utf8 = col_utf8 """ The value of ``.col``, but in UTF-8 code units. @@ -2106,24 +2148,24 @@ class TextChange: __slots__ = ['a', 'b', 'len_utf16', 'len_utf8', 'str'] - def __init__(self, pa, pb, len_utf16, len_utf8, str): - self.a: Point = pa + def __init__(self, pa: Point, pb: Point, len_utf16: int, len_utf8: int, str: str): + self.a = pa """ The beginning `Point` of the region that was modified. """ - self.b: Point = pb + self.b = pb """ The ending `Point` of the region that was modified. """ - self.len_utf16: int = len_utf16 + self.len_utf16 = len_utf16 """ The length of the old contents, in UTF-16 code units. .. since:: 4075 """ - self.len_utf8: int = len_utf8 + self.len_utf8 = len_utf8 """ The length of the old contents, in UTF-8 code units. .. since:: 4075 """ - self.str: str = str + self.str = str """ A string of the *new* contents of the region specified by ``.a`` and ``.b``. @@ -2144,7 +2186,7 @@ class Selection: This is primarily used to represent the textual selection. """ - def __init__(self, id): + def __init__(self, id: int): self.view_id = id def __iter__(self) -> Iterator[Region]: @@ -2227,7 +2269,7 @@ class Selection: return sublime_api.view_selection_contains(self.view_id, region.a, region.b) -def make_sheet(sheet_id): +def make_sheet(sheet_id: int) -> Sheet: if (sheet_id & 3) == 0: return TextSheet(sheet_id) elif (sheet_id & 3) == 1: @@ -2244,7 +2286,7 @@ class Sheet: contain a View, or an image preview. """ - def __init__(self, id): + def __init__(self, id: int): self.sheet_id = id def __hash__(self) -> int: @@ -2395,12 +2437,12 @@ class ContextStackFrame: __slots__ = ['context_name', 'source_file', 'source_location'] - def __init__(self, context_name, source_file, source_location): - self.context_name: str = context_name + def __init__(self, context_name: str, source_file: str, source_location: tuple[int, int]): + self.context_name = context_name """ The name of the context. """ - self.source_file: str = source_file + self.source_file = source_file """ The name of the file the context is defined in. """ - self.source_location: tuple[int, int] = source_location + self.source_location = source_location """ The location of the context inside the source file as a pair of row and column. Maybe be ``(-1, -1)`` if the location is unclear, like in @@ -2421,10 +2463,10 @@ class View: `View.clones()` or `Buffer.views()`. """ - def __init__(self, id): + def __init__(self, id: int): self.view_id = id self.selection = Selection(id) - self.settings_object = None + self.settings_object: Optional[Settings] = None def __len__(self) -> int: return self.size() @@ -2738,7 +2780,12 @@ class View: """ return sublime_api.view_find(self.view_id, pattern, start_pt, flags) - def find_all(self, pattern: str, flags=FindFlags.NONE, fmt: Optional[str] = None, extractions: Optional[list[str]] = None) -> list[Region]: + def find_all( + self, + pattern: str, + flags=FindFlags.NONE, + fmt: Optional[str] = None, + extractions: Optional[list[str]] = None) -> list[Region]: """ :param pattern: The regex or literal pattern to search by. :param flags: Controls various behaviors of find. See `FindFlags`. @@ -3149,11 +3196,17 @@ class View: else: return sublime_api.view_unfold_regions(self.view_id, x) - def add_regions(self, key: str, regions: list[Region], scope="", - icon="", flags=RegionFlags.NONE, annotations: list[str] = [], - annotation_color="", - on_navigate: Optional[Callable[[str], None]] = None, - on_close: Optional[Callable[[], None]] = None): + def add_regions( + self, + key: str, + regions: list[Region], + scope="", + icon="", + flags=RegionFlags.NONE, + annotations: list[str] = [], + annotation_color="", + on_navigate: Optional[Callable[[str], None]] = None, + on_close: Optional[Callable[[], None]] = None): """ Adds visual indicators to regions of text in the view. Indicators include icons in the gutter, underlines under the text, borders around @@ -3397,10 +3450,15 @@ class View: """ return sublime_api.view_show_popup_table(self.view_id, items, on_done, flags, -1) - def show_popup(self, content: str, flags=PopupFlags.NONE, location: Point = -1, - max_width: DIP = 320, max_height: DIP = 240, - on_navigate: Optional[Callable[[str], None]] = None, - on_hide: Optional[Callable[[], None]] = None): + def show_popup( + self, + content: str, + flags=PopupFlags.NONE, + location: Point = -1, + max_width: DIP = 320, + max_height: DIP = 240, + on_navigate: Optional[Callable[[str], None]] = None, + on_hide: Optional[Callable[[], None]] = None): """ Show a popup displaying HTML content. @@ -3454,10 +3512,13 @@ class View: """ sublime_api.view_preserve_auto_complete_on_focus_lost(self.view_id) - def export_to_html(self, - regions: Optional[Region | list[Region]] = None, - minihtml=False, enclosing_tags=False, - font_size=True, font_family=True): + def export_to_html( + self, + regions: Optional[Region | list[Region]] = None, + minihtml=False, + enclosing_tags=False, + font_size=True, + font_family=True): """ Generates an HTML string of the current view contents, including styling for syntax highlighting. @@ -3515,7 +3576,7 @@ class Buffer: .. since:: 4081 """ - def __init__(self, id): + def __init__(self, id: int): self.buffer_id = id def __hash__(self) -> int: @@ -3566,7 +3627,7 @@ class Settings: A ``dict`` like object that a settings hierarchy. """ - def __init__(self, id): + def __init__(self, id: int): self.settings_id = id def __getitem__(self, key: str) -> Value: @@ -3656,7 +3717,7 @@ class Settings: for key, value in kwargs.items(): self[key] = value - def get(self, key: str, default: Value = None) -> Value: + def get(self, key: str, default: Optional[Value] = None) -> Value: if default is not None: return sublime_api.settings_get_default(self.settings_id, key, default) else: @@ -3700,22 +3761,27 @@ class Phantom: the `View`, changes to the attributes will have no effect. """ - def __init__(self, region, content, layout, on_navigate=None): - self.region: Region = region + def __init__( + self, + region: Region, + content: str, + layout: PhantomLayout, + on_navigate: Optional[Callable[[str], None]] = None): + self.region = region """ The `Region` associated with the phantom. The phantom is displayed at the start of the `Region`. """ - self.content: str = content + self.content = content """ The HTML content of the phantom. """ - self.layout: PhantomLayout = layout + self.layout = layout """ How the phantom should be placed relative to the ``region``. """ - self.on_navigate: Optional[Callable[[str], None]] = on_navigate + self.on_navigate = on_navigate """ Called when a link in the HTML is clicked. The value of the ``href`` attribute is passed. """ - self.id = None + self.id: Optional[int] = None def __eq__(self, rhs: object) -> bool: # Note that self.id is not considered @@ -3744,18 +3810,18 @@ class PhantomSet: updating them and removing them from a `View`. """ - def __init__(self, view, key=""): + def __init__(self, view: View, key=""): """ """ - self.view: View = view + self.view = view """ The `View` the phantom set is attached to. """ - self.key: str = key + self.key = key """ A string used to group the phantoms together. """ - self.phantoms: [Phantom] = [] + self.phantoms: list[Phantom] = [] def __del__(self): for p in self.phantoms: @@ -3807,8 +3873,8 @@ class Html: __slots__ = ['data'] - def __init__(self, data): - self.data: str = data + def __init__(self, data: str): + self.data = data def __repr__(self) -> str: return f'Html({self.data})' @@ -3822,7 +3888,10 @@ class CompletionList: .. since:: 4050 """ - def __init__(self, completions: Optional[list[CompletionValue]] = None, flags=AutoCompleteFlags.NONE): + def __init__( + self, + completions: Optional[list[CompletionValue]] = None, + flags=AutoCompleteFlags.NONE): """ :param completions: If ``None`` is passed, the method `set_completions()` must be called @@ -3842,7 +3911,11 @@ class CompletionList: else: self.target = target - def set_completions(self, completions: list[CompletionValue], flags=AutoCompleteFlags.NONE): + def set_completions( + self, + completions: list[CompletionValue], + flags=AutoCompleteFlags.NONE + ): """ Sets the list of completions, allowing the list to be displayed to the user. @@ -3876,28 +3949,27 @@ class CompletionItem: def __init__( self, - trigger, + trigger: str, annotation="", completion="", completion_format=CompletionFormat.TEXT, kind=KIND_AMBIGUOUS, details="", flags=CompletionItemFlags.NONE): - - self.trigger: str = trigger + self.trigger = trigger """ Text to match against the user's input. """ - self.annotation: str = annotation + self.annotation = annotation """ A hint to draw to the right-hand side of the trigger. """ - self.completion: str = completion + self.completion = completion """ Text to insert if the completion is specified. If empty the `trigger` will be inserted instead. """ - self.completion_format: CompletionFormat = completion_format + self.completion_format = completion_format """ The format of the completion. See `CompletionFormat`. """ - self.kind: Kind = kind + self.kind = kind """ The kind of the completion. See `Kind`. """ - self.details: str = details + self.details = details """ An optional `minihtml` description of the completion, shown in the detail pane at the bottom of the auto complete window. @@ -4033,14 +4105,14 @@ class Syntax: __slots__ = ['path', 'name', 'hidden', 'scope'] - def __init__(self, path, name, hidden, scope): - self.path: str = path + def __init__(self, path: str, name: str, hidden: bool, scope: str): + self.path = path """ The packages path to the syntax file. """ - self.name: str = name + self.name = name """ The name of the syntax. """ - self.hidden: bool = hidden + self.hidden = hidden """ If the syntax is hidden from the user. """ - self.scope: str = scope + self.scope = scope """ The base scope name of the syntax. """ def __eq__(self, other: object) -> bool: @@ -4063,16 +4135,21 @@ class QuickPanelItem: __slots__ = ['trigger', 'details', 'annotation', 'kind'] - def __init__(self, trigger, details="", annotation="", kind=KIND_AMBIGUOUS): - self.trigger: str = trigger + def __init__( + self, + trigger: str, + details: str | list[str] | tuple[str] = "", + annotation="", + kind=KIND_AMBIGUOUS): + self.trigger = trigger """ Text to match against user's input. """ - self.details: str | list[str] | tuple[str] = details + self.details = details """ A `minihtml` string or list of strings displayed below the trigger. """ - self.annotation: str = annotation + self.annotation = annotation """ Hint to draw to the right-hand side of the row. """ - self.kind: Kind = kind + self.kind = kind """ The kind of the item. See `Kind`. """ def __repr__(self) -> str: @@ -4091,18 +4168,24 @@ class ListInputItem: __slots__ = ['text', 'value', 'details', 'annotation', 'kind'] - def __init__(self, text, value, details="", annotation="", kind=KIND_AMBIGUOUS): - self.text: str = text + def __init__( + self, + text: str, + value: Any, + details: str | list[str] | tuple[str] = "", + annotation="", + kind=KIND_AMBIGUOUS): + self.text = text """ Text to match against the user's input. """ - self.value: Any = value + self.value = value """ A `Value` passed to the command if the row is selected. """ - self.details: str | list[str] | tuple[str] = details + self.details = details """ A `minihtml` string or list of strings displayed below the trigger. """ - self.annotation: str = annotation + self.annotation = annotation """ Hint to draw to the right-hand side of the row. """ - self.kind: Kind = kind + self.kind = kind """ The kind of the item. See `Kind`. """ def __repr__(self) -> str: @@ -4122,16 +4205,16 @@ class SymbolRegion: __slots__ = ['name', 'region', 'syntax', 'type', 'kind'] - def __init__(self, name, region, syntax, type, kind): - self.name: str = name + def __init__(self, name: str, region: Region, syntax: str, type: SymbolType, kind: Kind): + self.name = name """ The name of the symbol. """ - self.region: Region = region + self.region = region """ The location of the symbol within the `View`. """ - self.syntax: str = syntax + self.syntax = syntax """ The name of the syntax for the symbol. """ - self.type: SymbolType = type + self.type = type """ The type of the symbol. See `SymbolType`. """ - self.kind: Kind = kind + self.kind = kind """ The kind of the symbol. See `Kind`. """ def __repr__(self) -> str: @@ -4149,20 +4232,20 @@ class SymbolLocation: __slots__ = ['path', 'display_name', 'row', 'col', 'syntax', 'type', 'kind'] - def __init__(self, path, display_name, row, col, syntax, type, kind): - self.path: str = path + def __init__(self, path: str, display_name: str, row: int, col: int, syntax: str, type: SymbolType, kind: Kind): + self.path = path """ The filesystem path to the file containing the symbol. """ - self.display_name: str = display_name + self.display_name = display_name """ The project-relative path to the file containing the symbol. """ - self.row: int = row + self.row = row """ The row of the file the symbol is contained on. """ - self.col: int = col + self.col = col """ The column of the row that the symbol is contained on. """ - self.syntax: str = syntax + self.syntax = syntax """ The name of the syntax for the symbol. """ - self.type: SymbolType = type + self.type = type """ The type of the symbol. See `SymbolType`. """ - self.kind: Kind = kind + self.kind = kind """ The kind of the symbol. See `Kind`. """ def __repr__(self) -> str: ```
rchl commented 2 years ago

As for the patch:

-    def __init__(self, a: Point, b: Optional[Point] = None, xpos: DIP = -1):
+    def __init__(self, a: Point, b: Optional[Point]=None, xpos: DIP=-1):

The original version is actually "better". Linters (flake8) would complain about your change with default settings.

-    def __init__(self, id):
-        self.view_id = id
-        self.selection = Selection(id)
-        self.settings_object = None
+    def __init__(self, id: int):
+        self.view_id: int = id
+        self.selection: Selection = Selection(id)
+        self.settings_object: Optional[Selection] = None

I would personally skip explicit type when assigning to class properties in the constructor as that type can be clearly inferred from the value. That of course doesn't apply to self.settings_object in this case which starts as None. This is a bit of a preference though so you can ignore my suggestion.

deathaxe commented 2 years ago

I was always under impression that = in default value assignments in parameter lists must not be surrounded by spaces. Did that change with type hints being present?

EDIT: Indeed, parameters with and without type hints are treated different.

.\sublime.py:1294:61: E251 unexpected spaces around keyword / parameter equals        
.\sublime.py:4069:46: E252 missing whitespace around parameter equals

I would personally skip explicit type when assigning to class properties

Makes sense. Just added missing ones as those existed in various constructors (e.g.: QuickPanalItem) before.

rchl commented 2 years ago

I was always under impression that = in default value assignments in parameter lists must not be surrounded by spaces. Did that change with type hints being present?

Yes, it seems so. flake8 (or pycodestyle) prefers those variants:

def foo(test='test') -> None:
  pass

def foo(test: str = 'test') -> None:
  pass
deathaxe commented 2 years ago

Makes sense, TBH. I'd prefer it this way, too.

deathaxe commented 2 years ago

I've updated my patch according to review commands.

  1. fix various flake8 issues (e.g. missing double whitespace between Enum classes)
  2. fix whitspace in default value assignments
  3. drop explicit type hints in case type is specified by assigned value
    TBH: I'd prefer to explicitly always add typehints to all method/function parameters.
  4. normalized some method/function parameter list indentations. Seems various coding styles are applied across the module.
kaste commented 2 years ago

Just a random note as I was falling into this issue. You have attribute/member comments here like so

        self.trigger: str = trigger
        """ Text to match against user's input. """
        self.details: str | list[str] | tuple[str] = details
        """
        A `minihtml` string or list of strings displayed below the trigger.
        """
        self.annotation: str = annotation
        """ Hint to draw to the right-hand side of the row. """
        self.kind: Kind = kind
        """ The kind of the item. See `Kind`. """

It is a python/sphinx standard to use #: comments for that and this often better to read:

        #: Text to match against user's input.
        self.trigger: str = trigger

        #: A `minihtml` string or list of strings displayed below the trigger.
        self.details: str | list[str] | tuple[str] = details

        #: Hint to draw to the right-hand side of the row. """
        self.annotation: str = annotation

        self.kind: Kind = kind  #: The kind of the item. See `Kind`.
rchl commented 2 years ago

Pyright doesn't seem to support the #: format (when showing symbol documentation) but it supports the current one.

kaste commented 2 years ago

They totally should, look how nicely this is https://github.com/pytest-dev/pytest/blob/main/src/_pytest/reports.py#L272 https://github.com/pallets/flask/blob/main/src/flask/app.py#L207 🤷