diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d970a96e..1ed8f87a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -80,7 +80,7 @@ Again, the most checks can be performed by `tox` command, though some additional >>> clazz = Clazz() """ - CLAZZ_ATTRIBUTE = 42 + CLAZZ_ATTRIBUTE: ClassVar[int] = 42 def __init__(self, *args: Any, **kwargs: Any) -> None: """ @@ -96,6 +96,7 @@ Again, the most checks can be performed by `tox` command, though some additional * Type annotations are the must, even for local functions. For the function argument `self` (for instance methods) and `cls` (for class methods) should not be annotated. * For collection types built-in classes must be used if possible (e.g. `dict` instead of `typing.Dict`, `tuple` instead of `typing.Tuple`). In case if built-in type is not available, but `collections.abc` provides interface, it must be used (e.g. `collections.abc.Awaitable` instead of `typing.Awaitable`, `collections.abc.Iterable` instead of `typing.Iterable`). For union classes, the bar operator (`|`) must be used (e.g. `float | int` instead of `typing.Union[float, int]`), which also includes `typing.Optional` (e.g. `str | None` instead of `Optional[str]`). * `classmethod` should (almost) always return `Self`. In case of mypy warning (e.g. if there is a branch in which function doesn't return the instance of `cls`) consider using `staticmethod` instead. +* Class attributes must be decorated as `ClassVar[...]`. * Recommended order of function definitions in class: ```python diff --git a/src/ahriman/application/handlers/handler.py b/src/ahriman/application/handlers/handler.py index 035a192f..7f63b493 100644 --- a/src/ahriman/application/handlers/handler.py +++ b/src/ahriman/application/handlers/handler.py @@ -22,7 +22,7 @@ import logging from collections.abc import Callable, Iterable from multiprocessing import Pool -from typing import TypeVar +from typing import ClassVar, TypeVar from ahriman.application.lock import Lock from ahriman.core.configuration import Configuration @@ -58,8 +58,8 @@ class Handler: >>> Add.execute(args) """ - ALLOW_MULTI_ARCHITECTURE_RUN = True - arguments: list[Callable[[SubParserAction], argparse.ArgumentParser]] + ALLOW_MULTI_ARCHITECTURE_RUN: ClassVar[bool] = True + arguments: ClassVar[list[Callable[[SubParserAction], argparse.ArgumentParser]]] @classmethod def call(cls, args: argparse.Namespace, repository_id: RepositoryId) -> bool: diff --git a/src/ahriman/application/handlers/search.py b/src/ahriman/application/handlers/search.py index 55dd7eeb..c981791a 100644 --- a/src/ahriman/application/handlers/search.py +++ b/src/ahriman/application/handlers/search.py @@ -21,6 +21,7 @@ import argparse from collections.abc import Callable, Iterable from dataclasses import fields +from typing import ClassVar from ahriman.application.handlers.handler import Handler, SubParserAction from ahriman.core.alpm.remote import AUR, Official @@ -40,7 +41,7 @@ class Search(Handler): """ ALLOW_MULTI_ARCHITECTURE_RUN = False # system-wide action - SORT_FIELDS = { + SORT_FIELDS: ClassVar[set[str]] = { field.name for field in fields(AURPackage) if field.default_factory is not list diff --git a/src/ahriman/application/handlers/setup.py b/src/ahriman/application/handlers/setup.py index 65f5bc23..a00114fd 100644 --- a/src/ahriman/application/handlers/setup.py +++ b/src/ahriman/application/handlers/setup.py @@ -21,6 +21,7 @@ import argparse from pathlib import Path from pwd import getpwuid +from typing import ClassVar from urllib.parse import quote_plus as url_encode from ahriman.application.application import Application @@ -46,9 +47,9 @@ class Setup(Handler): ALLOW_MULTI_ARCHITECTURE_RUN = False # conflicting io - ARCHBUILD_COMMAND_PATH = Path("/") / "usr" / "bin" / "archbuild" - MIRRORLIST_PATH = Path("/") / "etc" / "pacman.d" / "mirrorlist" - SUDOERS_DIR_PATH = Path("/") / "etc" / "sudoers.d" + ARCHBUILD_COMMAND_PATH: ClassVar[Path] = Path("/") / "usr" / "bin" / "archbuild" + MIRRORLIST_PATH: ClassVar[Path] = Path("/") / "etc" / "pacman.d" / "mirrorlist" + SUDOERS_DIR_PATH: ClassVar[Path] = Path("/") / "etc" / "sudoers.d" @classmethod def run(cls, args: argparse.Namespace, repository_id: RepositoryId, configuration: Configuration, *, diff --git a/src/ahriman/application/handlers/versions.py b/src/ahriman/application/handlers/versions.py index bf2526b6..00cb6960 100644 --- a/src/ahriman/application/handlers/versions.py +++ b/src/ahriman/application/handlers/versions.py @@ -23,6 +23,7 @@ import sys from collections.abc import Generator from importlib import metadata +from typing import ClassVar from ahriman import __version__ from ahriman.application.handlers.handler import Handler, SubParserAction @@ -36,11 +37,11 @@ class Versions(Handler): version handler Attributes: - PEP423_PACKAGE_NAME(str): (class attribute) special regex for valid PEP423 package name + PEP423_PACKAGE_NAME(re.Pattern[str]): (class attribute) special regex for valid PEP423 package name """ ALLOW_MULTI_ARCHITECTURE_RUN = False # system-wide action - PEP423_PACKAGE_NAME = re.compile(r"^[A-Za-z0-9._-]+") + PEP423_PACKAGE_NAME: ClassVar[re.Pattern[str]] = re.compile(r"^[A-Za-z0-9._-]+") @classmethod def run(cls, args: argparse.Namespace, repository_id: RepositoryId, configuration: Configuration, *, diff --git a/src/ahriman/core/alpm/pacman_database.py b/src/ahriman/core/alpm/pacman_database.py index 62d9a793..3f2d575c 100644 --- a/src/ahriman/core/alpm/pacman_database.py +++ b/src/ahriman/core/alpm/pacman_database.py @@ -23,6 +23,7 @@ import shutil from email.utils import parsedate_to_datetime from pathlib import Path from pyalpm import DB # type: ignore[import-not-found] +from typing import ClassVar from urllib.parse import urlparse from ahriman.core.configuration import Configuration @@ -41,7 +42,7 @@ class PacmanDatabase(SyncHttpClient): sync_files_database(bool): sync files database """ - LAST_MODIFIED_HEADER = "Last-Modified" + LAST_MODIFIED_HEADER: ClassVar[str] = "Last-Modified" def __init__(self, database: DB, configuration: Configuration) -> None: """ diff --git a/src/ahriman/core/alpm/pkgbuild_parser.py b/src/ahriman/core/alpm/pkgbuild_parser.py index e3eb9f80..5fbf325d 100644 --- a/src/ahriman/core/alpm/pkgbuild_parser.py +++ b/src/ahriman/core/alpm/pkgbuild_parser.py @@ -34,14 +34,14 @@ class PkgbuildToken(StrEnum): well-known tokens dictionary Attributes: - ArrayEnds(PkgbuildToken): (class attribute) array ends token - ArrayStarts(PkgbuildToken): (class attribute) array starts token - Comma(PkgbuildToken): (class attribute) comma token - Comment(PkgbuildToken): (class attribute) comment token - FunctionDeclaration(PkgbuildToken): (class attribute) function declaration token - FunctionEnds(PkgbuildToken): (class attribute) function ends token - FunctionStarts(PkgbuildToken): (class attribute) function starts token - NewLine(PkgbuildToken): (class attribute) new line token + ArrayEnds(PkgbuildToken): array ends token + ArrayStarts(PkgbuildToken): array starts token + Comma(PkgbuildToken): comma token + Comment(PkgbuildToken): comment token + FunctionDeclaration(PkgbuildToken): function declaration token + FunctionEnds(PkgbuildToken): function ends token + FunctionStarts(PkgbuildToken): function starts token + NewLine(PkgbuildToken): new line token """ ArrayStarts = "(" diff --git a/src/ahriman/core/alpm/remote/aur.py b/src/ahriman/core/alpm/remote/aur.py index 9b7ff28a..d7df1a91 100644 --- a/src/ahriman/core/alpm/remote/aur.py +++ b/src/ahriman/core/alpm/remote/aur.py @@ -17,7 +17,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # -from typing import Any +from typing import Any, ClassVar from ahriman.core.alpm.pacman import Pacman from ahriman.core.alpm.remote.remote import Remote @@ -35,9 +35,9 @@ class AUR(Remote): DEFAULT_RPC_VERSION(str): (class attribute) default AUR RPC version """ - DEFAULT_AUR_URL = "https://aur.archlinux.org" - DEFAULT_RPC_URL = f"{DEFAULT_AUR_URL}/rpc" - DEFAULT_RPC_VERSION = "5" + DEFAULT_AUR_URL: ClassVar[str] = "https://aur.archlinux.org" + DEFAULT_RPC_URL: ClassVar[str] = f"{DEFAULT_AUR_URL}/rpc" + DEFAULT_RPC_VERSION: ClassVar[str] = "5" @classmethod def remote_git_url(cls, package_base: str, repository: str) -> str: diff --git a/src/ahriman/core/alpm/remote/official.py b/src/ahriman/core/alpm/remote/official.py index a41bba12..e931b1f9 100644 --- a/src/ahriman/core/alpm/remote/official.py +++ b/src/ahriman/core/alpm/remote/official.py @@ -17,7 +17,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # -from typing import Any +from typing import Any, ClassVar from ahriman.core.alpm.pacman import Pacman from ahriman.core.alpm.remote.remote import Remote @@ -36,10 +36,10 @@ class Official(Remote): DEFAULT_RPC_URL(str): (class attribute) default archlinux repositories RPC url """ - DEFAULT_ARCHLINUX_GIT_URL = "https://gitlab.archlinux.org" - DEFAULT_ARCHLINUX_URL = "https://archlinux.org" - DEFAULT_SEARCH_REPOSITORIES = ["Core", "Extra", "Multilib"] - DEFAULT_RPC_URL = "https://archlinux.org/packages/search/json" + DEFAULT_ARCHLINUX_GIT_URL: ClassVar[str] = "https://gitlab.archlinux.org" + DEFAULT_ARCHLINUX_URL: ClassVar[str] = "https://archlinux.org" + DEFAULT_SEARCH_REPOSITORIES: ClassVar[list[str]] = ["Core", "Extra", "Multilib"] + DEFAULT_RPC_URL: ClassVar[str] = "https://archlinux.org/packages/search/json" @classmethod def remote_git_url(cls, package_base: str, repository: str) -> str: diff --git a/src/ahriman/core/build_tools/sources.py b/src/ahriman/core/build_tools/sources.py index 2d35e32c..9943a533 100644 --- a/src/ahriman/core/build_tools/sources.py +++ b/src/ahriman/core/build_tools/sources.py @@ -21,6 +21,7 @@ import shutil from collections.abc import Generator from pathlib import Path +from typing import ClassVar from ahriman.core.exceptions import CalledProcessError from ahriman.core.log import LazyLogging @@ -42,9 +43,9 @@ class Sources(LazyLogging): GITCONFIG(dict[str, str]): (class attribute) git config options to suppress annoying hints """ - DEFAULT_BRANCH = "master" # default fallback branch - DEFAULT_COMMIT_AUTHOR = ("ahriman", "ahriman@localhost") - GITCONFIG = { + DEFAULT_BRANCH: ClassVar[str] = "master" # default fallback branch + DEFAULT_COMMIT_AUTHOR: ClassVar[tuple[str, str]] = ("ahriman", "ahriman@localhost") + GITCONFIG: ClassVar[dict[str, str]] = { "init.defaultBranch": DEFAULT_BRANCH, } diff --git a/src/ahriman/core/configuration/configuration.py b/src/ahriman/core/configuration/configuration.py index c0c03cec..257461f6 100644 --- a/src/ahriman/core/configuration/configuration.py +++ b/src/ahriman/core/configuration/configuration.py @@ -22,7 +22,7 @@ import shlex import sys from pathlib import Path -from typing import Any, Self +from typing import Any, ClassVar, Self from ahriman.core.configuration.configuration_multi_dict import ConfigurationMultiDict from ahriman.core.configuration.shell_interpolator import ShellInterpolator @@ -65,8 +65,8 @@ class Configuration(configparser.RawConfigParser): """ _LEGACY_ARCHITECTURE_SPECIFIC_SECTIONS = ["web"] - ARCHITECTURE_SPECIFIC_SECTIONS = ["alpm", "build", "sign"] - SYSTEM_CONFIGURATION_PATH = Path(sys.prefix) / "share" / "ahriman" / "settings" / "ahriman.ini" + ARCHITECTURE_SPECIFIC_SECTIONS: ClassVar[list[str]] = ["alpm", "build", "sign"] + SYSTEM_CONFIGURATION_PATH: ClassVar[Path] = Path(sys.prefix) / "share" / "ahriman" / "settings" / "ahriman.ini" def __init__(self, allow_no_value: bool = False, allow_multi_key: bool = True) -> None: """ diff --git a/src/ahriman/core/configuration/shell_interpolator.py b/src/ahriman/core/configuration/shell_interpolator.py index 0a13f371..d09c166e 100644 --- a/src/ahriman/core/configuration/shell_interpolator.py +++ b/src/ahriman/core/configuration/shell_interpolator.py @@ -23,6 +23,7 @@ import sys from collections.abc import Generator, Mapping, MutableMapping from string import Template +from typing import ClassVar from ahriman.core.configuration.shell_template import ShellTemplate @@ -32,7 +33,7 @@ class ShellInterpolator(configparser.Interpolation): custom string interpolator, because we cannot use defaults argument due to config validation """ - DATA_LINK_ESCAPE = "\x10" + DATA_LINK_ESCAPE: ClassVar[str] = "\x10" @staticmethod def _extract_variables(parser: MutableMapping[str, Mapping[str, str]], value: str, diff --git a/src/ahriman/core/configuration/shell_template.py b/src/ahriman/core/configuration/shell_template.py index d1cbffbc..91f62c9d 100644 --- a/src/ahriman/core/configuration/shell_template.py +++ b/src/ahriman/core/configuration/shell_template.py @@ -28,9 +28,6 @@ class ShellTemplate(Template): """ extension to the default :class:`Template` class, which also adds additional tokens to braced regex and enables bash expansion - - Attributes: - braceidpattern(str): regular expression to match every character except for closing bracket """ braceidpattern = r"(?a:[_a-z0-9][^}]*)" diff --git a/src/ahriman/core/distributed/distributed_system.py b/src/ahriman/core/distributed/distributed_system.py index 24920f6e..c4361bfc 100644 --- a/src/ahriman/core/distributed/distributed_system.py +++ b/src/ahriman/core/distributed/distributed_system.py @@ -22,7 +22,6 @@ import contextlib from functools import cached_property from ahriman.core.configuration import Configuration -from ahriman.core.configuration.schema import ConfigurationSchema from ahriman.core.status.web_client import WebClient from ahriman.core.triggers import Trigger from ahriman.models.repository_id import RepositoryId @@ -34,7 +33,7 @@ class DistributedSystem(Trigger, WebClient): simple class to (un)register itself as a distributed worker """ - CONFIGURATION_SCHEMA: ConfigurationSchema = { + CONFIGURATION_SCHEMA = { "worker": { "type": "dict", "schema": { diff --git a/src/ahriman/core/formatters/configuration_printer.py b/src/ahriman/core/formatters/configuration_printer.py index 0687aa2c..670d628b 100644 --- a/src/ahriman/core/formatters/configuration_printer.py +++ b/src/ahriman/core/formatters/configuration_printer.py @@ -17,6 +17,8 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # +from typing import ClassVar + from ahriman.core.formatters.string_printer import StringPrinter from ahriman.models.property import Property @@ -31,7 +33,7 @@ class ConfigurationPrinter(StringPrinter): values(dict[str, str]): configuration values dictionary """ - HIDE_KEYS = [ + HIDE_KEYS: ClassVar[list[str]] = [ "api_key", # telegram key "client_secret", # oauth secret "cookie_secret_key", # cookie secret key diff --git a/src/ahriman/core/formatters/package_stats_printer.py b/src/ahriman/core/formatters/package_stats_printer.py index c3527a26..3f979aa4 100644 --- a/src/ahriman/core/formatters/package_stats_printer.py +++ b/src/ahriman/core/formatters/package_stats_printer.py @@ -17,6 +17,8 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # +from typing import ClassVar + from ahriman.core.formatters.string_printer import StringPrinter from ahriman.models.property import Property @@ -26,10 +28,11 @@ class PackageStatsPrinter(StringPrinter): print packages statistics Attributes: + MAX_COUNT(int): (class attribute) maximum number of packages to print events(dict[str, int]): map of package to its event frequency """ - MAX_COUNT = 10 + MAX_COUNT: ClassVar[int] = 10 def __init__(self, events: dict[str, int]) -> None: """ diff --git a/src/ahriman/core/log/log_loader.py b/src/ahriman/core/log/log_loader.py index 2ac4a4f5..f137c679 100644 --- a/src/ahriman/core/log/log_loader.py +++ b/src/ahriman/core/log/log_loader.py @@ -21,6 +21,7 @@ import logging from logging.config import fileConfig from pathlib import Path +from typing import ClassVar from ahriman.core.configuration import Configuration from ahriman.core.log.http_log_handler import HttpLogHandler @@ -38,9 +39,9 @@ class LogLoader: DEFAULT_SYSLOG_DEVICE(Path): (class attribute) default path to syslog device """ - DEFAULT_LOG_FORMAT = "[%(levelname)s %(asctime)s] [%(filename)s:%(lineno)d %(funcName)s]: %(message)s" - DEFAULT_LOG_LEVEL = logging.DEBUG - DEFAULT_SYSLOG_DEVICE = Path("/") / "dev" / "log" + DEFAULT_LOG_FORMAT: ClassVar[str] = "[%(levelname)s %(asctime)s] [%(name)s]: %(message)s" + DEFAULT_LOG_LEVEL: ClassVar[int] = logging.DEBUG + DEFAULT_SYSLOG_DEVICE: ClassVar[Path] = Path("/") / "dev" / "log" @staticmethod def handler(selected: LogHandler | None) -> LogHandler: diff --git a/src/ahriman/core/report/telegram.py b/src/ahriman/core/report/telegram.py index 044b0ffc..c4828196 100644 --- a/src/ahriman/core/report/telegram.py +++ b/src/ahriman/core/report/telegram.py @@ -17,6 +17,8 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # +from typing import ClassVar + from ahriman.core.configuration import Configuration from ahriman.core.http import SyncHttpClient from ahriman.core.report.jinja_template import JinjaTemplate @@ -39,8 +41,8 @@ class Telegram(Report, JinjaTemplate, SyncHttpClient): template_type(str): template message type to be used in parse mode, one of MarkdownV2, HTML, Markdown """ - TELEGRAM_API_URL = "https://api.telegram.org" - TELEGRAM_MAX_CONTENT_LENGTH = 4096 + TELEGRAM_API_URL: ClassVar[str] = "https://api.telegram.org" + TELEGRAM_MAX_CONTENT_LENGTH: ClassVar[int] = 4096 def __init__(self, repository_id: RepositoryId, configuration: Configuration, section: str) -> None: """ diff --git a/src/ahriman/core/support/pkgbuild/pkgbuild_generator.py b/src/ahriman/core/support/pkgbuild/pkgbuild_generator.py index b6b75c20..92bfb877 100644 --- a/src/ahriman/core/support/pkgbuild/pkgbuild_generator.py +++ b/src/ahriman/core/support/pkgbuild/pkgbuild_generator.py @@ -22,6 +22,7 @@ import itertools from collections.abc import Callable, Generator from pathlib import Path +from typing import ClassVar from ahriman.core.utils import utcnow from ahriman.models.pkgbuild_patch import PkgbuildPatch @@ -35,7 +36,7 @@ class PkgbuildGenerator: PKGBUILD_STATIC_PROPERTIES(list[PkgbuildPatch]): (class attribute) list of default pkgbuild static properties """ - PKGBUILD_STATIC_PROPERTIES = [ + PKGBUILD_STATIC_PROPERTIES: ClassVar[list[PkgbuildPatch]] = [ PkgbuildPatch("pkgrel", "1"), PkgbuildPatch("arch", ["any"]), ] diff --git a/src/ahriman/core/triggers/trigger.py b/src/ahriman/core/triggers/trigger.py index ce8cb822..8ae0ae13 100644 --- a/src/ahriman/core/triggers/trigger.py +++ b/src/ahriman/core/triggers/trigger.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # from collections.abc import Callable +from typing import ClassVar from ahriman.core.configuration import Configuration from ahriman.core.configuration.schema import ConfigurationSchema @@ -56,8 +57,8 @@ class Trigger(LazyLogging): >>> loader.on_result(Result(), []) """ - CONFIGURATION_SCHEMA: ConfigurationSchema = {} - CONFIGURATION_SCHEMA_FALLBACK: str | None = None + CONFIGURATION_SCHEMA: ClassVar[ConfigurationSchema] = {} + CONFIGURATION_SCHEMA_FALLBACK: ClassVar[str | None] = None def __init__(self, repository_id: RepositoryId, configuration: Configuration) -> None: """ diff --git a/src/ahriman/models/action.py b/src/ahriman/models/action.py index cc346285..42c10ad9 100644 --- a/src/ahriman/models/action.py +++ b/src/ahriman/models/action.py @@ -25,9 +25,9 @@ class Action(StrEnum): base action enumeration Attributes: - List(Action): (class attribute) list available values - Remove(Action): (class attribute) remove everything from local storage - Update(Action): (class attribute) update local storage or add to + List(Action): list available values + Remove(Action): remove everything from local storage + Update(Action): update local storage or add to """ List = "list" diff --git a/src/ahriman/models/auth_settings.py b/src/ahriman/models/auth_settings.py index 02863b39..42c67a5a 100644 --- a/src/ahriman/models/auth_settings.py +++ b/src/ahriman/models/auth_settings.py @@ -27,10 +27,10 @@ class AuthSettings(StrEnum): web authorization type Attributes: - Disabled(AuthSettings): (class attribute) authorization is disabled - Configuration(AuthSettings): (class attribute) configuration based authorization - OAuth(AuthSettings): (class attribute) OAuth based provider - PAM(AuthSettings): (class attribute) PAM based provider + Disabled(AuthSettings): authorization is disabled + Configuration(AuthSettings): configuration based authorization + OAuth(AuthSettings): OAuth based provider + PAM(AuthSettings): PAM based provider """ Disabled = "disabled" diff --git a/src/ahriman/models/build_status.py b/src/ahriman/models/build_status.py index 7d0458a6..df0aae51 100644 --- a/src/ahriman/models/build_status.py +++ b/src/ahriman/models/build_status.py @@ -29,11 +29,11 @@ class BuildStatusEnum(StrEnum): build status enumeration Attributes: - Unknown(BuildStatusEnum): (class attribute) build status is unknown - Pending(BuildStatusEnum): (class attribute) package is out-of-dated and will be built soon - Building(BuildStatusEnum): (class attribute) package is building right now - Failed(BuildStatusEnum): (class attribute) package build failed - Success(BuildStatusEnum): (class attribute) package has been built without errors + Unknown(BuildStatusEnum): build status is unknown + Pending(BuildStatusEnum): package is out-of-dated and will be built soon + Building(BuildStatusEnum): package is building right now + Failed(BuildStatusEnum): package build failed + Success(BuildStatusEnum): package has been built without errors """ Unknown = "unknown" diff --git a/src/ahriman/models/event.py b/src/ahriman/models/event.py index 2f1281e7..061be39a 100644 --- a/src/ahriman/models/event.py +++ b/src/ahriman/models/event.py @@ -28,10 +28,10 @@ class EventType(StrEnum): predefined event types Attributes: - PackageOutdated(EventType): (class attribute) package has been marked as out-of-date - PackageRemoved(EventType): (class attribute) package has been removed - PackageUpdateFailed(EventType): (class attribute) package update has been failed - PackageUpdated(EventType): (class attribute) package has been updated + PackageOutdated(EventType): package has been marked as out-of-date + PackageRemoved(EventType): package has been removed + PackageUpdateFailed(EventType): package update has been failed + PackageUpdated(EventType): package has been updated """ PackageOutdated = "package-outdated" diff --git a/src/ahriman/models/log_handler.py b/src/ahriman/models/log_handler.py index bb1e42b8..b5936d46 100644 --- a/src/ahriman/models/log_handler.py +++ b/src/ahriman/models/log_handler.py @@ -25,9 +25,9 @@ class LogHandler(StrEnum): log handler as described by default configuration Attributes: - Console(LogHandler): (class attribute) write logs to console - Syslog(LogHandler): (class attribute) write logs to syslog device /dev/null - Journald(LogHandler): (class attribute) write logs to journald directly + Console(LogHandler): write logs to console + Syslog(LogHandler): write logs to syslog device /dev/null + Journald(LogHandler): write logs to journald directly """ Console = "console" diff --git a/src/ahriman/models/package_source.py b/src/ahriman/models/package_source.py index a7a4998e..e598ba62 100644 --- a/src/ahriman/models/package_source.py +++ b/src/ahriman/models/package_source.py @@ -32,13 +32,13 @@ class PackageSource(StrEnum): package source for addition enumeration Attributes: - Auto(PackageSource): (class attribute) automatically determine type of the source - Archive(PackageSource): (class attribute) source is a package archive - AUR(PackageSource): (class attribute) source is an AUR package for which it should search - Directory(PackageSource): (class attribute) source is a directory which contains packages - Local(PackageSource): (class attribute) source is locally stored PKGBUILD - Remote(PackageSource): (class attribute) source is remote (http, ftp etc...) link - Repository(PackageSource): (class attribute) source is official repository + Auto(PackageSource): automatically determine type of the source + Archive(PackageSource): source is a package archive + AUR(PackageSource): source is an AUR package for which it should search + Directory(PackageSource): source is a directory which contains packages + Local(PackageSource): source is locally stored PKGBUILD + Remote(PackageSource): source is remote (http, ftp etc...) link + Repository(PackageSource): source is official repository Examples: In case if source is unknown the :func:`resolve()` and the source diff --git a/src/ahriman/models/pacman_synchronization.py b/src/ahriman/models/pacman_synchronization.py index 8aebc928..089accd9 100644 --- a/src/ahriman/models/pacman_synchronization.py +++ b/src/ahriman/models/pacman_synchronization.py @@ -25,9 +25,9 @@ class PacmanSynchronization(IntEnum): pacman database synchronization flag Attributes: - Disabled(PacmanSynchronization): (class attribute) do not synchronize local database - Enabled(PacmanSynchronization): (class attribute) synchronize local database (same as pacman -Sy) - Force(PacmanSynchronization): (class attribute) force synchronize local database (same as pacman -Syy) + Disabled(PacmanSynchronization): do not synchronize local database + Enabled(PacmanSynchronization): synchronize local database (same as pacman -Sy) + Force(PacmanSynchronization): force synchronize local database (same as pacman -Syy) """ Disabled = 0 diff --git a/src/ahriman/models/pkgbuild.py b/src/ahriman/models/pkgbuild.py index 242accd4..37e7ca84 100644 --- a/src/ahriman/models/pkgbuild.py +++ b/src/ahriman/models/pkgbuild.py @@ -21,7 +21,7 @@ from collections.abc import Iterator, Mapping from dataclasses import dataclass from io import StringIO from pathlib import Path -from typing import Any, IO, Self +from typing import Any, ClassVar, IO, Self from ahriman.core.alpm.pkgbuild_parser import PkgbuildParser, PkgbuildToken from ahriman.core.exceptions import EncodeError @@ -40,7 +40,7 @@ class Pkgbuild(Mapping[str, Any]): fields: dict[str, PkgbuildPatch] - DEFAULT_ENCODINGS = ["utf8", "latin-1"] + DEFAULT_ENCODINGS: ClassVar[list[str]] = ["utf8", "latin-1"] @property def variables(self) -> dict[str, str]: diff --git a/src/ahriman/models/report_settings.py b/src/ahriman/models/report_settings.py index 6ea3c043..f94ec936 100644 --- a/src/ahriman/models/report_settings.py +++ b/src/ahriman/models/report_settings.py @@ -27,13 +27,13 @@ class ReportSettings(StrEnum): report targets enumeration Attributes: - Disabled(ReportSettings): (class attribute) option which generates no report for testing purpose - HTML(ReportSettings): (class attribute) html report generation - Email(ReportSettings): (class attribute) email report generation - Console(ReportSettings): (class attribute) print result to console - Telegram(ReportSettings): (class attribute) markdown report to telegram channel - RSS(ReportSettings): (class attribute) RSS report generation - RemoteCall(ReportSettings): (class attribute) remote ahriman server call + Disabled(ReportSettings): option which generates no report for testing purpose + HTML(ReportSettings): html report generation + Email(ReportSettings): email report generation + Console(ReportSettings): print result to console + Telegram(ReportSettings): markdown report to telegram channel + RSS(ReportSettings): RSS report generation + RemoteCall(ReportSettings): remote ahriman server call """ Disabled = "disabled" # for testing purpose diff --git a/src/ahriman/models/result.py b/src/ahriman/models/result.py index eb489d74..645d97ce 100644 --- a/src/ahriman/models/result.py +++ b/src/ahriman/models/result.py @@ -20,7 +20,7 @@ from __future__ import annotations from collections.abc import Callable, Iterable -from typing import Any, Self +from typing import Any, ClassVar, Self from ahriman.models.package import Package @@ -33,7 +33,7 @@ class Result: STATUS_PRIORITIES(list[str]): (class attribute) list of statues according to their priorities """ - STATUS_PRIORITIES = [ + STATUS_PRIORITIES: ClassVar[list[str]] = [ "failed", "removed", "updated", diff --git a/src/ahriman/models/sign_settings.py b/src/ahriman/models/sign_settings.py index c96b1442..bb74482b 100644 --- a/src/ahriman/models/sign_settings.py +++ b/src/ahriman/models/sign_settings.py @@ -27,9 +27,9 @@ class SignSettings(StrEnum): sign targets enumeration Attributes: - Disabled(SignSettings): (class attribute) option which generates no report for testing purpose - Packages(SignSettings): (class attribute) sign each package - Repository(SignSettings): (class attribute) sign repository database file + Disabled(SignSettings): option which generates no report for testing purpose + Packages(SignSettings): sign each package + Repository(SignSettings): sign repository database file """ Disabled = "disabled" diff --git a/src/ahriman/models/smtp_ssl_settings.py b/src/ahriman/models/smtp_ssl_settings.py index 77bcde7f..ac0402bc 100644 --- a/src/ahriman/models/smtp_ssl_settings.py +++ b/src/ahriman/models/smtp_ssl_settings.py @@ -27,9 +27,9 @@ class SmtpSSLSettings(StrEnum): SMTP SSL mode enumeration Attributes: - Disabled(SmtpSSLSettings): (class attribute) no SSL enabled - SSL(SmtpSSLSettings): (class attribute) use SMTP_SSL instead of normal SMTP client - STARTTLS(SmtpSSLSettings): (class attribute) use STARTTLS in normal SMTP client + Disabled(SmtpSSLSettings): no SSL enabled + SSL(SmtpSSLSettings): use SMTP_SSL instead of normal SMTP client + STARTTLS(SmtpSSLSettings): use STARTTLS in normal SMTP client """ Disabled = "disabled" diff --git a/src/ahriman/models/upload_settings.py b/src/ahriman/models/upload_settings.py index 1896c5ca..5445df69 100644 --- a/src/ahriman/models/upload_settings.py +++ b/src/ahriman/models/upload_settings.py @@ -27,11 +27,11 @@ class UploadSettings(StrEnum): remote synchronization targets enumeration Attributes: - Disabled(UploadSettings): (class attribute) no sync will be performed, required for testing purpose - Rsync(UploadSettings): (class attribute) sync via rsync - S3(UploadSettings): (class attribute) sync to Amazon S3 - GitHub(UploadSettings): (class attribute) sync to GitHub releases page - RemoteService(UploadSettings): (class attribute) sync to another ahriman instance + Disabled(UploadSettings): no sync will be performed, required for testing purpose + Rsync(UploadSettings): sync via rsync + S3(UploadSettings): sync to Amazon S3 + GitHub(UploadSettings): sync to GitHub releases page + RemoteService(UploadSettings): sync to another ahriman instance """ Disabled = "disabled" # for testing purpose diff --git a/src/ahriman/models/user.py b/src/ahriman/models/user.py index 6dbb43ef..c7def3aa 100644 --- a/src/ahriman/models/user.py +++ b/src/ahriman/models/user.py @@ -21,7 +21,7 @@ import bcrypt from dataclasses import dataclass, replace from secrets import token_urlsafe as generate_password -from typing import Self +from typing import ClassVar, Self from ahriman.models.user_access import UserAccess @@ -69,7 +69,7 @@ class User: packager_id: str | None = None key: str | None = None - SUPPORTED_ALGOS = {"$2$", "$2a$", "$2x$", "$2y$", "$2b$"} + SUPPORTED_ALGOS: ClassVar[set[str]] = {"$2$", "$2a$", "$2x$", "$2y$", "$2b$"} def __post_init__(self) -> None: """ diff --git a/src/ahriman/models/user_access.py b/src/ahriman/models/user_access.py index e4488c6d..01b58198 100644 --- a/src/ahriman/models/user_access.py +++ b/src/ahriman/models/user_access.py @@ -27,11 +27,11 @@ class UserAccess(StrEnum): web user access enumeration Attributes: - Unauthorized(UserAccess): (class attribute) user can access specific resources which are marked as available + Unauthorized(UserAccess): user can access specific resources which are marked as available without authorization (e.g. login, logout, static) - Read(UserAccess): (class attribute) user can read the page - Reporter(UserAccess): (class attribute) user can read everything and is able to perform some modifications - Full(UserAccess): (class attribute) user has full access + Read(UserAccess): user can read the page + Reporter(UserAccess): user can read everything and is able to perform some modifications + Full(UserAccess): user has full access """ Unauthorized = "unauthorized" diff --git a/src/ahriman/web/views/api/docs.py b/src/ahriman/web/views/api/docs.py index 856db24d..053a6408 100644 --- a/src/ahriman/web/views/api/docs.py +++ b/src/ahriman/web/views/api/docs.py @@ -19,7 +19,7 @@ # import aiohttp_jinja2 -from typing import Any +from typing import Any, ClassVar from ahriman.core.configuration import Configuration from ahriman.models.user_access import UserAccess @@ -35,7 +35,7 @@ class DocsView(BaseView): GET_PERMISSION(UserAccess): (class attribute) get permissions of self """ - GET_PERMISSION = UserAccess.Unauthorized + GET_PERMISSION: ClassVar[UserAccess] = UserAccess.Unauthorized ROUTES = ["/api-docs"] @classmethod diff --git a/src/ahriman/web/views/api/swagger.py b/src/ahriman/web/views/api/swagger.py index ead54c3b..60757b54 100644 --- a/src/ahriman/web/views/api/swagger.py +++ b/src/ahriman/web/views/api/swagger.py @@ -19,6 +19,7 @@ # from aiohttp.web import Response, json_response from collections.abc import Callable +from typing import ClassVar from ahriman.core.configuration import Configuration from ahriman.core.utils import partition @@ -35,7 +36,7 @@ class SwaggerView(BaseView): GET_PERMISSION(UserAccess): (class attribute) get permissions of self """ - GET_PERMISSION = UserAccess.Unauthorized + GET_PERMISSION: ClassVar[UserAccess] = UserAccess.Unauthorized ROUTES = ["/api-docs/swagger.json"] @classmethod diff --git a/src/ahriman/web/views/base.py b/src/ahriman/web/views/base.py index 887afc8d..32f0b33a 100644 --- a/src/ahriman/web/views/base.py +++ b/src/ahriman/web/views/base.py @@ -20,7 +20,7 @@ from aiohttp.web import HTTPBadRequest, HTTPNotFound, Request, StreamResponse, View from aiohttp_cors import CorsViewMixin # type: ignore[import-untyped] from collections.abc import Awaitable, Callable -from typing import TypeVar +from typing import ClassVar, TypeVar from ahriman.core.auth import Auth from ahriman.core.configuration import Configuration @@ -46,8 +46,8 @@ class BaseView(View, CorsViewMixin): ROUTES(list[str]): (class attribute) list of supported routes """ - OPTIONS_PERMISSION = UserAccess.Unauthorized - ROUTES: list[str] = [] + OPTIONS_PERMISSION: ClassVar[UserAccess] = UserAccess.Unauthorized + ROUTES: ClassVar[list[str]] = [] @property def configuration(self) -> Configuration: diff --git a/src/ahriman/web/views/index.py b/src/ahriman/web/views/index.py index 0621ac69..ab53db27 100644 --- a/src/ahriman/web/views/index.py +++ b/src/ahriman/web/views/index.py @@ -19,7 +19,7 @@ # import aiohttp_jinja2 -from typing import Any +from typing import Any, ClassVar from ahriman.core.auth.helpers import authorized_userid from ahriman.models.user_access import UserAccess @@ -48,7 +48,7 @@ class IndexView(BaseView): GET_PERMISSION(UserAccess): (class attribute) get permissions of self """ - GET_PERMISSION = UserAccess.Unauthorized + GET_PERMISSION: ClassVar[UserAccess] = UserAccess.Unauthorized ROUTES = ["/", "/index.html"] @aiohttp_jinja2.template("build-status.jinja2") diff --git a/src/ahriman/web/views/static.py b/src/ahriman/web/views/static.py index b4b6b0c3..8f61eb9f 100644 --- a/src/ahriman/web/views/static.py +++ b/src/ahriman/web/views/static.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # from aiohttp.web import HTTPFound, HTTPNotFound +from typing import ClassVar from ahriman.models.user_access import UserAccess from ahriman.web.views.base import BaseView @@ -31,7 +32,7 @@ class StaticView(BaseView): GET_PERMISSION(UserAccess): (class attribute) get permissions of self """ - GET_PERMISSION = UserAccess.Unauthorized + GET_PERMISSION: ClassVar[UserAccess] = UserAccess.Unauthorized ROUTES = ["/favicon.ico"] async def get(self) -> None: diff --git a/src/ahriman/web/views/status_view_guard.py b/src/ahriman/web/views/status_view_guard.py index eb82f127..3f35e48c 100644 --- a/src/ahriman/web/views/status_view_guard.py +++ b/src/ahriman/web/views/status_view_guard.py @@ -17,6 +17,8 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # +from typing import ClassVar + from ahriman.core.configuration import Configuration @@ -25,7 +27,7 @@ class StatusViewGuard: helper for check if status routes are enabled """ - ROUTES: list[str] + ROUTES: ClassVar[list[str]] @classmethod def routes(cls, configuration: Configuration) -> list[str]: diff --git a/src/ahriman/web/views/v1/auditlog/events.py b/src/ahriman/web/views/v1/auditlog/events.py index cc73be3f..4d3b267d 100644 --- a/src/ahriman/web/views/v1/auditlog/events.py +++ b/src/ahriman/web/views/v1/auditlog/events.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # from aiohttp.web import HTTPBadRequest, HTTPNoContent, Response, json_response +from typing import ClassVar from ahriman.models.event import Event from ahriman.models.user_access import UserAccess @@ -35,7 +36,7 @@ class EventsView(BaseView): POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ - GET_PERMISSION = POST_PERMISSION = UserAccess.Full + GET_PERMISSION = POST_PERMISSION = UserAccess.Full # type: ClassVar[UserAccess] ROUTES = ["/api/v1/events"] @apidocs( diff --git a/src/ahriman/web/views/v1/distributed/workers.py b/src/ahriman/web/views/v1/distributed/workers.py index 2754d287..f2b54f82 100644 --- a/src/ahriman/web/views/v1/distributed/workers.py +++ b/src/ahriman/web/views/v1/distributed/workers.py @@ -19,6 +19,7 @@ # from aiohttp.web import HTTPBadRequest, HTTPNoContent, Response, json_response from collections.abc import Callable +from typing import ClassVar from ahriman.models.user_access import UserAccess from ahriman.models.worker import Worker @@ -37,7 +38,7 @@ class WorkersView(BaseView): POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ - DELETE_PERMISSION = GET_PERMISSION = POST_PERMISSION = UserAccess.Full + DELETE_PERMISSION = GET_PERMISSION = POST_PERMISSION = UserAccess.Full # type: ClassVar[UserAccess] ROUTES = ["/api/v1/distributed"] @apidocs( diff --git a/src/ahriman/web/views/v1/packages/changes.py b/src/ahriman/web/views/v1/packages/changes.py index 84f228da..eec77675 100644 --- a/src/ahriman/web/views/v1/packages/changes.py +++ b/src/ahriman/web/views/v1/packages/changes.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # from aiohttp.web import HTTPBadRequest, HTTPNoContent, Response, json_response +from typing import ClassVar from ahriman.models.changes import Changes from ahriman.models.user_access import UserAccess @@ -36,8 +37,8 @@ class ChangesView(StatusViewGuard, BaseView): POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ - GET_PERMISSION = UserAccess.Reporter - POST_PERMISSION = UserAccess.Full + GET_PERMISSION: ClassVar[UserAccess] = UserAccess.Reporter + POST_PERMISSION: ClassVar[UserAccess] = UserAccess.Full ROUTES = ["/api/v1/packages/{package}/changes"] @apidocs( diff --git a/src/ahriman/web/views/v1/packages/dependencies.py b/src/ahriman/web/views/v1/packages/dependencies.py index 917888c0..942e2205 100644 --- a/src/ahriman/web/views/v1/packages/dependencies.py +++ b/src/ahriman/web/views/v1/packages/dependencies.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # from aiohttp.web import HTTPBadRequest, HTTPNoContent, Response, json_response +from typing import ClassVar from ahriman.models.dependencies import Dependencies from ahriman.models.user_access import UserAccess @@ -36,8 +37,8 @@ class DependenciesView(StatusViewGuard, BaseView): POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ - GET_PERMISSION = UserAccess.Reporter - POST_PERMISSION = UserAccess.Full + GET_PERMISSION: ClassVar[UserAccess] = UserAccess.Reporter + POST_PERMISSION: ClassVar[UserAccess] = UserAccess.Full ROUTES = ["/api/v1/packages/{package}/dependencies"] @apidocs( diff --git a/src/ahriman/web/views/v1/packages/logs.py b/src/ahriman/web/views/v1/packages/logs.py index cb82ff53..e4ee92b5 100644 --- a/src/ahriman/web/views/v1/packages/logs.py +++ b/src/ahriman/web/views/v1/packages/logs.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # from aiohttp.web import HTTPBadRequest, HTTPNoContent, HTTPNotFound, Response, json_response +from typing import ClassVar from ahriman.core.exceptions import UnknownPackageError from ahriman.core.utils import pretty_datetime @@ -39,8 +40,8 @@ class LogsView(StatusViewGuard, BaseView): POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ - DELETE_PERMISSION = POST_PERMISSION = UserAccess.Full - GET_PERMISSION = UserAccess.Reporter + DELETE_PERMISSION = POST_PERMISSION = UserAccess.Full # type: ClassVar[UserAccess] + GET_PERMISSION: ClassVar[UserAccess] = UserAccess.Reporter ROUTES = ["/api/v1/packages/{package}/logs"] @apidocs( diff --git a/src/ahriman/web/views/v1/packages/package.py b/src/ahriman/web/views/v1/packages/package.py index 93982669..5f9c75f4 100644 --- a/src/ahriman/web/views/v1/packages/package.py +++ b/src/ahriman/web/views/v1/packages/package.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # from aiohttp.web import HTTPBadRequest, HTTPNoContent, HTTPNotFound, Response, json_response +from typing import ClassVar from ahriman.core.exceptions import UnknownPackageError from ahriman.models.build_status import BuildStatusEnum @@ -40,8 +41,8 @@ class PackageView(StatusViewGuard, BaseView): POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ - DELETE_PERMISSION = POST_PERMISSION = UserAccess.Full - GET_PERMISSION = UserAccess.Read + DELETE_PERMISSION = POST_PERMISSION = UserAccess.Full # type: ClassVar[UserAccess] + GET_PERMISSION: ClassVar[UserAccess] = UserAccess.Read ROUTES = ["/api/v1/packages/{package}"] @apidocs( diff --git a/src/ahriman/web/views/v1/packages/packages.py b/src/ahriman/web/views/v1/packages/packages.py index 264c88c7..779591fe 100644 --- a/src/ahriman/web/views/v1/packages/packages.py +++ b/src/ahriman/web/views/v1/packages/packages.py @@ -21,6 +21,7 @@ import itertools from aiohttp.web import HTTPNoContent, Response, json_response from collections.abc import Callable +from typing import ClassVar from ahriman.models.build_status import BuildStatus from ahriman.models.package import Package @@ -40,8 +41,8 @@ class PackagesView(StatusViewGuard, BaseView): POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ - GET_PERMISSION = UserAccess.Read - POST_PERMISSION = UserAccess.Full + GET_PERMISSION: ClassVar[UserAccess] = UserAccess.Read + POST_PERMISSION: ClassVar[UserAccess] = UserAccess.Full ROUTES = ["/api/v1/packages"] @apidocs( diff --git a/src/ahriman/web/views/v1/packages/patch.py b/src/ahriman/web/views/v1/packages/patch.py index 0e057024..c8089f0a 100644 --- a/src/ahriman/web/views/v1/packages/patch.py +++ b/src/ahriman/web/views/v1/packages/patch.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # from aiohttp.web import HTTPNoContent, HTTPNotFound, Response, json_response +from typing import ClassVar from ahriman.models.user_access import UserAccess from ahriman.web.apispec.decorators import apidocs @@ -35,8 +36,8 @@ class PatchView(StatusViewGuard, BaseView): GET_PERMISSION(UserAccess): (class attribute) get permissions of self """ - DELETE_PERMISSION = UserAccess.Full - GET_PERMISSION = UserAccess.Reporter + DELETE_PERMISSION: ClassVar[UserAccess] = UserAccess.Full + GET_PERMISSION: ClassVar[UserAccess] = UserAccess.Reporter ROUTES = ["/api/v1/packages/{package}/patches/{patch}"] @apidocs( diff --git a/src/ahriman/web/views/v1/packages/patches.py b/src/ahriman/web/views/v1/packages/patches.py index b8dfb6ff..e87d0691 100644 --- a/src/ahriman/web/views/v1/packages/patches.py +++ b/src/ahriman/web/views/v1/packages/patches.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # from aiohttp.web import HTTPBadRequest, HTTPNoContent, Response, json_response +from typing import ClassVar from ahriman.models.pkgbuild_patch import PkgbuildPatch from ahriman.models.user_access import UserAccess @@ -36,8 +37,8 @@ class PatchesView(StatusViewGuard, BaseView): POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ - GET_PERMISSION = UserAccess.Reporter - POST_PERMISSION = UserAccess.Full + GET_PERMISSION: ClassVar[UserAccess] = UserAccess.Reporter + POST_PERMISSION: ClassVar[UserAccess] = UserAccess.Full ROUTES = ["/api/v1/packages/{package}/patches"] @apidocs( diff --git a/src/ahriman/web/views/v1/service/add.py b/src/ahriman/web/views/v1/service/add.py index 2e81e3cb..4a2b34f0 100644 --- a/src/ahriman/web/views/v1/service/add.py +++ b/src/ahriman/web/views/v1/service/add.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # from aiohttp.web import HTTPBadRequest, Response, json_response +from typing import ClassVar from ahriman.models.pkgbuild_patch import PkgbuildPatch from ahriman.models.user_access import UserAccess @@ -34,7 +35,7 @@ class AddView(BaseView): POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ - POST_PERMISSION = UserAccess.Full + POST_PERMISSION: ClassVar[UserAccess] = UserAccess.Full ROUTES = ["/api/v1/service/add"] @apidocs( diff --git a/src/ahriman/web/views/v1/service/logs.py b/src/ahriman/web/views/v1/service/logs.py index 552912fb..f2a4998c 100644 --- a/src/ahriman/web/views/v1/service/logs.py +++ b/src/ahriman/web/views/v1/service/logs.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # from aiohttp.web import HTTPBadRequest, HTTPNoContent +from typing import ClassVar from ahriman.models.user_access import UserAccess from ahriman.web.apispec.decorators import apidocs @@ -33,7 +34,7 @@ class LogsView(BaseView): DELETE_PERMISSION(UserAccess): (class attribute) delete permissions of self """ - DELETE_PERMISSION = UserAccess.Full + DELETE_PERMISSION: ClassVar[UserAccess] = UserAccess.Full ROUTES = ["/api/v1/service/logs"] @apidocs( diff --git a/src/ahriman/web/views/v1/service/pgp.py b/src/ahriman/web/views/v1/service/pgp.py index 56165a42..791b347c 100644 --- a/src/ahriman/web/views/v1/service/pgp.py +++ b/src/ahriman/web/views/v1/service/pgp.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # from aiohttp.web import HTTPBadRequest, HTTPNotFound, Response, json_response +from typing import ClassVar from ahriman.models.user_access import UserAccess from ahriman.web.apispec.decorators import apidocs @@ -34,8 +35,8 @@ class PGPView(BaseView): POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ - GET_PERMISSION = UserAccess.Reporter - POST_PERMISSION = UserAccess.Full + GET_PERMISSION: ClassVar[UserAccess] = UserAccess.Reporter + POST_PERMISSION: ClassVar[UserAccess] = UserAccess.Full ROUTES = ["/api/v1/service/pgp"] @apidocs( diff --git a/src/ahriman/web/views/v1/service/process.py b/src/ahriman/web/views/v1/service/process.py index 602f17fb..6dfa0483 100644 --- a/src/ahriman/web/views/v1/service/process.py +++ b/src/ahriman/web/views/v1/service/process.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # from aiohttp.web import HTTPNotFound, Response, json_response +from typing import ClassVar from ahriman.models.user_access import UserAccess from ahriman.web.apispec.decorators import apidocs @@ -33,7 +34,7 @@ class ProcessView(BaseView): GET_PERMISSION(UserAccess): (class attribute) get permissions of self """ - GET_PERMISSION = UserAccess.Reporter + GET_PERMISSION: ClassVar[UserAccess] = UserAccess.Reporter ROUTES = ["/api/v1/service/process/{process_id}"] @apidocs( diff --git a/src/ahriman/web/views/v1/service/rebuild.py b/src/ahriman/web/views/v1/service/rebuild.py index e39b5821..2d5ef840 100644 --- a/src/ahriman/web/views/v1/service/rebuild.py +++ b/src/ahriman/web/views/v1/service/rebuild.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # from aiohttp.web import HTTPBadRequest, Response, json_response +from typing import ClassVar from ahriman.models.user_access import UserAccess from ahriman.web.apispec.decorators import apidocs @@ -33,7 +34,7 @@ class RebuildView(BaseView): POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ - POST_PERMISSION = UserAccess.Full + POST_PERMISSION: ClassVar[UserAccess] = UserAccess.Full ROUTES = ["/api/v1/service/rebuild"] @apidocs( diff --git a/src/ahriman/web/views/v1/service/remove.py b/src/ahriman/web/views/v1/service/remove.py index 818c9d01..5f39bd37 100644 --- a/src/ahriman/web/views/v1/service/remove.py +++ b/src/ahriman/web/views/v1/service/remove.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # from aiohttp.web import HTTPBadRequest, Response, json_response +from typing import ClassVar from ahriman.models.user_access import UserAccess from ahriman.web.apispec.decorators import apidocs @@ -33,7 +34,7 @@ class RemoveView(BaseView): POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ - POST_PERMISSION = UserAccess.Full + POST_PERMISSION: ClassVar[UserAccess] = UserAccess.Full ROUTES = ["/api/v1/service/remove"] @apidocs( diff --git a/src/ahriman/web/views/v1/service/request.py b/src/ahriman/web/views/v1/service/request.py index 5d6c9b4f..502fcf0e 100644 --- a/src/ahriman/web/views/v1/service/request.py +++ b/src/ahriman/web/views/v1/service/request.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # from aiohttp.web import HTTPBadRequest, Response, json_response +from typing import ClassVar from ahriman.models.pkgbuild_patch import PkgbuildPatch from ahriman.models.user_access import UserAccess @@ -34,7 +35,7 @@ class RequestView(BaseView): POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ - POST_PERMISSION = UserAccess.Reporter + POST_PERMISSION: ClassVar[UserAccess] = UserAccess.Reporter ROUTES = ["/api/v1/service/request"] @apidocs( diff --git a/src/ahriman/web/views/v1/service/search.py b/src/ahriman/web/views/v1/service/search.py index c2a45ded..6d1911cf 100644 --- a/src/ahriman/web/views/v1/service/search.py +++ b/src/ahriman/web/views/v1/service/search.py @@ -19,6 +19,7 @@ # from aiohttp.web import HTTPBadRequest, HTTPNotFound, Response, json_response from collections.abc import Callable +from typing import ClassVar from ahriman.core.alpm.remote import AUR from ahriman.models.aur_package import AURPackage @@ -36,7 +37,7 @@ class SearchView(BaseView): GET_PERMISSION(UserAccess): (class attribute) get permissions of self """ - GET_PERMISSION = UserAccess.Reporter + GET_PERMISSION: ClassVar[UserAccess] = UserAccess.Reporter ROUTES = ["/api/v1/service/search"] @apidocs( diff --git a/src/ahriman/web/views/v1/service/update.py b/src/ahriman/web/views/v1/service/update.py index eb39110e..6974a88e 100644 --- a/src/ahriman/web/views/v1/service/update.py +++ b/src/ahriman/web/views/v1/service/update.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # from aiohttp.web import HTTPBadRequest, Response, json_response +from typing import ClassVar from ahriman.models.user_access import UserAccess from ahriman.web.apispec.decorators import apidocs @@ -33,7 +34,7 @@ class UpdateView(BaseView): POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ - POST_PERMISSION = UserAccess.Full + POST_PERMISSION: ClassVar[UserAccess] = UserAccess.Full ROUTES = ["/api/v1/service/update"] @apidocs( diff --git a/src/ahriman/web/views/v1/service/upload.py b/src/ahriman/web/views/v1/service/upload.py index 4aec7e14..7d15b60b 100644 --- a/src/ahriman/web/views/v1/service/upload.py +++ b/src/ahriman/web/views/v1/service/upload.py @@ -23,6 +23,7 @@ from aiohttp import BodyPartReader from aiohttp.web import HTTPBadRequest, HTTPCreated from pathlib import Path from tempfile import NamedTemporaryFile +from typing import ClassVar from ahriman.core.configuration import Configuration from ahriman.models.repository_paths import RepositoryPaths @@ -40,7 +41,7 @@ class UploadView(BaseView): POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ - POST_PERMISSION = UserAccess.Full + POST_PERMISSION: ClassVar[UserAccess] = UserAccess.Full ROUTES = ["/api/v1/service/upload"] @classmethod diff --git a/src/ahriman/web/views/v1/status/info.py b/src/ahriman/web/views/v1/status/info.py index 01ffc230..3f154ed1 100644 --- a/src/ahriman/web/views/v1/status/info.py +++ b/src/ahriman/web/views/v1/status/info.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # from aiohttp.web import Response, json_response +from typing import ClassVar from ahriman import __version__ from ahriman.models.user_access import UserAccess @@ -34,7 +35,7 @@ class InfoView(BaseView): GET_PERMISSION(UserAccess): (class attribute) get permissions of self """ - GET_PERMISSION = UserAccess.Unauthorized + GET_PERMISSION: ClassVar[UserAccess] = UserAccess.Unauthorized ROUTES = ["/api/v1/info"] @apidocs( diff --git a/src/ahriman/web/views/v1/status/repositories.py b/src/ahriman/web/views/v1/status/repositories.py index f35f82da..58fa3362 100644 --- a/src/ahriman/web/views/v1/status/repositories.py +++ b/src/ahriman/web/views/v1/status/repositories.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # from aiohttp.web import Response, json_response +from typing import ClassVar from ahriman.models.user_access import UserAccess from ahriman.web.apispec.decorators import apidocs @@ -33,7 +34,7 @@ class RepositoriesView(BaseView): GET_PERMISSION(UserAccess): (class attribute) get permissions of self """ - GET_PERMISSION = UserAccess.Read + GET_PERMISSION: ClassVar[UserAccess] = UserAccess.Read ROUTES = ["/api/v1/repositories"] @apidocs( diff --git a/src/ahriman/web/views/v1/status/status.py b/src/ahriman/web/views/v1/status/status.py index 3c3a0813..fb87f973 100644 --- a/src/ahriman/web/views/v1/status/status.py +++ b/src/ahriman/web/views/v1/status/status.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # from aiohttp.web import HTTPBadRequest, HTTPNoContent, Response, json_response +from typing import ClassVar from ahriman import __version__ from ahriman.models.build_status import BuildStatusEnum @@ -40,8 +41,8 @@ class StatusView(StatusViewGuard, BaseView): POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ - GET_PERMISSION = UserAccess.Read - POST_PERMISSION = UserAccess.Full + GET_PERMISSION: ClassVar[UserAccess] = UserAccess.Read + POST_PERMISSION: ClassVar[UserAccess] = UserAccess.Full ROUTES = ["/api/v1/status"] @apidocs( diff --git a/src/ahriman/web/views/v1/user/login.py b/src/ahriman/web/views/v1/user/login.py index 591685ff..56bb803a 100644 --- a/src/ahriman/web/views/v1/user/login.py +++ b/src/ahriman/web/views/v1/user/login.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # from aiohttp.web import HTTPBadRequest, HTTPFound, HTTPMethodNotAllowed, HTTPUnauthorized +from typing import ClassVar from ahriman.core.auth.helpers import remember from ahriman.models.user_access import UserAccess @@ -35,7 +36,7 @@ class LoginView(BaseView): POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ - GET_PERMISSION = POST_PERMISSION = UserAccess.Unauthorized + GET_PERMISSION = POST_PERMISSION = UserAccess.Unauthorized # type: ClassVar[UserAccess] ROUTES = ["/api/v1/login"] @apidocs( diff --git a/src/ahriman/web/views/v1/user/logout.py b/src/ahriman/web/views/v1/user/logout.py index 24587f0b..f5911c8c 100644 --- a/src/ahriman/web/views/v1/user/logout.py +++ b/src/ahriman/web/views/v1/user/logout.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # from aiohttp.web import HTTPFound, HTTPUnauthorized +from typing import ClassVar from ahriman.core.auth.helpers import check_authorized, forget from ahriman.models.user_access import UserAccess @@ -33,7 +34,7 @@ class LogoutView(BaseView): POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ - POST_PERMISSION = UserAccess.Unauthorized + POST_PERMISSION: ClassVar[UserAccess] = UserAccess.Unauthorized ROUTES = ["/api/v1/logout"] @apidocs( diff --git a/src/ahriman/web/views/v2/packages/logs.py b/src/ahriman/web/views/v2/packages/logs.py index 0e9bfe40..699c52ed 100644 --- a/src/ahriman/web/views/v2/packages/logs.py +++ b/src/ahriman/web/views/v2/packages/logs.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # from aiohttp.web import Response, json_response +from typing import ClassVar from ahriman.models.user_access import UserAccess from ahriman.web.apispec.decorators import apidocs @@ -34,7 +35,7 @@ class LogsView(StatusViewGuard, BaseView): GET_PERMISSION(UserAccess): (class attribute) get permissions of self """ - GET_PERMISSION = UserAccess.Reporter + GET_PERMISSION: ClassVar[UserAccess] = UserAccess.Reporter ROUTES = ["/api/v2/packages/{package}/logs"] @apidocs(