From 6b2aa24d6ece14c6b178e9a13d3fca3ce97cd741 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philipp=20H=C3=B6rist?= <philipp@hoerist.com>
Date: Fri, 21 Sep 2018 23:55:57 +0200
Subject: [PATCH] Fix rest of mypy errors

- This allows us to run mypy on the full gajim folder
---
 gajim/atom_window.py                     |  5 ++++-
 gajim/chat_control.py                    | 16 +++++++++++-----
 gajim/common/app.py                      | 23 +++++++++++++++--------
 gajim/common/config.py                   |  9 +++++++--
 gajim/common/const.py                    |  4 ++--
 gajim/common/file_props.py               |  8 +++++++-
 gajim/common/jingle_content.py           |  9 +++++++--
 gajim/common/jingle_transport.py         |  7 ++++++-
 gajim/common/passwords.py                |  6 ++++--
 gajim/common/pep.py                      |  7 +++++--
 gajim/common/rst_xhtml_generator.py      |  6 +++---
 gajim/common/socks5.py                   |  2 +-
 gajim/common/types.py                    |  9 +++++++++
 gajim/common/zeroconf/client_zeroconf.py |  1 +
 gajim/common/zeroconf/zeroconf.py        |  5 ++++-
 gajim/dialogs.py                         | 16 ++++++++++------
 gajim/gtk/single_message.py              |  4 +++-
 gajim/gtkgui_helpers.py                  | 24 +++++++++++++-----------
 gajim/roster_window.py                   |  2 +-
 mypy.ini                                 | 10 ++++++++++
 20 files changed, 123 insertions(+), 50 deletions(-)

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 <http://www.gnu.org/licenses/>.
 
+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 <http://www.gnu.org/licenses/>.
 
+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 <http://www.gnu.org/licenses/>.
 
+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 <http://www.gnu.org/licenses/>.
 
+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 <http://www.gnu.org/licenses/>.
 
+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 <http://www.gnu.org/licenses/>.
 
 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 <http://www.gnu.org/licenses/>.
 
+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 <http://www.gnu.org/licenses/>.
 
-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 <http://www.gnu.org/licenses/>.
 
+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 <http://www.gnu.org/licenses/>.
 
+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