Philipp Hörist pushed to branch master at gajim / gajim

Commits:

24 changed files:

Changes:

  • .gitlab-ci.yml
    ... ... @@ -14,7 +14,7 @@ run-test:
    14 14
     run-mypy:
    
    15 15
       stage: test
    
    16 16
       script:
    
    17
    -    - mypy -p gajim.common.modules --follow-imports=skip
    
    17
    +    - mypy gajim
    
    18 18
     
    
    19 19
     run-pylint:
    
    20 20
       stage: test
    

  • gajim/atom_window.py
    ... ... @@ -17,6 +17,9 @@
    17 17
     # You should have received a copy of the GNU General Public License
    
    18 18
     # along with Gajim. If not, see <http://www.gnu.org/licenses/>.
    
    19 19
     
    
    20
    +from typing import List  # pylint: disable=unused-import
    
    21
    +from typing import Any  # pylint: disable=unused-import
    
    22
    +
    
    20 23
     from gi.repository import Gdk
    
    21 24
     from gi.repository import GLib
    
    22 25
     
    
    ... ... @@ -26,7 +29,7 @@ from gajim.common import i18n
    26 29
     
    
    27 30
     class AtomWindow:
    
    28 31
         window = None
    
    29
    -    entries = []
    
    32
    +    entries = []  # type: List[Any]
    
    30 33
     
    
    31 34
         @classmethod
    
    32 35
         def newAtomEntry(cls, entry):
    

  • gajim/chat_control.py
    ... ... @@ -23,12 +23,21 @@
    23 23
     # You should have received a copy of the GNU General Public License
    
    24 24
     # along with Gajim. If not, see <http://www.gnu.org/licenses/>.
    
    25 25
     
    
    26
    +from typing import ClassVar  # pylint: disable=unused-import
    
    27
    +from typing import Type  # pylint: disable=unused-import
    
    28
    +
    
    26 29
     import os
    
    27 30
     import time
    
    31
    +
    
    28 32
     from gi.repository import Gtk
    
    29 33
     from gi.repository import Gio
    
    30 34
     from gi.repository import Pango
    
    31 35
     from gi.repository import GLib
    
    36
    +from nbxmpp.protocol import NS_XHTML, NS_XHTML_IM, NS_FILE, NS_MUC
    
    37
    +from nbxmpp.protocol import NS_JINGLE_RTP_AUDIO, NS_JINGLE_RTP_VIDEO
    
    38
    +from nbxmpp.protocol import NS_JINGLE_ICE_UDP, NS_JINGLE_FILE_TRANSFER_5
    
    39
    +from nbxmpp.protocol import NS_CHATSTATES
    
    40
    +
    
    32 41
     from gajim import gtkgui_helpers
    
    33 42
     from gajim import gui_menu_builder
    
    34 43
     from gajim import message_control
    
    ... ... @@ -41,14 +50,11 @@ from gajim.common import helpers
    41 50
     from gajim.common import ged
    
    42 51
     from gajim.common import i18n
    
    43 52
     from gajim.common.contacts import GC_Contact
    
    44
    -from nbxmpp.protocol import NS_XHTML, NS_XHTML_IM, NS_FILE, NS_MUC
    
    45
    -from nbxmpp.protocol import NS_JINGLE_RTP_AUDIO, NS_JINGLE_RTP_VIDEO
    
    46
    -from nbxmpp.protocol import NS_JINGLE_ICE_UDP, NS_JINGLE_FILE_TRANSFER_5
    
    47
    -from nbxmpp.protocol import NS_CHATSTATES
    
    48 53
     from gajim.common.connection_handlers_events import MessageOutgoingEvent
    
    49 54
     from gajim.common.const import AvatarSize, KindConstant
    
    50 55
     
    
    51 56
     from gajim.command_system.implementation.hosts import ChatCommands
    
    57
    +from gajim.command_system.framework import CommandHost  # pylint: disable=unused-import
    
    52 58
     from gajim.chat_control_base import ChatControlBase
    
    53 59
     
    
    54 60
     ################################################################################
    
    ... ... @@ -69,7 +75,7 @@ class ChatControl(ChatControlBase):
    69 75
     
    
    70 76
         # Set a command host to bound to. Every command given through a chat will be
    
    71 77
         # processed with this command host.
    
    72
    -    COMMAND_HOST = ChatCommands
    
    78
    +    COMMAND_HOST = ChatCommands  # type: ClassVar[Type[CommandHost]]
    
    73 79
     
    
    74 80
         def __init__(self, parent_win, contact, acct, session, resource=None):
    
    75 81
             ChatControlBase.__init__(self, self.TYPE_ID, parent_win,
    

  • gajim/common/app.py
    ... ... @@ -24,8 +24,11 @@
    24 24
     # You should have received a copy of the GNU General Public License
    
    25 25
     # along with Gajim. If not, see <http://www.gnu.org/licenses/>.
    
    26 26
     
    
    27
    +from typing import Any  # pylint: disable=unused-import
    
    27 28
     from typing import Dict  # pylint: disable=unused-import
    
    28 29
     from typing import List  # pylint: disable=unused-import
    
    30
    +from typing import Optional  # pylint: disable=unused-import
    
    31
    +from typing import cast
    
    29 32
     
    
    30 33
     import os
    
    31 34
     import sys
    
    ... ... @@ -44,21 +47,25 @@ from gajim.common import ged as ged_module
    44 47
     from gajim.common.contacts import LegacyContactsAPI
    
    45 48
     from gajim.common.events import Events
    
    46 49
     from gajim.common.css_config import CSSConfig
    
    50
    +from gajim.common.types import NetworkEventsControllerT  # pylint: disable=unused-import
    
    51
    +from gajim.common.types import InterfaceT  # pylint: disable=unused-import
    
    52
    +from gajim.common.types import LoggerT  # pylint: disable=unused-import
    
    53
    +from gajim.common.types import ConnectionT  # pylint: disable=unused-import
    
    47 54
     
    
    48
    -interface = None  # type: gajim.interface.Interface
    
    55
    +interface = cast(InterfaceT, None)
    
    49 56
     thread_interface = lambda *args: None # Interface to run a thread and then a callback
    
    50 57
     config = c_config.Config()
    
    51 58
     version = gajim.__version__
    
    52
    -connections = {} # 'account name': 'account (connection.Connection) instance'
    
    53
    -avatar_cache = {}
    
    59
    +connections = {}  # type: Dict[str, ConnectionT]
    
    60
    +avatar_cache = {}  # type: Dict[str, Dict[str, Any]]
    
    54 61
     ipython_window = None
    
    55 62
     app = None  # Gtk.Application
    
    56 63
     
    
    57 64
     ged = ged_module.GlobalEventsDispatcher() # Global Events Dispatcher
    
    58
    -nec = None  # type: gajim.common.nec.NetworkEventsController
    
    65
    +nec = cast(NetworkEventsControllerT, None)
    
    59 66
     plugin_manager = None # Plugins Manager
    
    60 67
     
    
    61
    -logger = None  # type: gajim.common.logger.Logger
    
    68
    +logger = cast(LoggerT, None)
    
    62 69
     
    
    63 70
     # For backwards compatibility needed
    
    64 71
     # some plugins use that
    
    ... ... @@ -113,7 +120,7 @@ nicks = {} # type: Dict[str, str]
    113 120
     # to something else than offline
    
    114 121
     # can also contain account/transport_jid to block notifications for contacts
    
    115 122
     # from this transport
    
    116
    -block_signed_in_notifications = {}
    
    123
    +block_signed_in_notifications = {}  # type: Dict[str, bool]
    
    117 124
     
    
    118 125
      # type of each connection (ssl, tls, tcp, ...)
    
    119 126
     con_types = {}  # type: Dict[str, Optional[str]]
    
    ... ... @@ -153,10 +160,10 @@ gajim_common_features = [nbxmpp.NS_BYTESTREAM, nbxmpp.NS_SI, nbxmpp.NS_FILE,
    153 160
         nbxmpp.NS_EME, 'urn:xmpp:avatar:metadata+notify']
    
    154 161
     
    
    155 162
     # Optional features gajim supports per account
    
    156
    -gajim_optional_features = {}
    
    163
    +gajim_optional_features = {}  # type: Dict[str, List[str]]
    
    157 164
     
    
    158 165
     # Capabilities hash per account
    
    159
    -caps_hash = {}
    
    166
    +caps_hash = {}  # type: Dict[str, List[str]]
    
    160 167
     
    
    161 168
     _dependencies = {
    
    162 169
         'PYTHON-DBUS': False,
    

  • gajim/common/config.py
    ... ... @@ -27,6 +27,11 @@
    27 27
     # You should have received a copy of the GNU General Public License
    
    28 28
     # along with Gajim. If not, see <http://www.gnu.org/licenses/>.
    
    29 29
     
    
    30
    +from typing import Any  # pylint: disable=unused-import
    
    31
    +from typing import Dict  # pylint: disable=unused-import
    
    32
    +from typing import List  # pylint: disable=unused-import
    
    33
    +from typing import Tuple  # pylint: disable=unused-import
    
    34
    +
    
    30 35
     import re
    
    31 36
     from enum import IntEnum, unique
    
    32 37
     
    
    ... ... @@ -287,7 +292,7 @@ class Config:
    287 292
             'use_keyring': [opt_bool, True, _('If true, Gajim will use the Systems Keyring to store account passwords.')],
    
    288 293
             'pgp_encoding': [opt_str, '', _('Sets the encoding used by python-gnupg'), True],
    
    289 294
             'remote_commands': [opt_bool, False, _('If true, Gajim will execute XEP-0146 Commands.')],
    
    290
    -    }, {})
    
    295
    +    }, {})  # type: Tuple[Dict[str, List[Any]], Dict[Any, Any]]
    
    291 296
     
    
    292 297
         __options_per_key = {
    
    293 298
             'accounts': ({
    
    ... ... @@ -436,7 +441,7 @@ class Config:
    436 441
             'plugins': ({
    
    437 442
                 '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.')],
    
    438 443
             }, {}),
    
    439
    -    }
    
    444
    +    }  # type: Dict[str, Tuple[Dict[str, List[Any]], Dict[Any, Any]]]
    
    440 445
     
    
    441 446
         statusmsg_default = {
    
    442 447
             _('Sleeping'): ['ZZZZzzzzzZZZZZ', 'inactive', 'sleeping', '', 'sleepy', ''],
    

  • gajim/common/const.py
    ... ... @@ -4,10 +4,10 @@ from collections import namedtuple
    4 4
     from gajim.common.i18n import _
    
    5 5
     
    
    6 6
     Option = namedtuple('Option', 'kind label type value name callback data desc enabledif props')
    
    7
    -Option.__new__.__defaults__ = (None,) * len(Option._fields)
    
    7
    +Option.__new__.__defaults__ = (None,) * len(Option._fields)  # type: ignore
    
    8 8
     
    
    9 9
     DialogButton = namedtuple('DialogButton', 'text callback action')
    
    10
    -DialogButton.__new__.__defaults__ = (None, None)
    
    10
    +DialogButton.__new__.__defaults__ = (None, None)  # type: ignore
    
    11 11
     
    
    12 12
     
    
    13 13
     @unique
    

  • gajim/common/file_props.py
    ... ... @@ -17,8 +17,14 @@ Exception: this class should not be instatiated
    17 17
     True
    
    18 18
     """
    
    19 19
     
    
    20
    +from typing import Any  # pylint: disable=unused-import
    
    21
    +from typing import ClassVar  # pylint: disable=unused-import
    
    22
    +from typing import Dict  # pylint: disable=unused-import
    
    23
    +from typing import Tuple  # pylint: disable=unused-import
    
    24
    +
    
    25
    +
    
    20 26
     class FilesProp:
    
    21
    -    _files_props = {}
    
    27
    +    _files_props = {}  # type: ClassVar[Dict[Tuple[str, str], Any]]
    
    22 28
     
    
    23 29
         def __init__(self):
    
    24 30
             raise Exception('this class should not be instantiated')
    

  • gajim/common/jingle_content.py
    ... ... @@ -16,14 +16,19 @@
    16 16
     Handles Jingle contents (XEP 0166)
    
    17 17
     """
    
    18 18
     
    
    19
    +from typing import Any  # pylint: disable=unused-import
    
    20
    +from typing import Dict  # pylint: disable=unused-import
    
    21
    +
    
    19 22
     import os
    
    23
    +
    
    24
    +import nbxmpp
    
    25
    +
    
    20 26
     from gajim.common import app
    
    21 27
     from gajim.common import configpaths
    
    22
    -import nbxmpp
    
    23 28
     from gajim.common.jingle_xtls import SELF_SIGNED_CERTIFICATE
    
    24 29
     from gajim.common.jingle_xtls import load_cert_file
    
    25 30
     
    
    26
    -contents = {}
    
    31
    +contents = {}  # type: Dict[str, Any]
    
    27 32
     
    
    28 33
     def get_jingle_content(node):
    
    29 34
         namespace = node.getNamespace()
    

  • gajim/common/jingle_transport.py
    ... ... @@ -16,16 +16,21 @@
    16 16
     Handles Jingle Transports (currently only ICE-UDP)
    
    17 17
     """
    
    18 18
     
    
    19
    +from typing import Any  # pylint: disable=unused-import
    
    20
    +from typing import Dict  # pylint: disable=unused-import
    
    21
    +
    
    19 22
     import logging
    
    20 23
     import socket
    
    21 24
     from enum import IntEnum, unique
    
    25
    +
    
    22 26
     import nbxmpp
    
    27
    +
    
    23 28
     from gajim.common import app
    
    24 29
     
    
    25 30
     log = logging.getLogger('gajim.c.jingle_transport')
    
    26 31
     
    
    27 32
     
    
    28
    -transports = {}
    
    33
    +transports = {}  # type: Dict[str, Any]
    
    29 34
     
    
    30 35
     def get_jingle_transport(node):
    
    31 36
         namespace = node.getNamespace()
    

  • gajim/common/passwords.py
    ... ... @@ -28,10 +28,12 @@ __all__ = ['get_password', 'save_password']
    28 28
     
    
    29 29
     log = logging.getLogger('gajim.password')
    
    30 30
     
    
    31
    -keyring = None
    
    31
    +
    
    32 32
     try:
    
    33 33
         import keyring
    
    34
    +    KEYRING_AVAILABLE = True
    
    34 35
     except ImportError:
    
    36
    +    KEYRING_AVAILABLE = False
    
    35 37
         log.debug('python-keyring missing, falling back to plaintext storage')
    
    36 38
     
    
    37 39
     
    
    ... ... @@ -83,7 +85,7 @@ class PasswordStorageManager(PasswordStorage):
    83 85
             """
    
    84 86
             # TODO: handle disappearing backends
    
    85 87
     
    
    86
    -        if app.config.get('use_keyring') and keyring:
    
    88
    +        if app.config.get('use_keyring') and KEYRING_AVAILABLE:
    
    87 89
                 self.secret = SecretPasswordStorage()
    
    88 90
     
    
    89 91
         def get_password(self, account_name):
    

  • gajim/common/pep.py
    ... ... @@ -19,11 +19,14 @@
    19 19
     # You should have received a copy of the GNU General Public License
    
    20 20
     # along with Gajim. If not, see <http://www.gnu.org/licenses/>.
    
    21 21
     
    
    22
    +from typing import Any  # pylint: disable=unused-import
    
    23
    +from typing import List  # pylint: disable=unused-import
    
    24
    +
    
    22 25
     import logging
    
    23
    -log = logging.getLogger('gajim.c.pep')
    
    24 26
     
    
    25 27
     from gajim.common import app
    
    26 28
     
    
    29
    +log = logging.getLogger('gajim.c.pep')
    
    27 30
     
    
    28 31
     class AbstractPEP:
    
    29 32
     
    
    ... ... @@ -75,4 +78,4 @@ class AbstractPEP:
    75 78
             pass
    
    76 79
     
    
    77 80
     
    
    78
    -SUPPORTED_PERSONAL_USER_EVENTS = []
    81
    +SUPPORTED_PERSONAL_USER_EVENTS = []  # type: List[Any]

  • gajim/common/rst_xhtml_generator.py
    ... ... @@ -18,11 +18,11 @@
    18 18
     # along with Gajim. If not, see <http://www.gnu.org/licenses/>.
    
    19 19
     
    
    20 20
     try:
    
    21
    -    from docutils import io
    
    21
    +    from docutils import io  # type: ignore
    
    22 22
         from docutils.core import Publisher
    
    23 23
         from docutils.parsers.rst import roles
    
    24
    -    from docutils import nodes, utils
    
    25
    -    from docutils.parsers.rst.roles import set_classes
    
    24
    +    from docutils import nodes, utils  # type: ignore
    
    25
    +    from docutils.parsers.rst.roles import set_classes  # type: ignore
    
    26 26
     except ImportError:
    
    27 27
         print("Requires docutils 0.4 for set_classes to be available")
    
    28 28
         def create_xhtml(text):
    

  • gajim/common/socks5.py
    ... ... @@ -799,7 +799,7 @@ class Socks5:
    799 799
                     return self.file_props.received_len
    
    800 800
             return None
    
    801 801
     
    
    802
    -    def disconnect(self):
    
    802
    +    def disconnect(self, *args, **kwargs):
    
    803 803
             """
    
    804 804
             Close open descriptors and remover socket descr. from idleque
    
    805 805
             """
    

  • gajim/common/types.py
    ... ... @@ -33,6 +33,15 @@ if TYPE_CHECKING:
    33 33
         from gajim.common.contacts import Contact
    
    34 34
         from gajim.common.contacts import GC_Contact
    
    35 35
         from gajim.common.nec import NetworkEvent
    
    36
    +    from gajim.common.nec import NetworkEventsController
    
    37
    +    from gajim.common.logger import Logger
    
    38
    +
    
    39
    +    from gajim.gui_interface import Interface
    
    40
    +
    
    41
    +
    
    42
    +NetworkEventsControllerT = Union['NetworkEventsController']
    
    43
    +InterfaceT = Union['Interface']
    
    44
    +LoggerT = Union['Logger']
    
    36 45
     
    
    37 46
     ConnectionT = Union['Connection', 'ConnectionZeroconf']
    
    38 47
     ContactT = Union['Contact', 'GC_Contact']
    

  • gajim/common/zeroconf/client_zeroconf.py
    ... ... @@ -19,6 +19,7 @@ from gajim.common import app
    19 19
     import nbxmpp
    
    20 20
     from nbxmpp.idlequeue import IdleObject
    
    21 21
     from nbxmpp import dispatcher_nb, simplexml
    
    22
    +from nbxmpp.plugin import PlugIn
    
    22 23
     from nbxmpp.plugin import *
    
    23 24
     from nbxmpp.transports_nb import DATA_RECEIVED, DATA_SENT, DATA_ERROR
    
    24 25
     from gajim.common.zeroconf import zeroconf
    

  • gajim/common/zeroconf/zeroconf.py
    ... ... @@ -14,8 +14,11 @@
    14 14
     # You should have received a copy of the GNU General Public License
    
    15 15
     # along with Gajim.  If not, see <http://www.gnu.org/licenses/>.
    
    16 16
     
    
    17
    +from typing import Any  # pylint: disable=unused-import
    
    18
    +
    
    17 19
     from enum import IntEnum, unique
    
    18 20
     
    
    21
    +
    
    19 22
     @unique
    
    20 23
     class Constant(IntEnum):
    
    21 24
         NAME = 0
    
    ... ... @@ -54,7 +57,7 @@ def test_zeroconf():
    54 57
     
    
    55 58
     if test_avahi():
    
    56 59
         from gajim.common.zeroconf import zeroconf_avahi
    
    57
    -    Zeroconf = zeroconf_avahi.Zeroconf
    
    60
    +    Zeroconf = zeroconf_avahi.Zeroconf  # type: Any
    
    58 61
     elif test_bonjour():
    
    59 62
         from gajim.common.zeroconf import zeroconf_bonjour
    
    60 63
         Zeroconf = zeroconf_bonjour.Zeroconf

  • gajim/dev/__init__.py

  • gajim/dev/ipython_view.py
    ... ... @@ -40,17 +40,17 @@ available under the terms of the BSD which accompanies this distribution, and
    40 40
     is available at U{http://www.opensource.org/licenses/bsd-license.php}
    
    41 41
     """
    
    42 42
     
    
    43
    +import re
    
    44
    +import sys
    
    45
    +import os
    
    46
    +from io import StringIO
    
    43 47
     from functools import reduce
    
    44 48
     
    
    45 49
     from gi.repository import Gtk
    
    46 50
     from gi.repository import Gdk
    
    47 51
     from gi.repository import GObject
    
    48 52
     from gi.repository import GLib
    
    49
    -import re
    
    50
    -import sys
    
    51
    -import os
    
    52 53
     from gi.repository import Pango
    
    53
    -from io import StringIO
    
    54 54
     
    
    55 55
     try:
    
    56 56
         import IPython
    
    ... ... @@ -92,8 +92,8 @@ class IterableIPShell:
    92 92
         @ivar complete_sep: Seperation delimeters for completion function.
    
    93 93
         @type complete_sep: _sre.SRE_Pattern
    
    94 94
         """
    
    95
    -    def __init__(self,argv=[],user_ns=None,user_global_ns=None, cin=None,
    
    96
    -                    cout=None,cerr=None, input_func=None):
    
    95
    +    def __init__(self, argv=None, user_ns=None, user_global_ns=None, cin=None,
    
    96
    +                 cout=None, cerr=None, input_func=None):
    
    97 97
             """
    
    98 98
             @param argv: Command line options for IPython
    
    99 99
             @type argv: list
    
    ... ... @@ -110,6 +110,9 @@ class IterableIPShell:
    110 110
             @param input_func: Replacement for builtin raw_input()
    
    111 111
             @type input_func: function
    
    112 112
             """
    
    113
    +        if argv is None:
    
    114
    +            argv = []
    
    115
    +
    
    113 116
             io = IPython.utils.io
    
    114 117
             if input_func:
    
    115 118
                 if IPython.version_info[0] >= 1:
    
    ... ... @@ -161,9 +164,9 @@ class IterableIPShell:
    161 164
             sys.excepthook = excepthook
    
    162 165
             self.iter_more = 0
    
    163 166
             self.history_level = 0
    
    164
    -        self.complete_sep =  re.compile('[\s\{\}\[\]\(\)]')
    
    165
    -        self.updateNamespace({'exit':lambda:None})
    
    166
    -        self.updateNamespace({'quit':lambda:None})
    
    167
    +        self.complete_sep = re.compile(r'[\s\{\}\[\]\(\)]')
    
    168
    +        self.updateNamespace({'exit':lambda: None})
    
    169
    +        self.updateNamespace({'quit':lambda: None})
    
    167 170
             #self.IP.readline_startup_hook(self.IP.pre_readline)
    
    168 171
             # Workaround for updating namespace with sys.modules
    
    169 172
             #
    
    ... ... @@ -173,7 +176,7 @@ class IterableIPShell:
    173 176
             '''
    
    174 177
             Update self.IP namespace for autocompletion with sys.modules
    
    175 178
             '''
    
    176
    -        for k,v in sys.modules.items():
    
    179
    +        for k, v in sys.modules.items():
    
    177 180
                 if not '.' in k:
    
    178 181
                     self.IP.user_ns.update({k:v})
    
    179 182
     
    
    ... ... @@ -315,7 +318,7 @@ class IterableIPShell:
    315 318
                 possibilities = self.IP.complete(split_line[-1])
    
    316 319
             else:
    
    317 320
                 completed = line
    
    318
    -            possibilities = ['',[]]
    
    321
    +            possibilities = ['', []]
    
    319 322
             if possibilities:
    
    320 323
                 def _commonPrefix(str1, str2):
    
    321 324
                     '''
    
    ... ... @@ -361,14 +364,14 @@ class ConsoleView(Gtk.TextView):
    361 364
         @type line_start: Gtk.TextMark
    
    362 365
         """
    
    363 366
     
    
    364
    -    ANSI_COLORS =  {'0;30': 'Black',     '0;31': 'Red',
    
    365
    -                    '0;32': 'Green',     '0;33': 'Brown',
    
    366
    -                    '0;34': 'Blue',      '0;35': 'Purple',
    
    367
    -                    '0;36': 'Cyan',      '0;37': 'LightGray',
    
    368
    -                    '1;30': 'DarkGray',  '1;31': 'DarkRed',
    
    369
    -                    '1;32': 'SeaGreen',  '1;33': 'Yellow',
    
    370
    -                    '1;34': 'LightBlue', '1;35': 'MediumPurple',
    
    371
    -                    '1;36': 'LightCyan', '1;37': 'White'}
    
    367
    +    ANSI_COLORS = {'0;30': 'Black', '0;31': 'Red',
    
    368
    +                   '0;32': 'Green', '0;33': 'Brown',
    
    369
    +                   '0;34': 'Blue', '0;35': 'Purple',
    
    370
    +                   '0;36': 'Cyan', '0;37': 'LightGray',
    
    371
    +                   '1;30': 'DarkGray', '1;31': 'DarkRed',
    
    372
    +                   '1;32': 'SeaGreen', '1;33': 'Yellow',
    
    373
    +                   '1;34': 'LightBlue', '1;35': 'MediumPurple',
    
    374
    +                   '1;36': 'LightCyan', '1;37': 'White'}
    
    372 375
     
    
    373 376
         def __init__(self):
    
    374 377
             """
    
    ... ... @@ -387,7 +390,7 @@ class ConsoleView(Gtk.TextView):
    387 390
                                             weight=700)
    
    388 391
             self.text_buffer.create_tag('0')
    
    389 392
             self.text_buffer.create_tag('notouch', editable=False)
    
    390
    -        self.color_pat = re.compile('\x01?\x1b\[(.*?)m\x02?')
    
    393
    +        self.color_pat = re.compile(r'\x01?\x1b\[(.*?)m\x02?')
    
    391 394
             if HAS_IPYTHON5:
    
    392 395
                 self.style_dict = {
    
    393 396
                     Token.Prompt:        '0;32',
    
    ... ... @@ -401,7 +404,7 @@ class ConsoleView(Gtk.TextView):
    401 404
             self.connect('key-press-event', self.onKeyPress)
    
    402 405
     
    
    403 406
         def write(self, text, editable=False):
    
    404
    -        if type(text) == str:
    
    407
    +        if isinstance(text, str):
    
    405 408
                 GLib.idle_add(self._write, text, editable)
    
    406 409
             elif IPython.version_info[0] >= 5:
    
    407 410
                 GLib.idle_add(self._write5, text, editable)
    
    ... ... @@ -422,7 +425,7 @@ class ConsoleView(Gtk.TextView):
    422 425
             for token, segment in text:
    
    423 426
                 tag = self.style_dict[token]
    
    424 427
                 self.text_buffer.insert_with_tags_by_name(self.text_buffer.get_end_iter(),
    
    425
    -                                                          segment, tag)
    
    428
    +                                                      segment, tag)
    
    426 429
             if not editable:
    
    427 430
                 self.text_buffer.apply_tag_by_name('notouch',
    
    428 431
                                                    self.text_buffer.get_iter_at_mark(start_mark),
    
    ... ... @@ -439,7 +442,7 @@ class ConsoleView(Gtk.TextView):
    439 442
             @param editable: If true, added text is editable.
    
    440 443
             @type editable: boolean
    
    441 444
             """
    
    442
    -        if type(text) == list and IPython.version_info[0] >= 5:
    
    445
    +        if isinstance(text, list) and IPython.version_info[0] >= 5:
    
    443 446
                 self._write5(text, editable)
    
    444 447
                 return
    
    445 448
             segments = self.color_pat.split(text)
    
    ... ... @@ -454,7 +457,7 @@ class ConsoleView(Gtk.TextView):
    454 457
                 for tag in ansi_tags:
    
    455 458
                     i = segments.index(tag)
    
    456 459
                     self.text_buffer.insert_with_tags_by_name(self.text_buffer.get_end_iter(),
    
    457
    -                                                     segments[i+1], str(tag))
    
    460
    +                                                          segments[i+1], str(tag))
    
    458 461
                     segments.pop(i)
    
    459 462
             if not editable:
    
    460 463
                 self.text_buffer.apply_tag_by_name('notouch',
    
    ... ... @@ -501,8 +504,8 @@ class ConsoleView(Gtk.TextView):
    501 504
             @rtype: string
    
    502 505
             """
    
    503 506
             rv = self.text_buffer.get_slice(
    
    504
    -          self.text_buffer.get_iter_at_mark(self.line_start),
    
    505
    -          self.text_buffer.get_end_iter(), False)
    
    507
    +            self.text_buffer.get_iter_at_mark(self.line_start),
    
    508
    +            self.text_buffer.get_end_iter(), False)
    
    506 509
             return rv
    
    507 510
     
    
    508 511
         def showReturned(self, text):
    
    ... ... @@ -518,9 +521,9 @@ class ConsoleView(Gtk.TextView):
    518 521
             iter_ = self.text_buffer.get_iter_at_mark(self.line_start)
    
    519 522
             iter_.forward_to_line_end()
    
    520 523
             self.text_buffer.apply_tag_by_name(
    
    521
    -          'notouch',
    
    522
    -          self.text_buffer.get_iter_at_mark(self.line_start),
    
    523
    -          iter_)
    
    524
    +            'notouch',
    
    525
    +            self.text_buffer.get_iter_at_mark(self.line_start),
    
    526
    +            iter_)
    
    524 527
             self._write('\n'+text)
    
    525 528
             if text:
    
    526 529
                 self._write('\n')
    
    ... ... @@ -532,7 +535,7 @@ class ConsoleView(Gtk.TextView):
    532 535
                 indentation = self.IP.input_splitter.indent_spaces * ' '
    
    533 536
                 self.text_buffer.insert_at_cursor(indentation)
    
    534 537
     
    
    535
    -    def onKeyPress(self, widget, event):
    
    538
    +    def onKeyPress(self, _widget, event):
    
    536 539
             """
    
    537 540
             Key press callback used for correcting behavior for console-like
    
    538 541
             interfaces. For example 'home' should go to prompt, not to beginning of
    
    ... ... @@ -555,10 +558,11 @@ class ConsoleView(Gtk.TextView):
    555 558
                 if event.get_state() == 0:
    
    556 559
                     self.text_buffer.place_cursor(start_iter)
    
    557 560
                     return True
    
    558
    -            elif event.get_state() == Gdk.ModifierType.SHIFT_MASK:
    
    561
    +            if event.get_state() == Gdk.ModifierType.SHIFT_MASK:
    
    559 562
                     self.text_buffer.move_mark(insert_mark, start_iter)
    
    560 563
                     return True
    
    561
    -        elif event.keyval == Gdk.KEY_Left:
    
    564
    +
    
    565
    +        if event.keyval == Gdk.KEY_Left:
    
    562 566
                 insert_iter.backward_cursor_position()
    
    563 567
                 if not insert_iter.editable(True):
    
    564 568
                     return True
    
    ... ... @@ -611,7 +615,7 @@ class IPythonView(ConsoleView, IterableIPShell):
    611 615
             # IPython 5.0 calls prompt_for_code instead of raw_input
    
    612 616
             return self.raw_input(self)
    
    613 617
     
    
    614
    -    def raw_input(self, prompt=''):
    
    618
    +    def raw_input(self, _prompt=''):
    
    615 619
             """
    
    616 620
             Custom raw_input() replacement. Get's current line from console buffer
    
    617 621
     
    
    ... ... @@ -643,16 +647,16 @@ class IPythonView(ConsoleView, IterableIPShell):
    643 647
                 self.interrupt = True
    
    644 648
                 self._processLine()
    
    645 649
                 return True
    
    646
    -        elif event.keyval == Gdk.KEY_Return:
    
    650
    +        if event.keyval == Gdk.KEY_Return:
    
    647 651
                 self._processLine()
    
    648 652
                 return True
    
    649
    -        elif event.keyval == Gdk.KEY_Up:
    
    653
    +        if event.keyval == Gdk.KEY_Up:
    
    650 654
                 self.changeLine(self.historyBack())
    
    651 655
                 return True
    
    652
    -        elif event.keyval == Gdk.KEY_Down:
    
    656
    +        if event.keyval == Gdk.KEY_Down:
    
    653 657
                 self.changeLine(self.historyForward())
    
    654 658
                 return True
    
    655
    -        elif event.keyval == Gdk.KEY_Tab:
    
    659
    +        if event.keyval == Gdk.KEY_Tab:
    
    656 660
                 if not self.getCurrentLine().strip():
    
    657 661
                     return False
    
    658 662
                 completed, possibilities = self.complete(self.getCurrentLine())
    
    ... ... @@ -672,7 +676,8 @@ class IPythonView(ConsoleView, IterableIPShell):
    672 676
             self.history_pos = 0
    
    673 677
             self.execute()
    
    674 678
             rv = self.cout.getvalue()
    
    675
    -        if rv: rv = rv.strip('\n')
    
    679
    +        if rv:
    
    680
    +            rv = rv.strip('\n')
    
    676 681
             self.showReturned(rv)
    
    677 682
             self.cout.truncate(0)
    
    678 683
             self.cout.seek(0)

  • gajim/dialogs.py
    ... ... @@ -25,18 +25,22 @@
    25 25
     # You should have received a copy of the GNU General Public License
    
    26 26
     # along with Gajim. If not, see <http://www.gnu.org/licenses/>.
    
    27 27
     
    
    28
    -from gi.repository import Gtk
    
    29
    -from gi.repository import Gdk
    
    30
    -from gi.repository import GLib
    
    28
    +from typing import Dict  # pylint: disable=unused-import
    
    29
    +from typing import List  # pylint: disable=unused-import
    
    30
    +from typing import Tuple  # pylint: disable=unused-import
    
    31 31
     
    
    32 32
     import os
    
    33 33
     import logging
    
    34
    +from random import randrange
    
    35
    +
    
    36
    +from gi.repository import Gtk
    
    37
    +from gi.repository import Gdk
    
    38
    +from gi.repository import GLib
    
    34 39
     
    
    35 40
     from gajim import gtkgui_helpers
    
    36 41
     from gajim import vcard
    
    37 42
     from gajim import dataforms_widget
    
    38 43
     
    
    39
    -from random import randrange
    
    40 44
     from gajim.common import ged
    
    41 45
     from gajim.common.i18n import _
    
    42 46
     from gajim.common.const import ACTIVITIES
    
    ... ... @@ -1363,7 +1367,7 @@ class ProgressDialog:
    1363 1367
     
    
    1364 1368
     class TransformChatToMUC:
    
    1365 1369
         # Keep a reference on windows so garbage collector don't restroy them
    
    1366
    -    instances = []
    
    1370
    +    instances = []  # type: List[TransformChatToMUC]
    
    1367 1371
         def __init__(self, account, jids, preselected=None):
    
    1368 1372
             """
    
    1369 1373
             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):
    1584 1588
     
    
    1585 1589
     
    
    1586 1590
     class VoIPCallReceivedDialog:
    
    1587
    -    instances = {}
    
    1591
    +    instances = {}   # type: Dict[Tuple[str, str], VoIPCallReceivedDialog]
    
    1588 1592
         def __init__(self, account, contact_jid, sid, content_types):
    
    1589 1593
             self.instances[(contact_jid, sid)] = self
    
    1590 1594
             self.account = account
    

  • gajim/gtk/single_message.py
    ... ... @@ -12,6 +12,8 @@
    12 12
     # You should have received a copy of the GNU General Public License
    
    13 13
     # along with Gajim. If not, see <http://www.gnu.org/licenses/>.
    
    14 14
     
    
    15
    +from typing import List  # pylint: disable=unused-import
    
    16
    +
    
    15 17
     from gi.repository import Gdk
    
    16 18
     from gi.repository import GLib
    
    17 19
     
    
    ... ... @@ -40,7 +42,7 @@ class SingleMessageWindow:
    40 42
         action argument which can be 'send' or 'receive'
    
    41 43
         """
    
    42 44
         # Keep a reference on windows so garbage collector don't restroy them
    
    43
    -    instances = []
    
    45
    +    instances = []  # type: List[SingleMessageWindow]
    
    44 46
         def __init__(self, account, to='', action='', from_whom='', subject='',
    
    45 47
                 message='', resource='', session=None, form_node=None):
    
    46 48
             self.instances.append(self)
    

  • gajim/gtkgui_helpers.py
    ... ... @@ -23,32 +23,34 @@
    23 23
     # You should have received a copy of the GNU General Public License
    
    24 24
     # along with Gajim. If not, see <http://www.gnu.org/licenses/>.
    
    25 25
     
    
    26
    +import cairo
    
    27
    +import os
    
    28
    +import sys
    
    29
    +import math
    
    30
    +import logging
    
    31
    +from io import BytesIO
    
    32
    +import xml.etree.ElementTree as ET
    
    26 33
     import xml.sax.saxutils
    
    34
    +from xml.sax import ContentHandler  # type: ignore
    
    35
    +
    
    27 36
     from gi.repository import Gtk
    
    28 37
     from gi.repository import Gdk
    
    29 38
     from gi.repository import GdkPixbuf
    
    30 39
     from gi.repository import GLib
    
    31 40
     from gi.repository import Pango
    
    32
    -import cairo
    
    33
    -import os
    
    34
    -import sys
    
    35
    -import math
    
    36
    -import xml.etree.ElementTree as ET
    
    37 41
     
    
    38 42
     try:
    
    39 43
         from PIL import Image
    
    40 44
     except Exception:
    
    41 45
         pass
    
    42
    -from io import BytesIO
    
    43
    -
    
    44
    -import logging
    
    45
    -log = logging.getLogger('gajim.gtkgui_helpers')
    
    46 46
     
    
    47 47
     from gajim.common import i18n
    
    48 48
     from gajim.common import app
    
    49 49
     from gajim.common import configpaths
    
    50 50
     from gajim.common.const import PEPEventType, ACTIVITIES, MOODS
    
    51 51
     
    
    52
    +log = logging.getLogger('gajim.gtkgui_helpers')
    
    53
    +
    
    52 54
     gtk_icon_theme = Gtk.IconTheme.get_default()
    
    53 55
     gtk_icon_theme.append_search_path(configpaths.get('ICONS'))
    
    54 56
     
    
    ... ... @@ -234,9 +236,9 @@ def scroll_to_end(widget):
    234 236
         return False
    
    235 237
     
    
    236 238
     
    
    237
    -class ServersXMLHandler(xml.sax.ContentHandler):
    
    239
    +class ServersXMLHandler(ContentHandler):
    
    238 240
         def __init__(self):
    
    239
    -        xml.sax.ContentHandler.__init__(self)
    
    241
    +        ContentHandler.__init__(self)
    
    240 242
             self.servers = []
    
    241 243
     
    
    242 244
         def startElement(self, name, attributes):
    

  • gajim/roster_window.py
    ... ... @@ -5643,7 +5643,7 @@ class RosterWindow:
    5643 5643
     ###
    
    5644 5644
     ################################################################################
    
    5645 5645
     
    
    5646
    -    def __init__(self, application: Gtk.Application):
    
    5646
    +    def __init__(self, application):
    
    5647 5647
             self.application = application
    
    5648 5648
             self.filtering = False
    
    5649 5649
             self.starting = False
    

  • mypy.ini
    1 1
     [mypy]
    
    2 2
     python_version = 3.5
    
    3
    +warn_unused_configs = True
    
    3 4
     disallow_incomplete_defs = True
    
    4 5
     
    
    5 6
     [mypy-nbxmpp.*]
    
    ... ... @@ -61,3 +62,12 @@ ignore_missing_imports = True
    61 62
     
    
    62 63
     [mypy-docutils.*]
    
    63 64
     ignore_missing_imports = True
    
    65
    +
    
    66
    +[mypy-IPython.*]
    
    67
    +ignore_missing_imports = True
    
    68
    +
    
    69
    +[mypy-traitlets.*]
    
    70
    +ignore_missing_imports = True
    
    71
    +
    
    72
    +[mypy-pygments.*]
    
    73
    +ignore_missing_imports = True
    \ No newline at end of file

  • scripts/dev/pre-push-tests.sh
    1
    -mypy -p gajim.common.modules --follow-imports=skip
    
    1
    +mypy gajim
    
    2 2
     pylint --jobs=2 --disable=C0103,C0302,C0330,C0411,C0412,C0413,E0203,E0401,E0611,E0710,E0712,E1101,E1102,E1128,E1133,E1136,R0201,R0901,R0904,R0913,R0916,R1702,R1706,R1711,R1716,W0143,W0201,W0212,W0221,W0223,W0311,W0401,W0603,W0613,W0614 gajim
    
    3 3
     
    
    4 4
     # C0103 invalid-name