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(