diff --git a/gajim/atom_window.py b/gajim/atom_window.py index 93ca8b0c1..5ab727fce 100644 --- a/gajim/atom_window.py +++ b/gajim/atom_window.py @@ -17,6 +17,9 @@ # You should have received a copy of the GNU General Public License # along with Gajim. If not, see . +from typing import List # pylint: disable=unused-import +from typing import Any # pylint: disable=unused-import + from gi.repository import Gdk from gi.repository import GLib @@ -26,7 +29,7 @@ from gajim.common import i18n class AtomWindow: window = None - entries = [] + entries = [] # type: List[Any] @classmethod def newAtomEntry(cls, entry): diff --git a/gajim/chat_control.py b/gajim/chat_control.py index ac8da8eb2..044ee53d5 100644 --- a/gajim/chat_control.py +++ b/gajim/chat_control.py @@ -23,12 +23,21 @@ # You should have received a copy of the GNU General Public License # along with Gajim. If not, see . +from typing import ClassVar # pylint: disable=unused-import +from typing import Type # pylint: disable=unused-import + import os import time + from gi.repository import Gtk from gi.repository import Gio from gi.repository import Pango from gi.repository import GLib +from nbxmpp.protocol import NS_XHTML, NS_XHTML_IM, NS_FILE, NS_MUC +from nbxmpp.protocol import NS_JINGLE_RTP_AUDIO, NS_JINGLE_RTP_VIDEO +from nbxmpp.protocol import NS_JINGLE_ICE_UDP, NS_JINGLE_FILE_TRANSFER_5 +from nbxmpp.protocol import NS_CHATSTATES + from gajim import gtkgui_helpers from gajim import gui_menu_builder from gajim import message_control @@ -41,14 +50,11 @@ from gajim.common import helpers from gajim.common import ged from gajim.common import i18n from gajim.common.contacts import GC_Contact -from nbxmpp.protocol import NS_XHTML, NS_XHTML_IM, NS_FILE, NS_MUC -from nbxmpp.protocol import NS_JINGLE_RTP_AUDIO, NS_JINGLE_RTP_VIDEO -from nbxmpp.protocol import NS_JINGLE_ICE_UDP, NS_JINGLE_FILE_TRANSFER_5 -from nbxmpp.protocol import NS_CHATSTATES from gajim.common.connection_handlers_events import MessageOutgoingEvent from gajim.common.const import AvatarSize, KindConstant from gajim.command_system.implementation.hosts import ChatCommands +from gajim.command_system.framework import CommandHost # pylint: disable=unused-import from gajim.chat_control_base import ChatControlBase ################################################################################ @@ -69,7 +75,7 @@ class ChatControl(ChatControlBase): # Set a command host to bound to. Every command given through a chat will be # processed with this command host. - COMMAND_HOST = ChatCommands + COMMAND_HOST = ChatCommands # type: ClassVar[Type[CommandHost]] def __init__(self, parent_win, contact, acct, session, resource=None): ChatControlBase.__init__(self, self.TYPE_ID, parent_win, diff --git a/gajim/common/app.py b/gajim/common/app.py index eefed71d0..b8dd434a1 100644 --- a/gajim/common/app.py +++ b/gajim/common/app.py @@ -24,8 +24,11 @@ # You should have received a copy of the GNU General Public License # along with Gajim. If not, see . +from typing import Any # pylint: disable=unused-import from typing import Dict # pylint: disable=unused-import from typing import List # pylint: disable=unused-import +from typing import Optional # pylint: disable=unused-import +from typing import cast import os import sys @@ -44,21 +47,25 @@ from gajim.common import ged as ged_module from gajim.common.contacts import LegacyContactsAPI from gajim.common.events import Events from gajim.common.css_config import CSSConfig +from gajim.common.types import NetworkEventsControllerT # pylint: disable=unused-import +from gajim.common.types import InterfaceT # pylint: disable=unused-import +from gajim.common.types import LoggerT # pylint: disable=unused-import +from gajim.common.types import ConnectionT # pylint: disable=unused-import -interface = None # type: gajim.interface.Interface +interface = cast(InterfaceT, None) thread_interface = lambda *args: None # Interface to run a thread and then a callback config = c_config.Config() version = gajim.__version__ -connections = {} # 'account name': 'account (connection.Connection) instance' -avatar_cache = {} +connections = {} # type: Dict[str, ConnectionT] +avatar_cache = {} # type: Dict[str, Dict[str, Any]] ipython_window = None app = None # Gtk.Application ged = ged_module.GlobalEventsDispatcher() # Global Events Dispatcher -nec = None # type: gajim.common.nec.NetworkEventsController +nec = cast(NetworkEventsControllerT, None) plugin_manager = None # Plugins Manager -logger = None # type: gajim.common.logger.Logger +logger = cast(LoggerT, None) # For backwards compatibility needed # some plugins use that @@ -113,7 +120,7 @@ nicks = {} # type: Dict[str, str] # to something else than offline # can also contain account/transport_jid to block notifications for contacts # from this transport -block_signed_in_notifications = {} +block_signed_in_notifications = {} # type: Dict[str, bool] # type of each connection (ssl, tls, tcp, ...) con_types = {} # type: Dict[str, Optional[str]] @@ -153,10 +160,10 @@ gajim_common_features = [nbxmpp.NS_BYTESTREAM, nbxmpp.NS_SI, nbxmpp.NS_FILE, nbxmpp.NS_EME, 'urn:xmpp:avatar:metadata+notify'] # Optional features gajim supports per account -gajim_optional_features = {} +gajim_optional_features = {} # type: Dict[str, List[str]] # Capabilities hash per account -caps_hash = {} +caps_hash = {} # type: Dict[str, List[str]] _dependencies = { 'PYTHON-DBUS': False, diff --git a/gajim/common/config.py b/gajim/common/config.py index efe1237d5..e17c769c2 100644 --- a/gajim/common/config.py +++ b/gajim/common/config.py @@ -27,6 +27,11 @@ # You should have received a copy of the GNU General Public License # along with Gajim. If not, see . +from typing import Any # pylint: disable=unused-import +from typing import Dict # pylint: disable=unused-import +from typing import List # pylint: disable=unused-import +from typing import Tuple # pylint: disable=unused-import + import re from enum import IntEnum, unique @@ -287,7 +292,7 @@ class Config: 'use_keyring': [opt_bool, True, _('If true, Gajim will use the Systems Keyring to store account passwords.')], 'pgp_encoding': [opt_str, '', _('Sets the encoding used by python-gnupg'), True], 'remote_commands': [opt_bool, False, _('If true, Gajim will execute XEP-0146 Commands.')], - }, {}) + }, {}) # type: Tuple[Dict[str, List[Any]], Dict[Any, Any]] __options_per_key = { 'accounts': ({ @@ -436,7 +441,7 @@ class Config: 'plugins': ({ 'active': [opt_bool, False, _('State whether plugins should be activated on startup (this is saved on Gajim exit). This option SHOULD NOT be used to (de)activate plug-ins. Use GUI instead.')], }, {}), - } + } # type: Dict[str, Tuple[Dict[str, List[Any]], Dict[Any, Any]]] statusmsg_default = { _('Sleeping'): ['ZZZZzzzzzZZZZZ', 'inactive', 'sleeping', '', 'sleepy', ''], diff --git a/gajim/common/const.py b/gajim/common/const.py index 0ce7c118b..471a73459 100644 --- a/gajim/common/const.py +++ b/gajim/common/const.py @@ -4,10 +4,10 @@ from collections import namedtuple from gajim.common.i18n import _ Option = namedtuple('Option', 'kind label type value name callback data desc enabledif props') -Option.__new__.__defaults__ = (None,) * len(Option._fields) +Option.__new__.__defaults__ = (None,) * len(Option._fields) # type: ignore DialogButton = namedtuple('DialogButton', 'text callback action') -DialogButton.__new__.__defaults__ = (None, None) +DialogButton.__new__.__defaults__ = (None, None) # type: ignore @unique diff --git a/gajim/common/file_props.py b/gajim/common/file_props.py index 9cc6a9440..deceedfb2 100644 --- a/gajim/common/file_props.py +++ b/gajim/common/file_props.py @@ -17,8 +17,14 @@ Exception: this class should not be instatiated True """ +from typing import Any # pylint: disable=unused-import +from typing import ClassVar # pylint: disable=unused-import +from typing import Dict # pylint: disable=unused-import +from typing import Tuple # pylint: disable=unused-import + + class FilesProp: - _files_props = {} + _files_props = {} # type: ClassVar[Dict[Tuple[str, str], Any]] def __init__(self): raise Exception('this class should not be instantiated') diff --git a/gajim/common/jingle_content.py b/gajim/common/jingle_content.py index 39d8f7224..92c1f3b4d 100644 --- a/gajim/common/jingle_content.py +++ b/gajim/common/jingle_content.py @@ -16,14 +16,19 @@ Handles Jingle contents (XEP 0166) """ +from typing import Any # pylint: disable=unused-import +from typing import Dict # pylint: disable=unused-import + import os + +import nbxmpp + from gajim.common import app from gajim.common import configpaths -import nbxmpp from gajim.common.jingle_xtls import SELF_SIGNED_CERTIFICATE from gajim.common.jingle_xtls import load_cert_file -contents = {} +contents = {} # type: Dict[str, Any] def get_jingle_content(node): namespace = node.getNamespace() diff --git a/gajim/common/jingle_transport.py b/gajim/common/jingle_transport.py index fce1767d6..9d326df15 100644 --- a/gajim/common/jingle_transport.py +++ b/gajim/common/jingle_transport.py @@ -16,16 +16,21 @@ Handles Jingle Transports (currently only ICE-UDP) """ +from typing import Any # pylint: disable=unused-import +from typing import Dict # pylint: disable=unused-import + import logging import socket from enum import IntEnum, unique + import nbxmpp + from gajim.common import app log = logging.getLogger('gajim.c.jingle_transport') -transports = {} +transports = {} # type: Dict[str, Any] def get_jingle_transport(node): namespace = node.getNamespace() diff --git a/gajim/common/passwords.py b/gajim/common/passwords.py index b1ccd1f6f..fda112a24 100644 --- a/gajim/common/passwords.py +++ b/gajim/common/passwords.py @@ -28,10 +28,12 @@ __all__ = ['get_password', 'save_password'] log = logging.getLogger('gajim.password') -keyring = None + try: import keyring + KEYRING_AVAILABLE = True except ImportError: + KEYRING_AVAILABLE = False log.debug('python-keyring missing, falling back to plaintext storage') @@ -83,7 +85,7 @@ class PasswordStorageManager(PasswordStorage): """ # TODO: handle disappearing backends - if app.config.get('use_keyring') and keyring: + if app.config.get('use_keyring') and KEYRING_AVAILABLE: self.secret = SecretPasswordStorage() def get_password(self, account_name): diff --git a/gajim/common/pep.py b/gajim/common/pep.py index fe9533226..f936fe3e9 100644 --- a/gajim/common/pep.py +++ b/gajim/common/pep.py @@ -19,11 +19,14 @@ # You should have received a copy of the GNU General Public License # along with Gajim. If not, see . +from typing import Any # pylint: disable=unused-import +from typing import List # pylint: disable=unused-import + import logging -log = logging.getLogger('gajim.c.pep') from gajim.common import app +log = logging.getLogger('gajim.c.pep') class AbstractPEP: @@ -75,4 +78,4 @@ class AbstractPEP: pass -SUPPORTED_PERSONAL_USER_EVENTS = [] +SUPPORTED_PERSONAL_USER_EVENTS = [] # type: List[Any] diff --git a/gajim/common/rst_xhtml_generator.py b/gajim/common/rst_xhtml_generator.py index d0fc86df4..e198aea22 100644 --- a/gajim/common/rst_xhtml_generator.py +++ b/gajim/common/rst_xhtml_generator.py @@ -18,11 +18,11 @@ # along with Gajim. If not, see . try: - from docutils import io + from docutils import io # type: ignore from docutils.core import Publisher from docutils.parsers.rst import roles - from docutils import nodes, utils - from docutils.parsers.rst.roles import set_classes + from docutils import nodes, utils # type: ignore + from docutils.parsers.rst.roles import set_classes # type: ignore except ImportError: print("Requires docutils 0.4 for set_classes to be available") def create_xhtml(text): diff --git a/gajim/common/socks5.py b/gajim/common/socks5.py index bdc78a528..a37ce0e27 100644 --- a/gajim/common/socks5.py +++ b/gajim/common/socks5.py @@ -799,7 +799,7 @@ class Socks5: return self.file_props.received_len return None - def disconnect(self): + def disconnect(self, *args, **kwargs): """ Close open descriptors and remover socket descr. from idleque """ diff --git a/gajim/common/types.py b/gajim/common/types.py index 7d467add3..5f9b6a685 100644 --- a/gajim/common/types.py +++ b/gajim/common/types.py @@ -33,6 +33,15 @@ if TYPE_CHECKING: from gajim.common.contacts import Contact from gajim.common.contacts import GC_Contact from gajim.common.nec import NetworkEvent + from gajim.common.nec import NetworkEventsController + from gajim.common.logger import Logger + + from gajim.gui_interface import Interface + + +NetworkEventsControllerT = Union['NetworkEventsController'] +InterfaceT = Union['Interface'] +LoggerT = Union['Logger'] ConnectionT = Union['Connection', 'ConnectionZeroconf'] ContactT = Union['Contact', 'GC_Contact'] diff --git a/gajim/common/zeroconf/client_zeroconf.py b/gajim/common/zeroconf/client_zeroconf.py index 83e14c42d..6cc52a1a9 100644 --- a/gajim/common/zeroconf/client_zeroconf.py +++ b/gajim/common/zeroconf/client_zeroconf.py @@ -19,6 +19,7 @@ from gajim.common import app import nbxmpp from nbxmpp.idlequeue import IdleObject from nbxmpp import dispatcher_nb, simplexml +from nbxmpp.plugin import PlugIn from nbxmpp.plugin import * from nbxmpp.transports_nb import DATA_RECEIVED, DATA_SENT, DATA_ERROR from gajim.common.zeroconf import zeroconf diff --git a/gajim/common/zeroconf/zeroconf.py b/gajim/common/zeroconf/zeroconf.py index ad479cd26..37d4e2fba 100644 --- a/gajim/common/zeroconf/zeroconf.py +++ b/gajim/common/zeroconf/zeroconf.py @@ -14,8 +14,11 @@ # You should have received a copy of the GNU General Public License # along with Gajim. If not, see . +from typing import Any # pylint: disable=unused-import + from enum import IntEnum, unique + @unique class Constant(IntEnum): NAME = 0 @@ -54,7 +57,7 @@ def test_zeroconf(): if test_avahi(): from gajim.common.zeroconf import zeroconf_avahi - Zeroconf = zeroconf_avahi.Zeroconf + Zeroconf = zeroconf_avahi.Zeroconf # type: Any elif test_bonjour(): from gajim.common.zeroconf import zeroconf_bonjour Zeroconf = zeroconf_bonjour.Zeroconf diff --git a/gajim/dialogs.py b/gajim/dialogs.py index 1dc8977e5..3c72b82a5 100644 --- a/gajim/dialogs.py +++ b/gajim/dialogs.py @@ -25,18 +25,22 @@ # You should have received a copy of the GNU General Public License # along with Gajim. If not, see . -from gi.repository import Gtk -from gi.repository import Gdk -from gi.repository import GLib +from typing import Dict # pylint: disable=unused-import +from typing import List # pylint: disable=unused-import +from typing import Tuple # pylint: disable=unused-import import os import logging +from random import randrange + +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import GLib from gajim import gtkgui_helpers from gajim import vcard from gajim import dataforms_widget -from random import randrange from gajim.common import ged from gajim.common.i18n import _ from gajim.common.const import ACTIVITIES @@ -1363,7 +1367,7 @@ class ProgressDialog: class TransformChatToMUC: # Keep a reference on windows so garbage collector don't restroy them - instances = [] + instances = [] # type: List[TransformChatToMUC] def __init__(self, account, jids, preselected=None): """ This window is used to trasform a one-to-one chat to a MUC. We do 2 @@ -1584,7 +1588,7 @@ class ResourceConflictDialog(TimeoutDialog, InputDialog): class VoIPCallReceivedDialog: - instances = {} + instances = {} # type: Dict[Tuple[str, str], VoIPCallReceivedDialog] def __init__(self, account, contact_jid, sid, content_types): self.instances[(contact_jid, sid)] = self self.account = account diff --git a/gajim/gtk/single_message.py b/gajim/gtk/single_message.py index de5798177..c48d5a0f6 100644 --- a/gajim/gtk/single_message.py +++ b/gajim/gtk/single_message.py @@ -12,6 +12,8 @@ # You should have received a copy of the GNU General Public License # along with Gajim. If not, see . +from typing import List # pylint: disable=unused-import + from gi.repository import Gdk from gi.repository import GLib @@ -40,7 +42,7 @@ class SingleMessageWindow: action argument which can be 'send' or 'receive' """ # Keep a reference on windows so garbage collector don't restroy them - instances = [] + instances = [] # type: List[SingleMessageWindow] def __init__(self, account, to='', action='', from_whom='', subject='', message='', resource='', session=None, form_node=None): self.instances.append(self) diff --git a/gajim/gtkgui_helpers.py b/gajim/gtkgui_helpers.py index 325eb1cf0..f79285803 100644 --- a/gajim/gtkgui_helpers.py +++ b/gajim/gtkgui_helpers.py @@ -23,32 +23,34 @@ # You should have received a copy of the GNU General Public License # along with Gajim. If not, see . +import cairo +import os +import sys +import math +import logging +from io import BytesIO +import xml.etree.ElementTree as ET import xml.sax.saxutils +from xml.sax import ContentHandler # type: ignore + from gi.repository import Gtk from gi.repository import Gdk from gi.repository import GdkPixbuf from gi.repository import GLib from gi.repository import Pango -import cairo -import os -import sys -import math -import xml.etree.ElementTree as ET try: from PIL import Image except Exception: pass -from io import BytesIO - -import logging -log = logging.getLogger('gajim.gtkgui_helpers') from gajim.common import i18n from gajim.common import app from gajim.common import configpaths from gajim.common.const import PEPEventType, ACTIVITIES, MOODS +log = logging.getLogger('gajim.gtkgui_helpers') + gtk_icon_theme = Gtk.IconTheme.get_default() gtk_icon_theme.append_search_path(configpaths.get('ICONS')) @@ -234,9 +236,9 @@ def scroll_to_end(widget): return False -class ServersXMLHandler(xml.sax.ContentHandler): +class ServersXMLHandler(ContentHandler): def __init__(self): - xml.sax.ContentHandler.__init__(self) + ContentHandler.__init__(self) self.servers = [] def startElement(self, name, attributes): diff --git a/gajim/roster_window.py b/gajim/roster_window.py index 488f97222..29fb4839c 100644 --- a/gajim/roster_window.py +++ b/gajim/roster_window.py @@ -5643,7 +5643,7 @@ class RosterWindow: ### ################################################################################ - def __init__(self, application: Gtk.Application): + def __init__(self, application): self.application = application self.filtering = False self.starting = False diff --git a/mypy.ini b/mypy.ini index d8b13d777..7a8ff5766 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1,5 +1,6 @@ [mypy] python_version = 3.5 +warn_unused_configs = True disallow_incomplete_defs = True [mypy-nbxmpp.*] @@ -61,3 +62,12 @@ ignore_missing_imports = True [mypy-docutils.*] ignore_missing_imports = True + +[mypy-IPython.*] +ignore_missing_imports = True + +[mypy-traitlets.*] +ignore_missing_imports = True + +[mypy-pygments.*] +ignore_missing_imports = True \ No newline at end of file