mypy: Reduce errors on muctab.py by a lot

This commit is contained in:
mathieui 2020-05-28 21:31:18 +02:00
parent 4fae01c09a
commit c9e219c140
12 changed files with 312 additions and 218 deletions

View file

@ -15,7 +15,17 @@ import shutil
import time
import uuid
from collections import defaultdict
from typing import Callable, Dict, List, Optional, Set, Tuple, Type
from typing import (
cast,
Callable,
Dict,
List,
Optional,
Set,
Tuple,
Type,
TypeVar,
)
from xml.etree import ElementTree as ET
from functools import partial
@ -65,6 +75,7 @@ from poezio.ui.types import Message, InfoMessage
log = logging.getLogger(__name__)
T = TypeVar('T', bound=tabs.Tab)
class Core:
"""
@ -99,8 +110,10 @@ class Core:
# that are displayed in almost all tabs, in an
# information window.
self.information_buffer = TextBuffer()
self.information_win_size = config.get(
'info_win_height', section='var')
self.information_win_size = cast(
int,
config.get('info_win_height', section='var'),
)
self.information_win = windows.TextWin(300)
self.information_buffer.add_window(self.information_win)
self.left_tab_win = None
@ -813,7 +826,7 @@ class Core:
####################### XMPP-related actions ##################################
def get_status(self) -> str:
def get_status(self) -> Status:
"""
Get the last status that was previously set
"""
@ -1016,7 +1029,7 @@ class Core:
### Tab getters ###
def get_tabs(self, cls: Type[tabs.Tab] = None) -> List[tabs.Tab]:
def get_tabs(self, cls: Type[T] = None) -> List[T]:
"Get all the tabs of a type"
if cls is None:
return self.tabs.get_tabs()
@ -1324,7 +1337,7 @@ class Core:
if tab.name.startswith(room_name):
tab.activate(reason=reason)
def on_user_changed_status_in_private(self, jid: JID, status: str) -> None:
def on_user_changed_status_in_private(self, jid: JID, status: Status) -> None:
tab = self.tabs.by_name_and_class(jid, tabs.ChatTab)
if tab is not None: # display the message in private
tab.update_status(status)
@ -1652,7 +1665,7 @@ class Core:
return
else:
scr = self.stdscr
tabs.Tab.resize(scr)
tabs.Tab.initial_resize(scr)
self.resize_global_info_bar()
self.resize_global_information_win()
for tab in self.tabs:
@ -2105,7 +2118,7 @@ class Core:
self.bookmarks.get_remote(self.xmpp, self.information,
_join_remote_only)
def room_error(self, error, room_name):
def room_error(self, error: IqError, room_name: str) -> None:
"""
Display the error in the tab
"""

View file

@ -1,6 +1,8 @@
"""
Module defining structures useful to the core class and related methods
"""
from dataclasses import dataclass
from typing import Any, Callable, List, Dict
__all__ = [
'ERROR_AND_STATUS_CODES', 'DEPRECATED_ERRORS', 'POSSIBLE_SHOW', 'Status',
@ -51,23 +53,11 @@ POSSIBLE_SHOW = {
}
@dataclass
class Status:
__slots__ = ('show', 'message')
def __init__(self, show, message):
self.show = show
self.message = message
class Command:
__slots__ = ('func', 'desc', 'comp', 'short_desc', 'usage')
def __init__(self, func, desc, comp, short_desc, usage):
self.func = func
self.desc = desc
self.comp = comp
self.short_desc = short_desc
self.usage = usage
show: str
message: str
class Completion:
@ -75,8 +65,13 @@ class Completion:
A completion result essentially currying the input completion call.
"""
__slots__ = ['func', 'args', 'kwargs', 'comp_list']
def __init__(self, func, comp_list, *args, **kwargs):
def __init__(
self,
func: Callable[..., Any],
comp_list: List[str],
*args: Any,
**kwargs: Any
) -> None:
self.func = func
self.comp_list = comp_list
self.args = args
@ -84,3 +79,12 @@ class Completion:
def run(self):
return self.func(self.comp_list, *self.args, **self.kwargs)
@dataclass
class Command:
__slots__ = ('func', 'desc', 'comp', 'short_desc', 'usage')
func: Callable[..., Any]
desc: str
comp: Callable[['windows.Input'], Completion]
short_desc: str
usage: str

View file

@ -347,16 +347,16 @@ class Tabs:
if new_pos < len(self._tabs):
old_tab = self._tabs[old_pos]
self._tabs[new_pos], self._tabs[
old_pos] = old_tab, tabs.GapTab(self)
old_pos] = old_tab, tabs.GapTab(None)
else:
self._tabs.append(self._tabs[old_pos])
self._tabs[old_pos] = tabs.GapTab(self)
self._tabs[old_pos] = tabs.GapTab(None)
else:
if new_pos > old_pos:
self._tabs.insert(new_pos, tab)
self._tabs[old_pos] = tabs.GapTab(self)
self._tabs[old_pos] = tabs.GapTab(None)
elif new_pos < old_pos:
self._tabs[old_pos] = tabs.GapTab(self)
self._tabs[old_pos] = tabs.GapTab(None)
self._tabs.insert(new_pos, tab)
else:
return False

View file

@ -5,7 +5,8 @@ upstream.
TODO: Check that they are fixed and remove those hacks
"""
from slixmpp.stanza import Message
from typing import Callable, Any
from slixmpp import Message, Iq, ClientXMPP
from slixmpp.xmlstream import ET
import logging
@ -25,7 +26,7 @@ def has_identity(xmpp, jid, identity, on_true=None, on_false=None):
xmpp.plugin['xep_0030'].get_info(jid=jid, callback=_cb)
def get_room_form(xmpp, room, callback):
def get_room_form(xmpp: ClientXMPP, room: str, callback: Callable[[Iq], Any]):
def _cb(result):
if result["type"] == "error":
return callback(None)

View file

@ -104,7 +104,7 @@ def main():
logger.create_logger()
from poezio import roster
roster.create_roster()
roster.roster.reset()
from poezio.core.core import Core

View file

@ -10,6 +10,8 @@ Defines the Roster and RosterGroup classes
import logging
log = logging.getLogger(__name__)
from typing import List
from poezio.config import config
from poezio.contact import Contact
from poezio.roster_sorting import SORTING_METHODS, GROUP_SORTING_METHODS
@ -18,6 +20,7 @@ from os import path as p
from datetime import datetime
from poezio.common import safeJID
from slixmpp.exceptions import IqError, IqTimeout
from slixmpp import JID
class Roster:
@ -29,6 +32,22 @@ class Roster:
DEFAULT_FILTER = (lambda x, y: None, None)
def __init__(self):
self.__node = None
# A tuple(function, *args) function to filter contacts
# on search, for example
self.contact_filter = self.DEFAULT_FILTER
self.groups = {}
self.contacts = {}
self.length = 0
self.connected = 0
self.folded_groups = []
# Used for caching roster infos
self.last_built = datetime.now()
self.last_modified = datetime.now()
def reset(self):
"""
node: the RosterSingle from slixmpp
"""
@ -143,7 +162,7 @@ class Roster:
"""Subscribe to a jid"""
self.__node.subscribe(jid)
def jids(self):
def jids(self) -> List[JID]:
"""List of the contact JIDS"""
l = []
for key in self.__node.keys():
@ -335,11 +354,6 @@ class RosterGroup:
return len([1 for contact in self.contacts if len(contact)])
def create_roster():
"Create the global roster object"
global roster
roster = Roster()
# Shared roster object
roster = None
roster = Roster()

View file

@ -28,6 +28,7 @@ from typing import (
List,
Optional,
Union,
Tuple,
TYPE_CHECKING,
)
@ -52,6 +53,8 @@ from slixmpp import JID, InvalidJID, Message as SMessage
if TYPE_CHECKING:
from _curses import _CursesWindow # pylint: disable=E0611
from poezio.size_manager import SizeManager
from poezio.core.core import Core
log = logging.getLogger(__name__)
@ -117,7 +120,7 @@ class Tab:
height = 1
width = 1
def __init__(self, core):
def __init__(self, core: 'Core'):
self.core = core
self.nb = 0
if not hasattr(self, 'name'):
@ -133,7 +136,7 @@ class Tab:
self.commands = {} # and their own commands
@property
def size(self) -> int:
def size(self) -> 'SizeManager':
return self.core.size
@staticmethod
@ -196,7 +199,7 @@ class Tab:
self._state = 'normal'
@staticmethod
def resize(scr: '_CursesWindow'):
def initial_resize(scr: '_CursesWindow'):
Tab.height, Tab.width = scr.getmaxyx()
windows.base_wins.TAB_WIN = scr
@ -327,7 +330,7 @@ class Tab:
else:
return False
def refresh_tab_win(self):
def refresh_tab_win(self) -> None:
if config.get('enable_vertical_tab_list'):
left_tab_win = self.core.left_tab_win
if left_tab_win and not self.size.core_degrade_x:
@ -371,12 +374,12 @@ class Tab:
"""
pass
def update_commands(self):
def update_commands(self) -> None:
for c in self.plugin_commands:
if c not in self.commands:
self.commands[c] = self.plugin_commands[c]
def update_keys(self):
def update_keys(self) -> None:
for k in self.plugin_keys:
if k not in self.key_func:
self.key_func[k] = self.plugin_keys[k]
@ -435,7 +438,7 @@ class Tab:
"""
pass
def on_close(self):
def on_close(self) -> None:
"""
Called when the tab is to be closed
"""
@ -443,7 +446,7 @@ class Tab:
self.input.on_delete()
self.closed = True
def matching_names(self) -> List[str]:
def matching_names(self) -> List[Tuple[int, str]]:
"""
Returns a list of strings that are used to name a tab with the /win
command. For example you could switch to a tab that returns
@ -532,7 +535,7 @@ class ChatTab(Tab):
desc='Fix the last message with whatever you want.',
shortdesc='Correct the last message.',
completion=self.completion_correct)
self.chat_state = None
self.chat_state = None # type: Optional[str]
self.update_commands()
self.update_keys()
@ -667,11 +670,11 @@ class ChatTab(Tab):
self._text_buffer.messages = []
self.text_win.rebuild_everything(self._text_buffer)
def check_send_chat_state(self):
def check_send_chat_state(self) -> bool:
"If we should send a chat state"
return True
def send_chat_state(self, state, always_send=False):
def send_chat_state(self, state: str, always_send: bool = False) -> None:
"""
Send an empty chatstate message
"""
@ -691,9 +694,8 @@ class ChatTab(Tab):
x = ET.Element('{%s}x' % NS_MUC_USER)
msg.append(x)
msg.send()
return True
def send_composing_chat_state(self, empty_after):
def send_composing_chat_state(self, empty_after: bool) -> None:
"""
Send the "active" or "composing" chatstate, depending
on the the current status of the input
@ -729,7 +731,7 @@ class ChatTab(Tab):
self.core.add_timed_event(new_event)
self.timed_event_not_paused = new_event
def cancel_paused_delay(self):
def cancel_paused_delay(self) -> None:
"""
Remove that event from the list and set it to None.
Called for example when the input is emptied, or when the message
@ -741,7 +743,7 @@ class ChatTab(Tab):
self.core.remove_timed_event(self.timed_event_not_paused)
self.timed_event_not_paused = None
def set_last_sent_message(self, msg, correct=False):
def set_last_sent_message(self, msg: SMessage, correct: bool = False) -> None:
"""Ensure last_sent_message is set with the correct attributes"""
if correct:
# XXX: Is the copy needed. Is the object passed here reused
@ -751,7 +753,7 @@ class ChatTab(Tab):
self.last_sent_message = msg
@command_args_parser.raw
def command_correct(self, line):
def command_correct(self, line: str) -> None:
"""
/correct <fixed message>
"""
@ -777,7 +779,7 @@ class ChatTab(Tab):
return self.core.status.show in ('xa', 'away') or\
(hasattr(self, 'directed_presence') and not self.directed_presence)
def move_separator(self):
def move_separator(self) -> None:
self.text_win.remove_line_separator()
self.text_win.add_line_separator(self._text_buffer)
self.text_win.refresh()
@ -786,7 +788,7 @@ class ChatTab(Tab):
def get_conversation_messages(self):
return self._text_buffer.messages
def check_scrolled(self):
def check_scrolled(self) -> None:
if self.text_win.pos != 0:
self.state = 'scrolled'

File diff suppressed because it is too large Load diff

View file

@ -145,7 +145,7 @@ class PrivateTab(OneToOneTab):
@refresh_wrapper.always
@command_args_parser.raw
def command_say(self, line, attention=False, correct=False):
def command_say(self, line: str, attention: bool = False, correct: bool = False) -> None:
if not self.on:
return
our_jid = JID(self.jid.bare)

View file

@ -32,6 +32,7 @@ from poezio.ui.types import (
if TYPE_CHECKING:
from poezio.windows.text_win import TextWin
from poezio.user import User
class CorrectionError(Exception):
@ -249,7 +250,7 @@ class TextBuffer:
new_id: str,
highlight: bool = False,
time: Optional[datetime] = None,
user: Optional[str] = None,
user: Optional['User'] = None,
jid: Optional[str] = None) -> Message:
"""
Correct a message in a text buffer.

View file

@ -55,7 +55,7 @@ class User:
else:
self.color = choice(get_theme().LIST_COLOR_NICKNAMES)
def set_deterministic_color(self):
def set_deterministic_color(self) -> None:
theme = get_theme()
if theme.ccg_palette:
# use XEP-0392 CCG

View file

@ -3,6 +3,8 @@ Module defining all the "info wins", ie the bar which is on top of the
info buffer in normal tabs
"""
from typing import Optional, Dict, TYPE_CHECKING, Any
import logging
log = logging.getLogger(__name__)
@ -13,6 +15,11 @@ from poezio.windows.base_wins import Win
from poezio.ui.funcs import truncate_nick
from poezio.theming import get_theme, to_curses_attr
if TYPE_CHECKING:
from poezio.user import User
from poezio.tabs import MucTab
from poezio.windows import TextWin
class InfoWin(Win):
"""
@ -260,10 +267,16 @@ class MucInfoWin(InfoWin):
__slots__ = ()
def __init__(self):
def __init__(self) -> None:
InfoWin.__init__(self)
def refresh(self, room, window=None, user=None, information=None):
def refresh(
self,
room: 'MucTab',
window: Optional['TextWin'] = None,
user: Optional['User'] = None,
information: Optional[Dict[str, Any]] = None
) -> None:
log.debug('Refresh: %s', self.__class__.__name__)
self._win.erase()
self.write_room_name(room)