Philipp Hörist pushed to branch master at gajim / gajim
Commits:
fd47095e by Philipp Hörist at 2022-12-04T23:54:56+01:00
refactor: Remove unnecessary map() usage
- - - - -
6c666114 by Philipp Hörist at 2022-12-04T23:54:56+01:00
refactor: Remove unnecessary method arguments
- - - - -
532e2249 by Philipp Hörist at 2022-12-04T23:54:56+01:00
refactor: Use "not in" for inclusion check
- - - - -
f256b6ec by Philipp Hörist at 2022-12-05T00:00:21+01:00
refactor: Remove unnecessary variable assignment before return
- - - - -
90cd87a2 by Philipp Hörist at 2022-12-05T00:00:21+01:00
refactor: Simplify import
- - - - -
c4068f05 by Philipp Hörist at 2022-12-05T00:00:21+01:00
cq: Reorder comparison
- - - - -
012daf50 by Philipp Hörist at 2022-12-05T00:00:21+01:00
cq: Add noqa for false positive ruff checks
- - - - -
53f96919 by Philipp Hörist at 2022-12-05T00:00:21+01:00
refactor: PluginManager: Simplify setting module attribute
- - - - -
90a53769 by Philipp Hörist at 2022-12-05T00:00:21+01:00
refactor: Rename AppIndicator import
- - - - -
d14e1ee9 by Philipp Hörist at 2022-12-05T00:00:21+01:00
refactor: Follow CapWords convention for classes
- - - - -
b73700ee by Philipp Hörist at 2022-12-05T00:00:21+01:00
refactor: Assistant: Use dict literal
- - - - -
93890f8d by Philipp Hörist at 2022-12-05T00:00:21+01:00
refactor: Remove unnecessary method cache
This method is not expensive and only called a few times
- - - - -
6440fd60 by Philipp Hörist at 2022-12-05T00:00:21+01:00
ci: Update ruff configuration
- - - - -
9e9101a7 by Philipp Hörist at 2022-12-05T00:00:21+01:00
ci: Repace pylint/flake8 with ruff
- - - - -
28 changed files:
- − .ci/pylint.sh
- .gitignore
- .gitlab-ci.yml
- gajim/common/app.py
- gajim/common/const.py
- gajim/common/helpers.py
- gajim/common/i18n.py
- gajim/common/logging_helpers.py
- gajim/common/modules/bookmarks.py
- gajim/common/modules/bytestream.py
- gajim/common/regex.py
- gajim/common/setting_values.py
- gajim/gtk/adhoc.py
- gajim/gtk/assistant.py
- gajim/gtk/chat_function_page.py
- gajim/gtk/css_config.py
- gajim/gtk/dataform.py
- gajim/gtk/menus.py
- gajim/gtk/message_input.py
- gajim/gtk/status_icon.py
- gajim/gtk/util.py
- gajim/plugins/pluginmanager.py
- − pylintrc
- pyproject.toml
- scripts/pre-push-tests.sh
- setup.cfg
- setup.py
- test/no_gui/test_styling.py
Changes:
=====================================
.ci/pylint.sh deleted
=====================================
@@ -1,24 +0,0 @@
-#!/bin/sh
-
-# exit when any command fails
-set -e
-
-PYLINT=${PYLINT:-pylint}
-
-# Ignore but need fixing
-
-# C0103 invalid-name
-# C0415 import-outside-toplevel
-# R1710 inconsistent-return-statements
-# W0201 attribute-defined-outside-init
-# W0221 arguments-differ
-# W0233 non-parent-init-called
-# W0613 unused-argument
-
-NEED_FIXING=C0103,C0415,R1710,W0201,W0221,W0233,W0613
-
-
-"$PYLINT" --version
-"$PYLINT" --disable="$NEED_FIXING" --ignore=modules,dbus "$@"
-"$PYLINT" --disable="C0415" "$@/common/modules"
-"$PYLINT" "$@/common/dbus"
=====================================
.gitignore
=====================================
@@ -16,6 +16,7 @@ gajim/gui/*
__pycache__/
.mypy_cache/
+.ruff_cache/
# Build folders
=====================================
.gitlab-ci.yml
=====================================
@@ -33,23 +33,14 @@ test-pyright:
- $(npm bin)/pyright
interruptible: true
-test-flake8:
+test-ruff:
stage: test
rules:
- changes:
- "**/*.py"
script:
- - flake8
- interruptible: true
-
-test-pylint:
- stage: test
- rules:
- - changes:
- - "**/*.py"
- script:
- - pip3 install -I git+https://dev.gajim.org/gajim/python-nbxmpp.git
- - .ci/pylint.sh --jobs=2 gajim
+ - pip3 install ruff
+ - ruff .
interruptible: true
test-unittest:
=====================================
gajim/common/app.py
=====================================
@@ -474,8 +474,7 @@ def get_jid_from_account(account_name: str) -> str:
'''
name = settings.get_account_setting(account_name, 'name')
hostname = settings.get_account_setting(account_name, 'hostname')
- jid = name + '@' + hostname
- return jid
+ return name + '@' + hostname
def get_hostname_from_account(account_name: str, use_srv: bool = False) -> str:
@@ -502,10 +501,13 @@ def get_priority(account: str, show: str) -> int:
prio = settings.get_account_setting(account, 'autopriority_' + show)
else:
prio = settings.get_account_setting(account, 'priority')
+
if prio < -128:
- prio = -128
- elif prio > 127:
- prio = 127
+ return -128
+
+ if prio > 127:
+ return 127
+
return prio
=====================================
gajim/common/const.py
=====================================
@@ -247,7 +247,7 @@ class MUCJoinedState(Enum):
CREATING = 'creating'
CAPTCHA_REQUEST = 'captcha in progress'
CAPTCHA_FAILED = 'captcha failed'
- PASSWORD_REQUEST = 'password request'
+ PASSWORD_REQUEST = 'password request' # noqa: S105
def __str__(self):
return self.name
=====================================
gajim/common/helpers.py
=====================================
@@ -183,28 +183,28 @@ def get_uf_show(show: str, use_mnemonic: bool = False) -> str:
def get_uf_sub(sub: str) -> str:
if sub == 'none':
- uf_sub = p_('Contact subscription', 'None')
- elif sub == 'to':
- uf_sub = p_('Contact subscription', 'To')
- elif sub == 'from':
- uf_sub = p_('Contact subscription', 'From')
- elif sub == 'both':
- uf_sub = p_('Contact subscription', 'Both')
- else:
- uf_sub = p_('Contact subscription', 'Unknown')
+ return p_('Contact subscription', 'None')
+
+ if sub == 'to':
+ return p_('Contact subscription', 'To')
+
+ if sub == 'from':
+ return p_('Contact subscription', 'From')
- return uf_sub
+ if sub == 'both':
+ return p_('Contact subscription', 'Both')
+
+ return p_('Contact subscription', 'Unknown')
def get_uf_ask(ask: Union[str, None]) -> str:
if ask is None:
- uf_ask = p_('Contact subscription', 'None')
- elif ask == 'subscribe':
- uf_ask = p_('Contact subscription', 'Subscribe')
- else:
- uf_ask = ask
+ return p_('Contact subscription', 'None')
+
+ if ask == 'subscribe':
+ return p_('Contact subscription', 'Subscribe')
- return uf_ask
+ return ask
def get_uf_role(role: Union[Role, str], plural: bool = False) -> str:
@@ -280,13 +280,7 @@ def get_uf_relative_time(timestamp: float) -> str:
def to_one_line(msg: str) -> str:
msg = msg.replace('\\', '\\\\')
- msg = msg.replace('\n', '\\n')
- # s1 = 'test\ntest\\ntest'
- # s11 = s1.replace('\\', '\\\\')
- # s12 = s11.replace('\n', '\\n')
- # s12
- # 'test\\ntest\\\\ntest'
- return msg
+ return msg.replace('\n', '\\n')
def from_one_line(msg: str) -> str:
@@ -296,13 +290,7 @@ def from_one_line(msg: str) -> str:
# So here match '\\n' but not if you have a '\' before that
expr = re.compile(r'(?<!\\)\\n')
msg = expr.sub('\n', msg)
- msg = msg.replace('\\\\', '\\')
- # s12 = 'test\\ntest\\\\ntest'
- # s13 = re.sub('\n', s12)
- # s14 s13.replace('\\\\', '\\')
- # s14
- # 'test\ntest\\ntest'
- return msg
+ return msg.replace('\\\\', '\\')
def chatstate_to_string(chatstate: Optional[Chatstate]) -> str:
@@ -345,8 +333,7 @@ def build_command(executable: str, parameter: str) -> str:
# we add to the parameter (can hold path with spaces)
# "" so we have good parsing from shell
parameter = parameter.replace('"', '\\"') # but first escape "
- command = f'{executable} "{parameter}"'
- return command
+ return f'{executable} "{parameter}"'
def sanitize_filename(filename: str) -> str:
@@ -364,7 +351,7 @@ def sanitize_filename(filename: str) -> str:
]
filename = ''.join(char for char in filename if char not in blacklist)
- filename = ''.join(char for char in filename if 31 < ord(char))
+ filename = ''.join(char for char in filename if ord(char) > 31)
filename = unicodedata.normalize('NFKD', filename)
filename = filename.rstrip('. ')
@@ -565,12 +552,12 @@ def get_auth_sha(sid: str, initiator: str, target: str) -> str:
Return sha of sid + initiator + target used for proxy auth
'''
return hashlib.sha1(
- (f'{sid}{initiator}{target}').encode('utf-8')).hexdigest()
+ (f'{sid}{initiator}{target}').encode()).hexdigest()
def remove_invalid_xml_chars(string_: str) -> str:
if string_:
- string_ = re.sub(INVALID_XML_CHARS_REGEX, '', string_)
+ return re.sub(INVALID_XML_CHARS_REGEX, '', string_)
return string_
@@ -681,9 +668,8 @@ def jid_is_blocked(account: str, jid: str) -> bool:
def get_subscription_request_msg(account: Optional[str] = None) -> str:
- message = _('I would like to add you to my contact list.')
if account is None:
- return message
+ return _('I would like to add you to my contact list.')
message = app.settings.get_account_setting(
account, 'subscription_request_msg')
@@ -795,10 +781,9 @@ class AdditionalDataDict(collections.UserDict):
@staticmethod
def _get_path_childs(full_path: str) -> list[str]:
- path_childs = [full_path]
if ':' in full_path:
- path_childs = full_path.split(':')
- return path_childs
+ return full_path.split(':')
+ return [full_path]
def set_value(self, full_path: str, key: str, value: Optional[str]) -> None:
path_childs = self._get_path_childs(full_path)
@@ -851,7 +836,7 @@ class Singleton(type):
def __call__(cls, *args: Any, **kwargs: Any):
if cls not in cls._instances:
- cls._instances[cls] = super(Singleton, cls).__call__(
+ cls._instances[cls] = super().__call__(
*args, **kwargs)
return cls._instances[cls]
@@ -1459,28 +1444,25 @@ def warn_about_plain_connection(account: str,
def get_idle_status_message(state: str, status_message: str) -> str:
message = app.settings.get(f'auto{state}_message')
if not message:
- message = status_message
- else:
- message = message.replace('$S', '%(status)s')
- message = message.replace('$T', '%(time)s')
- message = message % {
- 'status': status_message,
- 'time': app.settings.get(f'auto{state}time')
- }
- return message
+ return status_message
+ message = message.replace('$S', '%(status)s')
+ message = message.replace('$T', '%(time)s')
+ return message % {
+ 'status': status_message,
+ 'time': app.settings.get(f'auto{state}time')
+ }
-def get_group_chat_nick(account: str, room_jid: Union[JID, str]) -> str:
- nick = app.nicks[account]
+def get_group_chat_nick(account: str, room_jid: Union[JID, str]) -> str:
client = app.get_client(account)
bookmark = client.get_module('Bookmarks').get_bookmark(room_jid)
if bookmark is not None:
if bookmark.nick is not None:
- nick = bookmark.nick
+ return bookmark.nick
- return nick
+ return app.nicks[account]
def get_random_muc_localpart() -> str:
@@ -1528,15 +1510,13 @@ def get_os_version() -> str:
def get_gobject_version() -> str:
- gobject_ver = '.'.join(map(str, GObject.pygobject_version))
- return gobject_ver
+ return '.'.join(map(str, GObject.pygobject_version))
def get_glib_version() -> str:
- glib_ver = '.'.join(map(str, [GLib.MAJOR_VERSION,
- GLib.MINOR_VERSION,
- GLib.MICRO_VERSION]))
- return glib_ver
+ return '.'.join(map(str, [GLib.MAJOR_VERSION,
+ GLib.MINOR_VERSION,
+ GLib.MICRO_VERSION]))
def make_path_from_jid(base_path: Path, jid: JID) -> Path:
=====================================
gajim/common/i18n.py
=====================================
@@ -140,9 +140,10 @@ def ngettext(s_sing: str,
'''
text = _translation.ngettext(s_sing, s_plural, n)
if n == 1 and replace_sing is not None:
- text = text % replace_sing
- elif n > 1 and replace_plural is not None:
- text = text % replace_plural
+ return text % replace_sing
+
+ if n > 1 and replace_plural is not None:
+ return text % replace_plural
return text
=====================================
gajim/common/logging_helpers.py
=====================================
@@ -81,7 +81,7 @@ def parseAndSetLogLevels(arg: str) -> None:
file=sys.stderr)
-class colors:
+class Colors:
NONE = chr(27) + '[0m'
BLACK = chr(27) + '[30m'
RED = chr(27) + '[31m'
@@ -102,19 +102,19 @@ class colors:
def colorize(text: str, color: str) -> str:
- return color + text + colors.NONE
+ return color + text + Colors.NONE
class FancyFormatter(logging.Formatter):
'''
- An eye-candy formatter with colors
+ An eye-candy formatter with Colors
'''
colors_mapping = {
- 'DEBUG': colors.BLUE,
- 'INFO': colors.GREEN,
- 'WARNING': colors.BROWN,
- 'ERROR': colors.RED,
- 'CRITICAL': colors.BRIGHT_RED,
+ 'DEBUG': Colors.BLUE,
+ 'INFO': Colors.GREEN,
+ 'WARNING': Colors.BROWN,
+ 'ERROR': Colors.RED,
+ 'CRITICAL': Colors.BRIGHT_RED,
}
def __init__(self,
@@ -129,7 +129,7 @@ def formatTime(self,
datefmt: Optional[str] = None) -> str:
f = logging.Formatter.formatTime(self, record, datefmt)
if self.use_color:
- f = colorize(f, colors.DARK_GRAY)
+ f = colorize(f, Colors.DARK_GRAY)
return f
def format(self, record: logging.LogRecord) -> str:
@@ -139,7 +139,7 @@ def format(self, record: logging.LogRecord) -> str:
if self.use_color:
c = FancyFormatter.colors_mapping.get(level, '')
record.levelname = colorize(record.levelname, c)
- record.name = '%-25s' % colorize(record.name, colors.CYAN)
+ record.name = '%-25s' % colorize(record.name, Colors.CYAN)
else:
record.name = '%-25s|' % record.name
=====================================
gajim/common/modules/bookmarks.py
=====================================
@@ -21,8 +21,6 @@
from typing import Optional
from typing import cast
-import functools
-
from nbxmpp.namespaces import Namespace
from nbxmpp.protocol import JID
from nbxmpp.structs import BookmarkData
@@ -153,7 +151,6 @@ def pass_disco(self, info: DiscoInfo) -> None:
self._compat = Namespace.BOOKMARKS_COMPAT in info.features
self._conversion = Namespace.BOOKMARK_CONVERSION in info.features
- @functools.lru_cache(maxsize=1)
def _bookmark_module(self) -> str:
if not self._con.get_module('PubSub').publish_options:
return 'PrivateBookmarks'
=====================================
gajim/common/modules/bytestream.py
=====================================
@@ -321,7 +321,7 @@ def _add_local_ips_as_streamhosts_to_query(self,
my_ips = [my_ip]
# all IPs from local DNS
for addr in socket.getaddrinfo(socket.gethostname(), None):
- if (not addr[4][0] in my_ips and
+ if (addr[4][0] not in my_ips and
not addr[4][0].startswith('127') and
not addr[4][0] == '::1'):
my_ips.append(addr[4][0])
=====================================
gajim/common/regex.py
=====================================
@@ -95,13 +95,13 @@ class PRECIS:
IdentifierClass: Any
-class PRECIS_IdentifierClass:
+class PRECISIdentifierClass:
_p = PRECIS
Valid = fr'{_p.LetterDigits}\x21-\x7e'
Disallowed = fr'{_p.Spaces}{_p.Symbols}{_p.HasCompat}' # there's a ton more
-PRECIS.IdentifierClass = PRECIS_IdentifierClass
+PRECIS.IdentifierClass = PRECISIdentifierClass
# (Rough approximation of) Jabber IDs, as defined in [XMPP: Address Format]
=====================================
gajim/common/setting_values.py
=====================================
@@ -27,12 +27,12 @@ class _DEFAULT:
pass
-class _ACCOUNT_DEFAULT:
+class _ACCOUNTDEFAULT:
pass
HAS_APP_DEFAULT = _DEFAULT()
-HAS_ACCOUNT_DEFAULT = _ACCOUNT_DEFAULT()
+HAS_ACCOUNT_DEFAULT = _ACCOUNTDEFAULT()
BoolSettings = Literal[
=====================================
gajim/gtk/adhoc.py
=====================================
@@ -329,9 +329,7 @@ def _on_is_valid(self, _widget: DataFormWidget, is_valid: bool) -> None:
self.update_page_complete()
def get_visible_buttons(self) -> list[str]:
- actions = list(map(lambda action: action.value,
- self._last_stage_data.actions))
- return actions
+ return [action.value for action in self._last_stage_data.actions]
def get_default_button(self) -> str:
return self._last_stage_data.default.value
=====================================
gajim/gtk/assistant.py
=====================================
@@ -30,17 +30,17 @@
class Assistant(Gtk.ApplicationWindow, EventHelper):
- __gsignals__ = dict(
- button_clicked=(
+ __gsignals__ = {
+ 'button-clicked': (
GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION,
None,
(str, )
),
- page_changed=(
+ 'page-changed': (
GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION,
None,
(str, )
- ))
+ )}
def __init__(self,
transient_for: Optional[Gtk.Window] = None,
=====================================
gajim/gtk/chat_function_page.py
=====================================
@@ -44,7 +44,7 @@ class FunctionMode(Enum):
CHANGE_NICKNAME = 'change-nickname'
KICK = 'kick'
BAN = 'ban'
- PASSWORD_REQUEST = 'password-request'
+ PASSWORD_REQUEST = 'password-request' # noqa: S105
CAPTCHA_REQUEST = 'captcha-request'
CAPTCHA_ERROR = 'captcha-error'
JOIN_FAILED = 'join-failed'
=====================================
gajim/gtk/css_config.py
=====================================
@@ -169,7 +169,7 @@ def _load_css_from_file(self,
) -> None:
path = configpaths.get('STYLE') / filename
try:
- with open(path, 'r', encoding='utf8') as file_:
+ with open(path, encoding='utf8') as file_:
css = file_.read()
except Exception as exc:
log.error('Error loading css: %s', exc)
=====================================
gajim/gtk/dataform.py
=====================================
@@ -516,9 +516,7 @@ def __init__(self,
self._store.append(
[label, value, label, value in field.values])
- labels_over_max_width = map(lambda x: len(x) > 40,
- [option[0] for option in field.options])
- if any(labels_over_max_width):
+ if any(filter(lambda x: len(x[0]) > 40, field.options)):
self.set_tooltip_column(2)
self.set_model(self._store)
=====================================
gajim/gtk/menus.py
=====================================
@@ -671,8 +671,7 @@ def get_chat_row_menu(contact: types.ChatContactT,
'win.retract-message',
param))
- menu = GajimMenu.from_list(menu_items)
- return menu
+ return GajimMenu.from_list(menu_items)
def get_preview_menu(preview: Preview) -> GajimMenu:
=====================================
gajim/gtk/message_input.py
=====================================
@@ -225,7 +225,7 @@ def _get_spell_checker_language(self,
assert isinstance(lang, str)
lang = Gspell.language_lookup(lang)
if lang is None:
- lang = Gspell.language_get_default()
+ return Gspell.language_get_default()
return lang
def _on_language_changed(self,
@@ -347,8 +347,7 @@ def has_text(self) -> bool:
def get_text(self) -> str:
buf = self.get_buffer()
start, end = buf.get_bounds()
- text = self.get_buffer().get_text(start, end, True)
- return text
+ return self.get_buffer().get_text(start, end, True)
def _on_toggle_spell_check(self, *args: Any) -> None:
if not app.is_installed('GSPELL'):
=====================================
gajim/gtk/status_icon.py
=====================================
@@ -46,11 +46,11 @@
if app.is_installed('APPINDICATOR'):
# pylint: disable=ungrouped-imports
- from gi.repository import AppIndicator3 as appindicator
+ from gi.repository import AppIndicator3 as AppIndicator
elif app.is_installed('AYATANA_APPINDICATOR'):
# pylint: disable=ungrouped-imports
- from gi.repository import AyatanaAppIndicator3 as appindicator
+ from gi.repository import AyatanaAppIndicator3 as AppIndicator
log = logging.getLogger('gajim.gui.statusicon')
@@ -61,7 +61,7 @@ def __init__(self) -> None:
if self._can_use_libindicator():
app.settings.connect_signal('show_trayicon',
self._on_setting_changed)
- self._backend = AppIndicator()
+ self._backend = AppIndicatorIcon()
log.info('Use AppIndicator3 backend')
elif app.is_display(Display.WAYLAND):
self._backend = NoneBackend()
@@ -295,16 +295,16 @@ def _build_menu(self, button: int, event_time: int) -> None:
None, None, None, None, button, event_time)
-class AppIndicator(GtkMenuBackend):
+class AppIndicatorIcon(GtkMenuBackend):
def __init__(self) -> None:
GtkMenuBackend.__init__(self)
- self._status_icon = appindicator.Indicator.new(
+ self._status_icon = AppIndicator.Indicator.new(
'Gajim',
'org.gajim.Gajim',
- appindicator.IndicatorCategory.COMMUNICATIONS)
+ AppIndicator.IndicatorCategory.COMMUNICATIONS)
self._status_icon.set_icon_theme_path(str(configpaths.get('ICONS')))
- self._status_icon.set_status(appindicator.IndicatorStatus.ACTIVE)
+ self._status_icon.set_status(AppIndicator.IndicatorStatus.ACTIVE)
self._status_icon.set_menu(self._ui.systray_context_menu)
self._status_icon.set_secondary_activate_target(
self._ui.toggle_window_menuitem)
@@ -313,10 +313,10 @@ def __init__(self) -> None:
def update_state(self, init: bool = False) -> None:
if not app.settings.get('show_trayicon'):
- self._status_icon.set_status(appindicator.IndicatorStatus.PASSIVE)
+ self._status_icon.set_status(AppIndicator.IndicatorStatus.PASSIVE)
return
- self._status_icon.set_status(appindicator.IndicatorStatus.ACTIVE)
+ self._status_icon.set_status(AppIndicator.IndicatorStatus.ACTIVE)
if not init and app.window.get_total_unread_count():
icon_name = 'dcraven-message-new'
@@ -335,7 +335,7 @@ def update_state(self, init: bool = False) -> None:
def is_visible(self) -> bool:
status = self._status_icon.get_status()
- return status == appindicator.IndicatorStatus.ACTIVE
+ return status == AppIndicator.IndicatorStatus.ACTIVE
def shutdown(self) -> None:
pass
=====================================
gajim/gtk/util.py
=====================================
@@ -406,11 +406,10 @@ def format_tune(data: TuneData) -> str:
title = GLib.markup_escape_text(data.title or _('Unknown Title'))
source = GLib.markup_escape_text(data.source or _('Unknown Source'))
- tune_string = _('<b>"%(title)s"</b> by <i>%(artist)s</i>\n'
- 'from <i>%(source)s</i>') % {'title': title,
- 'artist': artist,
- 'source': source}
- return tune_string
+ return _('<b>"%(title)s"</b> by <i>%(artist)s</i>\n'
+ 'from <i>%(source)s</i>') % {'title': title,
+ 'artist': artist,
+ 'source': source}
def get_account_tune_icon_name(account: str) -> Optional[str]:
@@ -720,11 +719,10 @@ def open_window(name: str, **kwargs: Any) -> Any:
def get_gtk_version() -> str:
- gtk_ver = '%i.%i.%i' % (
+ return '%i.%i.%i' % (
Gtk.get_major_version(),
Gtk.get_minor_version(),
Gtk.get_micro_version())
- return gtk_ver
class EventHelper(CommonEventHelper):
=====================================
gajim/plugins/pluginmanager.py
=====================================
@@ -268,8 +268,8 @@ def _load_plugin_module(self,
for module_attr_name in dir(module):
module_attr = getattr(module, module_attr_name)
if issubclass(module_attr, GajimPlugin):
- setattr(module_attr, 'manifest', manifest)
- setattr(module_attr, '__path__', str(manifest.path))
+ module_attr.manifest = manifest
+ module_attr.__path__ = str(manifest.path)
return module_attr
return None
=====================================
pylintrc deleted
=====================================
@@ -1,439 +0,0 @@
-[MASTER]
-
-# A comma-separated list of package or module names from where C extensions may
-# be loaded. Extensions are loading into the active Python interpreter and may
-# run arbitrary code
-extension-pkg-whitelist=
-
-# Add files or directories to the blacklist. They should be base names, not
-# paths.
-ignore=gui
-
-# Add files or directories matching the regex patterns to the blacklist. The
-# regex matches against base names, not paths.
-ignore-patterns=
-
-# Python code to execute, usually for sys.path manipulation such as
-# pygtk.require().
-#init-hook=
-
-# Use multiple processes to speed up Pylint.
-jobs=2
-
-# List of plugins (as comma separated values of python modules names) to load,
-# usually to register additional checkers.
-load-plugins=
-
-# Pickle collected data for later comparisons.
-persistent=yes
-
-# Specify a configuration file.
-#rcfile=
-
-# Allow loading of arbitrary C extensions. Extensions are imported into the
-# active Python interpreter and may run arbitrary code.
-unsafe-load-any-extension=no
-
-
-[MESSAGES CONTROL]
-
-# Only show warnings with the listed confidence levels. Leave empty to show
-# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
-confidence=
-
-# Disable the message, report, category or checker with the given id(s). You
-# can either give multiple identifiers separated by comma (,) or put this
-# option multiple times (only on the command line, not in the configuration
-# file where it should appear only once).You can also use "--disable=all" to
-# disable everything first and then re-enable specific checks. For example, if
-# you want to run only the similarities checker, you can use "--disable=all
-# --enable=similarities". If you want to run only the classes checker, but have
-# no Warning level messages displayed, use"--disable=all --enable=classes
-# --disable=W"
-#
-# Errors which are covered by pyright
-#
-# E0401 import-error
-# E1101 no-member
-# E1102 not-callable
-# E1111 assignment-from-no-return
-# E1120 no-value-for-parameter
-# E1121 too-many-function-args
-# E1123 unexpected-keyword-arg
-# E1124 redundant-keyword-arg
-# E1125 missing-kwoa
-# E1126 invalid-sequence-index
-# E1127 invalid-slice-index
-# E1128 assignment-from-none
-# E1129 not-context-manager
-# E1130 invalid-unary-operand-type
-# E1131 unsupported-binary-operation
-# E1132 repeated-keyword
-# E1133 not-an-iterable
-# E1134 not-a-mapping
-# E1135 unsupported-membership-test
-# E1136 unsubscriptable-object
-# E1137 unsupported-assignment-operation
-# E1138 unsupported-delete-operation
-# E1139 invalid-metaclass
-# E1140 unhashable-dict-key
-# E1141 dict-iter-missing-items
-# E1142 await-outside-async
-# I1101 c-extension-no-member
-# W0212 protected-access
-# W1113 keyword-arg-before-vararg
-# W1114 arguments-out-of-order
-# W1115 non-str-assignment-to-dunder-name
-# W1116 isinstance-second-argument-not-valid-type
-#
-# Errors which are covered by flake8
-#
-# C0301 line-too-long
-# C0303 trailing-whitespace
-# C0304 missing-final-newline
-# C0321 multiple-statements
-# W0301 unnecessary-semicolon
-# W0311 bad-indentation
-# W0611 unused-import
-#
-# Ignore Always, we don’t need these checks
-#
-# C0111 missing-docstring
-# C0209 use-f-string
-# C0302 too-many-lines
-# C0411 wrong-import-order
-# C0413 wrong-import-position
-# R0801 duplicat-code
-# R0904 too-many-public-methods
-# R0913 too-many-arguments
-# R0915 too-many-statements
-# R1725 super-with-arguments
-# R1732 consider-using-with
-# W0237 arguments-renamed
-# W0511 fix-me
-# W0707 raise-missing-from
-# W1404 implicit-str-concat
-# W1406 redundant-u-string-prefix
-
-disable=E0401,E1101,E1102,E1111,E1120,E1121,E1123,E1124,E1125,E1126,E1127,E1128,E1129,E1130,E1131,E1132,E1133,E1134,E1135,E1136,E1137,E1138,E1139,E1140,E1141,E1142,I1101,W0212,W1113,W1114,W1115,W1116,C0301,C0303,C0304,C0321,C0411,C0413,W0301,W0311,W0611,C0111,C0209,C0302,R0801,R0904,R0913,R0915,R1725,R1732,W0237,W0311,W0511,W0707,W1404,W1406
-
-# Enable the message, report, category or checker with the given id(s). You can
-# either give multiple identifier separated by comma (,) or put this option
-# multiple time (only on the command line, not in the configuration file where
-# it should appear only once). See also the "--disable" option for examples.
-enable=
-
-
-[REPORTS]
-
-# Python expression which should return a note less than 10 (10 is the highest
-# note). You have access to the variables errors warning, statement which
-# respectively contain the number of errors / warnings messages and the total
-# number of statements analyzed. This is used by the global evaluation report
-# (RP0004).
-evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
-
-# Template used to display messages. This is a python new-style format string
-# used to format the message information. See doc for all details
-#msg-template=
-
-# Set the output format. Available formats are text, parseable, colorized, json
-# and msvs (visual studio).You can also give a reporter class, eg
-# mypackage.mymodule.MyReporterClass.
-output-format=text
-
-# Tells whether to display a full report or only the messages
-reports=no
-
-# Activate the evaluation score.
-score=no
-
-
-[REFACTORING]
-
-# Maximum number of nested blocks for function / method body
-max-nested-blocks=5
-
-
-[VARIABLES]
-
-# List of additional names supposed to be defined in builtins. Remember that
-# you should avoid to define new builtins when possible.
-additional-builtins=
-
-# Tells whether unused global variables should be treated as a violation.
-allow-global-unused-variables=yes
-
-# List of strings which can identify a callback function by name. A callback
-# name must start or end with one of those strings.
-callbacks=cb_,_cb
-
-# A regular expression matching the name of dummy variables (i.e. expectedly
-# not used).
-dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy
-
-# Argument names that match this expression will be ignored. Default to name
-# with leading underscore
-ignored-argument-names=(_.*|kwargs|args)
-
-# Tells whether we should check for unused import in __init__ files.
-init-import=no
-
-# List of qualified module names which can have objects that can redefine
-# builtins.
-redefining-builtins-modules=six.moves,future.builtins
-
-
-[TYPECHECK]
-
-# List of decorators that produce context managers, such as
-# contextlib.contextmanager. Add to this list to register other decorators that
-# produce valid context managers.
-contextmanager-decorators=contextlib.contextmanager
-
-# List of members which are set dynamically and missed by pylint inference
-# system, and so shouldn't trigger E1101 when accessed. Python regular
-# expressions are accepted.
-generated-members=
-
-# Tells whether missing members accessed in mixin class should be ignored. A
-# mixin class is detected if its name ends with "mixin" (case insensitive).
-ignore-mixin-members=yes
-
-# List of class names for which member attributes should not be checked (useful
-# for classes with dynamically set attributes). This supports the use of
-# qualified names.
-ignored-classes=optparse.Values,thread._local,_thread._local,gi.repository.GLib.Error
-
-# List of module names for which member attributes should not be checked
-# (useful for modules/projects where namespaces are manipulated during runtime
-# and thus existing member attributes cannot be deduced by static analysis. It
-# supports qualified module names, as well as Unix pattern matching.
-ignored-modules=gi.repository,cairo,gajim.gui
-
-# Show a hint with possible names when a member name was not found. The aspect
-# of finding the hint is based on edit distance.
-missing-member-hint=yes
-
-# The minimum edit distance a name should have in order to be considered a
-# similar match for a missing member name.
-missing-member-hint-distance=1
-
-# The total number of similar names that should be taken in consideration when
-# showing a hint for a missing member.
-missing-member-max-choices=1
-
-
-[SPELLING]
-
-# Spelling dictionary name. Available dictionaries: none. To make it working
-# install python-enchant package.
-spelling-dict=
-
-# List of comma separated words that should not be checked.
-spelling-ignore-words=
-
-# A path to a file that contains private dictionary; one word per line.
-spelling-private-dict-file=
-
-# Tells whether to store unknown words to indicated private dictionary in
-# --spelling-private-dict-file option instead of raising a message.
-spelling-store-unknown-words=no
-
-
-[SIMILARITIES]
-
-# Ignore comments when computing similarities.
-ignore-comments=yes
-
-# Ignore docstrings when computing similarities.
-ignore-docstrings=yes
-
-# Ignore imports when computing similarities.
-ignore-imports=no
-
-# Minimum lines number of a similarity.
-min-similarity-lines=4
-
-
-[MISCELLANEOUS]
-
-# List of note tags to take in consideration, separated by a comma.
-notes=FIXME,XXX,TODO
-
-
-[LOGGING]
-
-# Logging modules to check that the string format arguments are in logging
-# function parameter format
-logging-modules=logging
-
-
-[FORMAT]
-
-# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
-expected-line-ending-format=
-
-# Regexp for a line that is allowed to be longer than the limit.
-ignore-long-lines=^\s*(# )?<?https?://\S+>?$
-
-# Number of spaces of indent required inside a hanging or continued line.
-indent-after-paren=4
-
-# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
-# tab).
-indent-string=' '
-
-# Maximum number of characters on a single line.
-max-line-length=80
-
-# Maximum number of lines in a module
-max-module-lines=3000
-
-# Allow the body of an if to be on the same line as the test if there is no
-# else.
-single-line-if-stmt=no
-
-
-[BASIC]
-
-# Regular expression matching correct argument names
-argument-rgx=(([a-z][a-z0-9_]{1,30})|(_[a-z0-9_]*))$
-
-# Regular expression matching correct attribute names
-attr-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
-
-# Bad variable names which should always be refused, separated by a comma
-bad-names=foo,bar,baz,toto,tutu,tata
-
-# Regular expression matching correct class attribute names
-class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
-
-# Regular expression matching correct class names
-class-rgx=[A-Z_][a-zA-Z0-9]+$
-
-# Regular expression matching correct constant names
-const-rgx=
-
-# Minimum line length for functions/classes that require docstrings, shorter
-# ones are exempt.
-docstring-min-length=-1
-
-# Regular expression matching correct function names
-function-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
-
-# Good variable names which should always be accepted, separated by a comma
-good-names=i,j,k,ex,Run,_,iq
-
-# Include a hint for the correct naming format with invalid-name
-include-naming-hint=no
-
-# Regular expression matching correct inline iteration names
-inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
-
-# Regular expression matching correct method names
-method-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
-
-# Regular expression matching correct module names
-module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
-
-# Colon-delimited sets of names that determine each other's naming style when
-# the name regexes allow several styles.
-name-group=
-
-# Regular expression which should only match function or class names that do
-# not require a docstring.
-no-docstring-rgx=^_
-
-# List of decorators that produce properties, such as abc.abstractproperty. Add
-# to this list to register other decorators that produce valid properties.
-property-classes=abc.abstractproperty
-
-# Regular expression matching correct variable names
-variable-rgx=(([a-z][a-z0-9_]{1,30})|(_[a-z0-9_]*))$
-
-
-[IMPORTS]
-
-# Analyse import fallback blocks. This can be used to support both Python 2 and
-# 3 compatible code, which means that the block might have code that exists
-# only in one or another interpreter, leading to false positives when analysed.
-analyse-fallback-blocks=no
-
-# Deprecated modules which should not be used, separated by a comma
-deprecated-modules=optparse,tkinter.tix
-
-# Create a graph of external dependencies in the given file (report RP0402 must
-# not be disabled)
-ext-import-graph=
-
-# Create a graph of every (i.e. internal and external) dependencies in the
-# given file (report RP0402 must not be disabled)
-import-graph=
-
-# Create a graph of internal dependencies in the given file (report RP0402 must
-# not be disabled)
-int-import-graph=
-
-# Force import order to recognize a module as part of the standard
-# compatibility libraries.
-known-standard-library=
-
-# Force import order to recognize a module as part of a third party library.
-known-third-party=enchant
-
-
-[DESIGN]
-
-# Maximum number of arguments for function / method
-max-args=15
-
-# Maximum number of attributes for a class (see R0902).
-max-attributes=9999
-
-# Maximum number of boolean expressions in a if statement
-max-bool-expr=5
-
-# Maximum number of branch for function / method body
-max-branches=50
-
-# Maximum number of locals for function / method body
-max-locals=50
-
-# Maximum number of parents for a class (see R0901).
-max-parents=7
-
-# Maximum number of public methods for a class (see R0904).
-max-public-methods=50
-
-# Maximum number of return / yield for function / method body
-max-returns=100
-
-# Maximum number of statements in function / method body
-max-statements=100
-
-# Minimum number of public methods for a class (see R0903).
-min-public-methods=0
-
-
-[CLASSES]
-
-# List of method names used to declare (i.e. assign) instance attributes.
-defining-attr-methods=__init__,__new__,setUp
-
-# List of member names, which should be excluded from the protected access
-# warning.
-exclude-protected=_asdict,_fields,_replace,_source,_make
-
-# List of valid names for the first argument in a class method.
-valid-classmethod-first-arg=cls
-
-# List of valid names for the first argument in a metaclass class method.
-valid-metaclass-classmethod-first-arg=mcs
-
-
-[EXCEPTIONS]
-
-# Exceptions that will emit a warning when being caught. Defaults to
-# "Exception"
-overgeneral-exceptions=
=====================================
pyproject.toml
=====================================
@@ -163,24 +163,42 @@ select = [
"C901", # mccabe
# "D", # pydocstyle
"E", # pycodestyle
+ # "ERA", # eradicate
"F", # pyflakes
# "FBT", # flake8-boolean-trap
# "I", # flake8-tidy-imports, isort
- "M", # Meta rules
"N", # pep8-naming
+ "PGH", # pylint
+ "PLC", # pylint
+ "PLE", # pylint
+ "PLR", # pylint
+ "PLW", # pylint
"Q", # flake8-quotes
"RUF", # Ruff-specific rules
+ # "RET", # flake8-return
"S", # flake8-bandit
- "T", # flake8-debugger, flake8-print
- "U", # pyupgrade
+ # "T", # flake8-debugger, flake8-print
+ "UP", # pyupgrade
"W", # pycodestyle
"YTT", # flake8-2020
]
ignore = [
- "S101", # Use of `assert` detected
- "FBT003", # Boolean positional value in function call
+ "A003", # Class attribute is shadowing python builtin
+ "B904", # Within an except clause ..
"BLE001", # Blind except Exception: statement
+ "C901", # too complex
+ "FBT003", # Boolean positional value in function call
+ "N802", # Function name should be lower case
+ "N806", # Variable should be lower case
+ "N817", # CamelCase imported as acronym
+ "N818", # Exception name should be named with an Error suffix
+ "RUF001", # AmbiguousUnicodeCharacterString
+ "RUF002", # AmbiguousUnicodeCharacterDocstring
+ "RUF003", # AmbiguousUnicodeCharacterComment
+ "RUF100", # Unused `noqa` directive
+ "S101", # Use of `assert` detected
+ "UP007", # Use X | Y for type annotations
]
exclude = [
@@ -197,7 +215,7 @@ exclude = [
"typings",
"gajim/common/config.py", # legacy module, will be removed
"gajim/common/optparser.py", # legacy module, will be removed
- "gajim/common/socks5.py", # legacy module, will be removed
+ "gajim/common/socks5.py", # legacy module, will be removed
]
# Allow unused variables when underscore-prefixed.
=====================================
scripts/pre-push-tests.sh
=====================================
@@ -6,10 +6,10 @@ set -e
GREEN='\033[0;32m'
-./scripts/dev/pylint-ci.sh gajim
-echo "${GREEN}pylint: \t OK"
-mypy gajim
-echo "${GREEN}mypy: \t\t OK"
-codespell -I codespell.conf --skip="*__pycache__*,gajim/data/icons,gajim/data/sounds,gajim/data/emoticons" gajim
+pyright
+echo "${GREEN}pyright: \t OK"
+ruff .
+echo "${GREEN}ruff: \t\t OK"
+codespell gajim
echo "${GREEN}codespell: \t OK"
echo "${GREEN}ready to push"
=====================================
setup.cfg
=====================================
@@ -1,27 +1,3 @@
-[flake8]
-ignore = W504, C901
-exclude =
- __pycache__,
- build,
- dist,
- debian_build,
- test,
- typings,
- gajim/common/config.py,
- gajim/common/optparser.py,
- gajim/common/regex.py,
- gajim/common/socks5.py,
- gajim/gui,
-max-complexity = 15
-builtins=_
-max-line-length = 80
-statistics = True
-count = True
-
-inline-quotes = single
-multiline-quotes = '''
-docstring-quotes = '''
-
[metadata]
name = gajim
version = attr: gajim.__version__
=====================================
setup.py
=====================================
@@ -156,7 +156,7 @@ def merge(in_file: Path,
log.info('Compiling %s >> %s', in_file, out_file)
-class build(_build):
+class Build(_build):
def run(self):
build_translation()
if sys.platform != 'win32':
@@ -165,7 +165,7 @@ def run(self):
_build.run(self)
-class install(_install):
+class Install(_install):
def run(self):
data_files = cast(DataFilesT, self.distribution.data_files) # pyright: ignore # noqa: E501
install_trans(data_files)
@@ -187,8 +187,8 @@ def run(self):
setup(
cmdclass={
- 'build_py': build,
- 'install': install,
+ 'build_py': Build,
+ 'install': Install,
},
entry_points={
'console_scripts': [
=====================================
test/no_gui/test_styling.py
=====================================
@@ -5,7 +5,7 @@
gui.init('gtk')
from gajim.common import app # Avoids circular imports from common.helpers
-import gajim.common.styling as styling
+from gajim.common import styling
from gajim.common.styling import PlainBlock
from gajim.common.styling import PreBlock
from gajim.common.styling import QuoteBlock
View it on GitLab: https://dev.gajim.org/gajim/gajim/-/compare/5265a80ce7ac7343cb299c8eb1e79cf…
--
View it on GitLab: https://dev.gajim.org/gajim/gajim/-/compare/5265a80ce7ac7343cb299c8eb1e79cf…
You're receiving this email because of your account on dev.gajim.org.