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