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.exceptions import OptionError
from ahriman.core.formatters import AurPrinter
from ahriman.core.types import Comparable
from ahriman.models.aur_package import AURPackage
from ahriman.models.repository_id import RepositoryId
@ -115,7 +116,7 @@ class Search(Handler):
raise OptionError(sort_by)
# always sort by package name at the last
# 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)
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.core.configuration import Configuration
from ahriman.core.formatters import PackagePrinter, StatusPrinter
from ahriman.core.types import Comparable
from ahriman.core.utils import enum_values
from ahriman.models.build_status import BuildStatus, BuildStatusEnum
from ahriman.models.package import Package
@ -64,7 +65,7 @@ class Status(Handler):
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] =\
lambda item: args.status is None or item[1].status == args.status
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.sign.gpg import GPG
from ahriman.core.types import Comparable
from ahriman.core.utils import pretty_datetime, pretty_size, utcnow
from ahriman.models.repository_id import RepositoryId
from ahriman.models.result import Result
@ -111,7 +112,7 @@ class JinjaTemplate:
Returns:
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)
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.report import Report
from ahriman.core.status import Client
from ahriman.core.types import Comparable
from ahriman.models.event import EventType
from ahriman.models.package import Package
from ahriman.models.repository_id import RepositoryId
@ -86,7 +87,7 @@ class RSS(Report, JinjaTemplate):
Returns:
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"])
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
# 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):

View File

@ -21,6 +21,7 @@ from aiohttp.web import HTTPBadRequest, HTTPNoContent, Response, json_response
from collections.abc import Callable
from typing import ClassVar
from ahriman.core.types import Comparable
from ahriman.models.user_access import UserAccess
from ahriman.models.worker import Worker
from ahriman.web.apispec.decorators import apidocs
@ -74,7 +75,7 @@ class WorkersView(BaseView):
"""
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)]
return json_response(response)

View File

@ -23,6 +23,7 @@ from aiohttp.web import HTTPNoContent, Response, json_response
from collections.abc import Callable
from typing import ClassVar
from ahriman.core.types import Comparable
from ahriman.models.build_status import BuildStatus
from ahriman.models.package import Package
from ahriman.models.user_access import UserAccess
@ -68,7 +69,7 @@ class PackagesView(StatusViewGuard, BaseView):
repository_id = self.repository_id()
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 = [
{
"package": package.view(),

View File

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