diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index d074805ba..52e2e9c81 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -50,11 +50,6 @@ jobs: run: | tox -e codestyle - - name: Lint - sort - if: ${{ matrix.python-version == '3.12' }} - run: | - tox -e sort - - name: Security if: ${{ matrix.python-version == '3.12' }} run: | diff --git a/CHANGES.rst b/CHANGES.rst index 4a3c7b56f..da17ff3a3 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -12,6 +12,7 @@ fixes: - docs: fix telegram install command (#1697) - chore: add python versions to test (#1705) - chore: remove python 3.8 support (#1707) +- chore: use ruff for formatting (#1706) v6.2.0 (2024-01-01) ------------------- diff --git a/docs/conf.py b/docs/conf.py index 3c062fc85..5f7bed142 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -12,7 +12,9 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import subprocess, sys, os +import subprocess +import sys +import os sys.path.append(os.path.abspath('_themes')) sys.path.append(os.path.abspath('_themes/err')) sys.path.append(os.path.abspath('../')) diff --git a/errbot/__init__.py b/errbot/__init__.py index 3e4ebab6b..ea2903da5 100644 --- a/errbot/__init__.py +++ b/errbot/__init__.py @@ -3,9 +3,8 @@ import logging import re import shlex -import sys from functools import wraps -from typing import Any, Callable, List, Optional, Tuple +from typing import Any, Callable, Optional, Tuple from .backends.base import AWAY, DND, OFFLINE, ONLINE, Message # noqa from .botplugin import ( # noqa @@ -16,7 +15,7 @@ ShlexArgParser, ValidationException, ) -from .core_plugins.wsview import WebView, route +from .core_plugins.wsview import route from .flow import FLOW_END, BotFlow, Flow, FlowRoot __all__ = [ diff --git a/errbot/backend_plugin_manager.py b/errbot/backend_plugin_manager.py index 5a3a0bba1..ee40bebe1 100644 --- a/errbot/backend_plugin_manager.py +++ b/errbot/backend_plugin_manager.py @@ -15,7 +15,7 @@ class PluginNotFoundException(Exception): def enumerate_backend_plugins( - all_plugins_paths: List[Union[str, Path]] + all_plugins_paths: List[Union[str, Path]], ) -> Iterator[PluginInfo]: plugin_places = [Path(root) for root in all_plugins_paths] for path in plugin_places: diff --git a/errbot/backends/base.py b/errbot/backends/base.py index 757743575..11822eb64 100644 --- a/errbot/backends/base.py +++ b/errbot/backends/base.py @@ -4,7 +4,7 @@ import time from abc import ABC, abstractmethod from collections import defaultdict, deque -from typing import Any, BinaryIO, List, Mapping, Optional, Sequence, Tuple +from typing import Any, BinaryIO, List, Mapping, Optional, Sequence, Tuple, Type log = logging.getLogger(__name__) @@ -391,7 +391,7 @@ def extras(self) -> Mapping: return self._extras @property - def flow(self) -> "errbot.Flow": + def flow(self) -> Type["errbot.Flow"]: # noqa: F821 """ Get the conversation flow for this message. diff --git a/errbot/backends/irc.py b/errbot/backends/irc.py index a1755af0f..abc82a4e6 100644 --- a/errbot/backends/irc.py +++ b/errbot/backends/irc.py @@ -49,11 +49,11 @@ bg_default=NSC("\x03,"), fx_reset=NSC("\x03"), fx_bold=NSC("\x02"), - fx_italic=NSC("\x1D"), - fx_underline=NSC("\x1F"), - fx_not_italic=NSC("\x0F"), - fx_not_underline=NSC("\x0F"), - fx_normal=NSC("\x0F"), + fx_italic=NSC("\x1d"), + fx_underline=NSC("\x1f"), + fx_not_italic=NSC("\x0f"), + fx_not_underline=NSC("\x0f"), + fx_normal=NSC("\x0f"), fixed_width="", end_fixed_width="", inline_code="", diff --git a/errbot/backends/telegram_messenger.py b/errbot/backends/telegram_messenger.py index 6002c4e3e..f66766cdb 100644 --- a/errbot/backends/telegram_messenger.py +++ b/errbot/backends/telegram_messenger.py @@ -1,6 +1,6 @@ import logging import sys -from typing import Any, BinaryIO, List, Optional, Union +from typing import Any, BinaryIO, Optional, Union from errbot.backends.base import ( ONLINE, diff --git a/errbot/backends/xmpp.py b/errbot/backends/xmpp.py index f54cc9de0..8e28da034 100644 --- a/errbot/backends/xmpp.py +++ b/errbot/backends/xmpp.py @@ -5,7 +5,7 @@ from datetime import datetime from functools import lru_cache from time import sleep -from typing import Callable, List, Optional, Tuple +from typing import Callable, List, Optional, Tuple, Union from errbot.backends.base import ( AWAY, @@ -28,7 +28,6 @@ try: from slixmpp import JID, ClientXMPP from slixmpp.exceptions import IqError - from slixmpp.xmlstream import cert, resolver except ImportError: log.exception("Could not start the XMPP backend") diff --git a/errbot/botplugin.py b/errbot/botplugin.py index 79b50b009..d7a709a43 100644 --- a/errbot/botplugin.py +++ b/errbot/botplugin.py @@ -44,7 +44,7 @@ def recurse_check_structure(sample: Any, to_check: Any) -> None: recurse_check_structure(sample[0], element) return - if sample_type == dict: + if sample_type == dict: # noqa: E721 for key in sample: if key not in to_check: raise ValidationException(f"{to_check} doesn't contain the key {key}.") @@ -128,7 +128,7 @@ def __init__( self.definition = cmd_type(*((function,) + cmd_args), **cmd_kwargs) def append_args(self, args, kwargs): - from errbot import arg_botcmd, update_wrapper + from errbot import update_wrapper if hasattr(self.definition, "_err_command_parser"): update_wrapper(self.definition, args, kwargs) diff --git a/errbot/cli.py b/errbot/cli.py index 61934501a..8561f68ad 100755 --- a/errbot/cli.py +++ b/errbot/cli.py @@ -22,7 +22,6 @@ from os import W_OK, access, getcwd, path, sep from pathlib import Path from platform import system -from typing import Optional, Union from errbot.bootstrap import CORE_BACKENDS from errbot.logs import root_logger diff --git a/errbot/core.py b/errbot/core.py index 390e2ef7b..aee5a160e 100644 --- a/errbot/core.py +++ b/errbot/core.py @@ -55,12 +55,8 @@ def __init__(self, bot_config): log.debug( "created a thread pool of size %d.", bot_config.BOT_ASYNC_POOLSIZE ) - self.commands = ( - {} - ) # the dynamically populated list of commands available on the bot - self.re_commands = ( - {} - ) # the dynamically populated list of regex-based commands available on the bot + self.commands = {} # the dynamically populated list of commands available on the bot + self.re_commands = {} # the dynamically populated list of regex-based commands available on the bot self.command_filters = [] # the dynamically populated list of filters self.MSG_UNKNOWN_COMMAND = ( 'Unknown command: "%(command)s". ' @@ -287,8 +283,6 @@ def process_message(self, msg: Message) -> bool: log.debug("*** username = %s", username) log.debug("*** text = %s", text) - suppress_cmd_not_found = self.bot_config.SUPPRESS_CMD_NOT_FOUND - prefixed = False # Keeps track whether text was prefixed with a bot prefix only_check_re_command = ( False # Becomes true if text is determed to not be a regular command @@ -324,10 +318,6 @@ def process_message(self, msg: Message) -> bool: 'Assuming "%s" to be a command because BOT_PREFIX_OPTIONAL_ON_CHAT is True', text, ) - # In order to keep noise down we surpress messages about the command - # not being found, because it's possible a plugin will trigger on what - # was said with trigger_message. - suppress_cmd_not_found = True elif not text.startswith(self.bot_config.BOT_PREFIX): only_check_re_command = True if text.startswith(self.bot_config.BOT_PREFIX): diff --git a/errbot/core_plugins/chatRoom.py b/errbot/core_plugins/chatRoom.py index ff1a66ed5..fbf73ffd3 100644 --- a/errbot/core_plugins/chatRoom.py +++ b/errbot/core_plugins/chatRoom.py @@ -1,6 +1,6 @@ import logging -from errbot import BotPlugin, SeparatorArgParser, ShlexArgParser, botcmd +from errbot import BotPlugin, ShlexArgParser, botcmd from errbot.backends.base import RoomNotJoinedError log = logging.getLogger(__name__) diff --git a/errbot/core_plugins/plugins.py b/errbot/core_plugins/plugins.py index 5fc3be12a..9f09e54e7 100644 --- a/errbot/core_plugins/plugins.py +++ b/errbot/core_plugins/plugins.py @@ -187,7 +187,7 @@ def plugin_config(self, _, args): except Exception: self.log.exception("Invalid expression for the configuration of the plugin") return "Syntax error in the given configuration" - if type(real_config_obj) != type(template_obj): + if type(real_config_obj) is not type(template_obj): return "It looks fishy, your config type is not the same as the template!" self._bot.plugin_manager.set_plugin_configuration(plugin_name, real_config_obj) diff --git a/errbot/plugin_manager.py b/errbot/plugin_manager.py index e49ede6d4..fda47bc02 100644 --- a/errbot/plugin_manager.py +++ b/errbot/plugin_manager.py @@ -1,4 +1,4 @@ -""" Logic related to plugin loading and lifecycle """ +"""Logic related to plugin loading and lifecycle""" import logging import os diff --git a/errbot/rendering/xhtmlim.py b/errbot/rendering/xhtmlim.py index 3a07b8d77..fc760a2fe 100644 --- a/errbot/rendering/xhtmlim.py +++ b/errbot/rendering/xhtmlim.py @@ -190,7 +190,7 @@ def _replace_charref(s): if num in _invalid_charrefs: return _invalid_charrefs[num] if 0xD800 <= num <= 0xDFFF or num > 0x10FFFF: - return "\uFFFD" + return "\ufffd" if num in _invalid_codepoints: return "" return chr(num) diff --git a/errbot/repo_manager.py b/errbot/repo_manager.py index 165159331..9aebf133b 100644 --- a/errbot/repo_manager.py +++ b/errbot/repo_manager.py @@ -8,7 +8,7 @@ from datetime import datetime, timedelta from os import path from pathlib import Path -from typing import Dict, Generator, List, Optional, Sequence, Tuple, Union +from typing import Dict, Generator, List, Optional, Sequence, Tuple from urllib.error import HTTPError, URLError from urllib.parse import urlparse from urllib.request import Request, urlopen diff --git a/errbot/storage/__init__.py b/errbot/storage/__init__.py index c63ecf0de..595ebcb12 100644 --- a/errbot/storage/__init__.py +++ b/errbot/storage/__init__.py @@ -1,5 +1,4 @@ import logging -import types from collections.abc import MutableMapping from contextlib import contextmanager @@ -36,7 +35,7 @@ def open_storage(self, storage_plugin, namespace): def close_storage(self): if not self.is_open_storage(): - raise StoreNotOpenError(f"Storage does not appear to have been opened yet") + raise StoreNotOpenError("Storage does not appear to have been opened yet") self._store.close() self._store = None log.debug("Closed storage '%s'", self.namespace) diff --git a/tests/borken_plugin/broken.py b/tests/borken_plugin/broken.py index ae325114a..a48f8ae99 100644 --- a/tests/borken_plugin/broken.py +++ b/tests/borken_plugin/broken.py @@ -1,7 +1,6 @@ -import borken # fails on purpose - from errbot import BotPlugin, botcmd +import borken # fails on purpose # noqa: F401 class Broken(BotPlugin): @botcmd diff --git a/tests/cascade_dependent_plugins/child1.py b/tests/cascade_dependent_plugins/child1.py index de3c68c73..f4b676475 100644 --- a/tests/cascade_dependent_plugins/child1.py +++ b/tests/cascade_dependent_plugins/child1.py @@ -1,4 +1,4 @@ -from errbot import BotPlugin, botcmd +from errbot import BotPlugin class Child1(BotPlugin): diff --git a/tests/cascade_dependent_plugins/child2.py b/tests/cascade_dependent_plugins/child2.py index 68464a38f..5b0643acb 100644 --- a/tests/cascade_dependent_plugins/child2.py +++ b/tests/cascade_dependent_plugins/child2.py @@ -1,4 +1,4 @@ -from errbot import BotPlugin, botcmd +from errbot import BotPlugin class Child2(BotPlugin): diff --git a/tests/core_test.py b/tests/core_test.py index 77430116e..843f970a2 100755 --- a/tests/core_test.py +++ b/tests/core_test.py @@ -1,7 +1,5 @@ """Test _admins_to_notify wrapper functionality""" -import pytest - extra_config = {"BOT_ADMINS_NOTIFICATIONS": "zoni@localdomain"} diff --git a/tests/flow_plugin/flowtest_flows.py b/tests/flow_plugin/flowtest_flows.py index dd981f218..6f8e3c699 100644 --- a/tests/flow_plugin/flowtest_flows.py +++ b/tests/flow_plugin/flowtest_flows.py @@ -1,3 +1,4 @@ +# ruff: noqa: F841 from __future__ import absolute_import from errbot import BotFlow, FlowRoot, botflow diff --git a/tests/link_test.py b/tests/link_test.py index 695156170..80b1b4d02 100644 --- a/tests/link_test.py +++ b/tests/link_test.py @@ -1,7 +1,6 @@ # coding=utf-8 from os import path -import pytest extra_plugin_dir = path.join(path.dirname(path.realpath(__file__)), "test_link") diff --git a/tests/matchall_test.py b/tests/matchall_test.py index c0edd1740..8f99a374e 100644 --- a/tests/matchall_test.py +++ b/tests/matchall_test.py @@ -1,8 +1,6 @@ # coding=utf-8 from os import path -import pytest - extra_plugin_dir = path.join(path.dirname(path.realpath(__file__)), "matchall_plugin") diff --git a/tests/template_plugin/test.py b/tests/template_plugin/test.py index a6614ccf7..be0bac526 100644 --- a/tests/template_plugin/test.py +++ b/tests/template_plugin/test.py @@ -1,6 +1,6 @@ from __future__ import absolute_import -from errbot import BotPlugin, arg_botcmd, botcmd, re_botcmd +from errbot import BotPlugin, arg_botcmd, botcmd class Test(BotPlugin): diff --git a/tests/utils_test.py b/tests/utils_test.py index 858ee7d69..fb15c71e9 100644 --- a/tests/utils_test.py +++ b/tests/utils_test.py @@ -1,4 +1,7 @@ # coding=utf-8 +import logging +import sys + from datetime import timedelta import pytest @@ -8,7 +11,7 @@ from errbot.bootstrap import CORE_STORAGE, bot_config_defaults from errbot.storage import StoreMixin from errbot.storage.base import StoragePluginBase -from errbot.utils import * +from errbot.utils import version2tuple, format_timedelta, split_string_after log = logging.getLogger(__name__) diff --git a/tests/webhooks_test.py b/tests/webhooks_test.py index 62ae6135a..de32e6b03 100644 --- a/tests/webhooks_test.py +++ b/tests/webhooks_test.py @@ -7,7 +7,6 @@ import pytest import requests -from errbot.backends.test import FullStackTest, testbot log = logging.getLogger(__name__) diff --git a/tools/plugin-gen.py b/tools/plugin-gen.py index e83ede752..2f8e3de0f 100755 --- a/tools/plugin-gen.py +++ b/tools/plugin-gen.py @@ -187,7 +187,7 @@ def check_repo(repo): repo_entry[name] = plugin plugins[repo_name] = repo_entry log.debug("Catalog added plugin %s.", plugin["name"]) - except: + except Exception: log.error("Invalid syntax in %s, skipping...", plug["path"]) continue diff --git a/tox.ini b/tox.ini index 1decf8245..ac40f09c1 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py39,py310,py311,py312,py312,codestyle,dist-check,sort,security,docs +envlist = py39,py310,py311,py312,py312,codestyle,dist-check,security,docs skip_missing_interpreters = True [testenv] @@ -11,9 +11,9 @@ commands = pytest -v tests/ recreate = true [testenv:codestyle] -deps = black +deps = ruff commands = - black --check errbot/ tests/ tools/ + ruff check errbot/ tests/ tools/ [testenv:dist-check] deps = @@ -22,11 +22,6 @@ commands = python setup.py sdist twine check {toxinidir}/dist/* -[testenv:sort] -deps = - isort -commands = isort --check-only errbot/ - [testenv:security] deps = bandit