type: use custom comparable for comparable functions

This commit is contained in:
2025-07-15 21:20:49 +03:00
parent dff5b775a9
commit ae32cc8fbb
8 changed files with 27 additions and 11 deletions

View File

@ -28,6 +28,7 @@ from ahriman.core.alpm.remote import AUR, Official
from ahriman.core.configuration import Configuration from ahriman.core.configuration import Configuration
from ahriman.core.exceptions import OptionError from ahriman.core.exceptions import OptionError
from ahriman.core.formatters import AurPrinter from ahriman.core.formatters import AurPrinter
from ahriman.core.types import Comparable
from ahriman.models.aur_package import AURPackage from ahriman.models.aur_package import AURPackage
from ahriman.models.repository_id import RepositoryId from ahriman.models.repository_id import RepositoryId
@ -115,7 +116,7 @@ class Search(Handler):
raise OptionError(sort_by) raise OptionError(sort_by)
# always sort by package name at the last # always sort by package name at the last
# well technically it is not a string, but we can deal with it # well technically it is not a string, but we can deal with it
comparator: Callable[[AURPackage], tuple[str, str]] =\ comparator: Callable[[AURPackage], Comparable] = \
lambda package: (getattr(package, sort_by), package.name) lambda package: (getattr(package, sort_by), package.name)
return sorted(packages, key=comparator) return sorted(packages, key=comparator)

View File

@ -25,6 +25,7 @@ from ahriman.application.application import Application
from ahriman.application.handlers.handler import Handler, SubParserAction from ahriman.application.handlers.handler import Handler, SubParserAction
from ahriman.core.configuration import Configuration from ahriman.core.configuration import Configuration
from ahriman.core.formatters import PackagePrinter, StatusPrinter from ahriman.core.formatters import PackagePrinter, StatusPrinter
from ahriman.core.types import Comparable
from ahriman.core.utils import enum_values from ahriman.core.utils import enum_values
from ahriman.models.build_status import BuildStatus, BuildStatusEnum from ahriman.models.build_status import BuildStatus, BuildStatusEnum
from ahriman.models.package import Package from ahriman.models.package import Package
@ -64,7 +65,7 @@ class Status(Handler):
Status.check_status(args.exit_code, packages) Status.check_status(args.exit_code, packages)
comparator: Callable[[tuple[Package, BuildStatus]], str] = lambda item: item[0].base comparator: Callable[[tuple[Package, BuildStatus]], Comparable] = lambda item: item[0].base
filter_fn: Callable[[tuple[Package, BuildStatus]], bool] =\ filter_fn: Callable[[tuple[Package, BuildStatus]], bool] =\
lambda item: args.status is None or item[1].status == args.status lambda item: args.status is None or item[1].status == args.status
for package, package_status in sorted(filter(filter_fn, packages), key=comparator): for package, package_status in sorted(filter(filter_fn, packages), key=comparator):

View File

@ -26,6 +26,7 @@ from typing import Any
from ahriman.core.configuration import Configuration from ahriman.core.configuration import Configuration
from ahriman.core.sign.gpg import GPG from ahriman.core.sign.gpg import GPG
from ahriman.core.types import Comparable
from ahriman.core.utils import pretty_datetime, pretty_size, utcnow from ahriman.core.utils import pretty_datetime, pretty_size, utcnow
from ahriman.models.repository_id import RepositoryId from ahriman.models.repository_id import RepositoryId
from ahriman.models.result import Result from ahriman.models.result import Result
@ -111,7 +112,7 @@ class JinjaTemplate:
Returns: Returns:
list[dict[str, str]]: sorted content according to comparator defined list[dict[str, str]]: sorted content according to comparator defined
""" """
comparator: Callable[[dict[str, str]], str] = lambda item: item["filename"] comparator: Callable[[dict[str, str]], Comparable] = lambda item: item["filename"]
return sorted(content, key=comparator) return sorted(content, key=comparator)
def make_html(self, result: Result, template_name: Path | str) -> str: def make_html(self, result: Result, template_name: Path | str) -> str:

View File

@ -28,6 +28,7 @@ from ahriman.core.configuration import Configuration
from ahriman.core.report.jinja_template import JinjaTemplate from ahriman.core.report.jinja_template import JinjaTemplate
from ahriman.core.report.report import Report from ahriman.core.report.report import Report
from ahriman.core.status import Client from ahriman.core.status import Client
from ahriman.core.types import Comparable
from ahriman.models.event import EventType from ahriman.models.event import EventType
from ahriman.models.package import Package from ahriman.models.package import Package
from ahriman.models.repository_id import RepositoryId from ahriman.models.repository_id import RepositoryId
@ -86,7 +87,7 @@ class RSS(Report, JinjaTemplate):
Returns: Returns:
list[dict[str, str]]: sorted content according to comparator defined list[dict[str, str]]: sorted content according to comparator defined
""" """
comparator: Callable[[dict[str, str]], datetime.datetime] = \ comparator: Callable[[dict[str, str]], Comparable] = \
lambda item: parsedate_to_datetime(item["build_date"]) lambda item: parsedate_to_datetime(item["build_date"])
return sorted(content, key=comparator, reverse=True) return sorted(content, key=comparator, reverse=True)

View File

@ -17,7 +17,15 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
from typing import Protocol from typing import Any, Protocol
class Comparable(Protocol):
"""
class which supports :func:`__lt__` operation`
"""
def __lt__(self, other: Any) -> bool: ...
class HasBool(Protocol): class HasBool(Protocol):

View File

@ -21,6 +21,7 @@ from aiohttp.web import HTTPBadRequest, HTTPNoContent, Response, json_response
from collections.abc import Callable from collections.abc import Callable
from typing import ClassVar from typing import ClassVar
from ahriman.core.types import Comparable
from ahriman.models.user_access import UserAccess from ahriman.models.user_access import UserAccess
from ahriman.models.worker import Worker from ahriman.models.worker import Worker
from ahriman.web.apispec.decorators import apidocs from ahriman.web.apispec.decorators import apidocs
@ -74,7 +75,7 @@ class WorkersView(BaseView):
""" """
workers = self.workers.workers workers = self.workers.workers
comparator: Callable[[Worker], str] = lambda item: item.identifier comparator: Callable[[Worker], Comparable] = lambda item: item.identifier
response = [worker.view() for worker in sorted(workers, key=comparator)] response = [worker.view() for worker in sorted(workers, key=comparator)]
return json_response(response) return json_response(response)

View File

@ -23,6 +23,7 @@ from aiohttp.web import HTTPNoContent, Response, json_response
from collections.abc import Callable from collections.abc import Callable
from typing import ClassVar from typing import ClassVar
from ahriman.core.types import Comparable
from ahriman.models.build_status import BuildStatus from ahriman.models.build_status import BuildStatus
from ahriman.models.package import Package from ahriman.models.package import Package
from ahriman.models.user_access import UserAccess from ahriman.models.user_access import UserAccess
@ -68,7 +69,7 @@ class PackagesView(StatusViewGuard, BaseView):
repository_id = self.repository_id() repository_id = self.repository_id()
packages = self.service(repository_id).packages packages = self.service(repository_id).packages
comparator: Callable[[tuple[Package, BuildStatus]], str] = lambda items: items[0].base comparator: Callable[[tuple[Package, BuildStatus]], Comparable] = lambda items: items[0].base
response = [ response = [
{ {
"package": package.view(), "package": package.view(),

View File

@ -22,6 +22,7 @@ from collections.abc import Callable
from typing import ClassVar from typing import ClassVar
from ahriman.core.alpm.remote import AUR from ahriman.core.alpm.remote import AUR
from ahriman.core.types import Comparable
from ahriman.models.aur_package import AURPackage from ahriman.models.aur_package import AURPackage
from ahriman.models.user_access import UserAccess from ahriman.models.user_access import UserAccess
from ahriman.web.apispec.decorators import apidocs from ahriman.web.apispec.decorators import apidocs
@ -70,10 +71,11 @@ class SearchView(BaseView):
if not packages: if not packages:
raise HTTPNotFound(reason=f"No packages found for terms: {search}") raise HTTPNotFound(reason=f"No packages found for terms: {search}")
comparator: Callable[[AURPackage], tuple[bool, bool, str]] = lambda item: ( comparator: Callable[[AURPackage], Comparable] = \
item.package_base not in search, # inverted because False < True lambda item: (
not any(item.package_base.startswith(term) for term in search), # same as above item.package_base not in search, # inverted because False < True
item.package_base, not any(item.package_base.startswith(term) for term in search), # same as above
item.package_base,
) )
response = [ response = [
{ {