diff options
Diffstat (limited to 'searx/result_types')
| -rw-r--r-- | searx/result_types/__init__.py | 6 | ||||
| -rw-r--r-- | searx/result_types/_base.py | 61 | ||||
| -rw-r--r-- | searx/result_types/answer.py | 6 |
3 files changed, 38 insertions, 35 deletions
diff --git a/searx/result_types/__init__.py b/searx/result_types/__init__.py index f4b37df07..22316b172 100644 --- a/searx/result_types/__init__.py +++ b/searx/result_types/__init__.py @@ -34,7 +34,7 @@ from .keyvalue import KeyValue from .code import Code -class ResultList(list, abc.ABC): # pyright: ignore[reportMissingTypeArgument] +class ResultList(list[Result | LegacyResult], abc.ABC): """Base class of all result lists (abstract).""" @t.final @@ -55,11 +55,11 @@ class ResultList(list, abc.ABC): # pyright: ignore[reportMissingTypeArgument] def __init__(self): # pylint: disable=useless-parent-delegation - super().__init__() # pyright: ignore[reportUnknownMemberType] + super().__init__() def add(self, result: Result | LegacyResult): """Add a :py:`Result` item to the result list.""" - self.append(result) # pyright: ignore[reportUnknownMemberType] + self.append(result) class EngineResults(ResultList): diff --git a/searx/result_types/_base.py b/searx/result_types/_base.py index db81fc8d2..1c614651b 100644 --- a/searx/result_types/_base.py +++ b/searx/result_types/_base.py @@ -16,15 +16,13 @@ :members: """ - -from __future__ import annotations - __all__ = ["Result"] +import typing as t + import re import urllib.parse import warnings -import typing import time import datetime @@ -38,7 +36,7 @@ WHITESPACE_REGEX = re.compile('( |\t|\n)+', re.M | re.U) UNKNOWN = object() -def _normalize_url_fields(result: Result | LegacyResult): +def _normalize_url_fields(result: "Result | LegacyResult"): # As soon we need LegacyResult not any longer, we can move this function to # method Result.normalize_result_fields @@ -75,7 +73,7 @@ def _normalize_url_fields(result: Result | LegacyResult): path=_url.path, ).geturl() - infobox_id = getattr(result, "id", None) + infobox_id: str | None = getattr(result, "id", None) if infobox_id: _url = urllib.parse.urlparse(infobox_id) result.id = _url._replace( @@ -85,7 +83,7 @@ def _normalize_url_fields(result: Result | LegacyResult): ).geturl() -def _normalize_text_fields(result: MainResult | LegacyResult): +def _normalize_text_fields(result: "MainResult | LegacyResult"): # As soon we need LegacyResult not any longer, we can move this function to # method MainResult.normalize_result_fields @@ -111,7 +109,9 @@ def _normalize_text_fields(result: MainResult | LegacyResult): result.content = "" -def _filter_urls(result: Result | LegacyResult, filter_func: Callable[[Result | LegacyResult, str, str], str | bool]): +def _filter_urls( + result: "Result | LegacyResult", filter_func: "Callable[[Result | LegacyResult, str, str], str | bool]" +): # pylint: disable=too-many-branches, too-many-statements # As soon we need LegacyResult not any longer, we can move this function to @@ -119,6 +119,8 @@ def _filter_urls(result: Result | LegacyResult, filter_func: Callable[[Result | url_fields = ["url", "iframe_src", "audio_src", "img_src", "thumbnail_src", "thumbnail"] + url_src: str + for field_name in url_fields: url_src = getattr(result, field_name, "") if not url_src: @@ -155,7 +157,7 @@ def _filter_urls(result: Result | LegacyResult, filter_func: Callable[[Result | new_infobox_urls: list[dict[str, str]] = [] for item in infobox_urls: - url_src = item.get("url") + url_src = item.get("url", "") if not url_src: new_infobox_urls.append(item) continue @@ -179,14 +181,14 @@ def _filter_urls(result: Result | LegacyResult, filter_func: Callable[[Result | # # The infobox has additional subsections for attributes, urls and relatedTopics: - infobox_attributes: list[dict[str, dict]] = getattr(result, "attributes", []) + infobox_attributes: list[dict[str, t.Any]] = getattr(result, "attributes", []) if infobox_attributes: # log.debug("filter_urls: infobox_attributes .. %s", infobox_attributes) - new_infobox_attributes: list[dict[str, dict]] = [] + new_infobox_attributes: list[dict[str, str | list[dict[str, str]]]] = [] for item in infobox_attributes: - image = item.get("image", {}) + image: dict[str, str] = item.get("image", {}) url_src = image.get("src", "") if not url_src: new_infobox_attributes.append(item) @@ -215,7 +217,7 @@ def _filter_urls(result: Result | LegacyResult, filter_func: Callable[[Result | result.normalize_result_fields() -def _normalize_date_fields(result: MainResult | LegacyResult): +def _normalize_date_fields(result: "MainResult | LegacyResult"): if result.publishedDate: # do not try to get a date from an empty string or a None type try: # test if publishedDate >= 1900 (datetime module bug) @@ -264,7 +266,7 @@ class Result(msgspec.Struct, kw_only=True): def __post_init__(self): pass - def filter_urls(self, filter_func: Callable[[Result | LegacyResult, str, str], str | bool]): + def filter_urls(self, filter_func: "Callable[[Result | LegacyResult, str, str], str | bool]"): """A filter function is passed in the ``filter_func`` argument to filter and/or modify the URLs. @@ -304,7 +306,7 @@ class Result(msgspec.Struct, kw_only=True): """ return id(self) - def __eq__(self, other): + def __eq__(self, other: object): """py:obj:`Result` objects are equal if the hash values of the two objects are equal. If needed, its recommended to overwrite "py:obj:`Result.__hash__`.""" @@ -313,11 +315,11 @@ class Result(msgspec.Struct, kw_only=True): # for legacy code where a result is treated as a Python dict - def __setitem__(self, field_name, value): + def __setitem__(self, field_name: str, value: t.Any): return setattr(self, field_name, value) - def __getitem__(self, field_name): + def __getitem__(self, field_name: str) -> t.Any: if field_name not in self.__struct_fields__: raise KeyError(f"{field_name}") @@ -330,7 +332,7 @@ class Result(msgspec.Struct, kw_only=True): def as_dict(self): return {f: getattr(self, f) for f in self.__struct_fields__} - def defaults_from(self, other: Result): + def defaults_from(self, other: "Result"): """Fields not set in *self* will be updated from the field values of the *other*. """ @@ -374,7 +376,8 @@ class MainResult(Result): # pylint: disable=missing-class-docstring metadata: str = "" """Miscellaneous metadata.""" - priority: typing.Literal["", "high", "low"] = "" + PriorityType = t.Literal["", "high", "low"] # pyright: ignore[reportUnannotatedClassAttribute] + priority: "MainResult.PriorityType" = "" """The priority can be set via :ref:`hostnames plugin`, for example.""" engines: set[str] = set() @@ -412,7 +415,7 @@ class MainResult(Result): # pylint: disable=missing-class-docstring self.engines.add(self.engine) -class LegacyResult(dict): +class LegacyResult(dict[str, t.Any]): """A wrapper around a legacy result item. The SearXNG core uses this class for untyped dictionaries / to be downward compatible. @@ -428,7 +431,7 @@ class LegacyResult(dict): Do not use this class in your own implementations! """ - UNSET = object() + UNSET: object = object() # emulate field types from type class Result url: str | None @@ -441,7 +444,7 @@ class LegacyResult(dict): content: str img_src: str thumbnail: str - priority: typing.Literal["", "high", "low"] + priority: t.Literal["", "high", "low"] engines: set[str] positions: list[int] score: float @@ -456,7 +459,7 @@ class LegacyResult(dict): def as_dict(self): return self - def __init__(self, *args, **kwargs): + def __init__(self, *args: t.Any, **kwargs: t.Any): super().__init__(*args, **kwargs) @@ -499,15 +502,15 @@ class LegacyResult(dict): DeprecationWarning, ) - def __getattr__(self, name: str, default=UNSET) -> typing.Any: + def __getattr__(self, name: str, default: t.Any = UNSET) -> t.Any: if default == self.UNSET and name not in self: raise AttributeError(f"LegacyResult object has no field named: {name}") return self[name] - def __setattr__(self, name: str, val): + def __setattr__(self, name: str, val: t.Any): self[name] = val - def __hash__(self) -> int: # type: ignore + def __hash__(self) -> int: # pyright: ignore[reportIncompatibleVariableOverride] if "answer" in self: # deprecated .. @@ -535,7 +538,7 @@ class LegacyResult(dict): return id(self) - def __eq__(self, other): + def __eq__(self, other: object): return hash(self) == hash(other) @@ -550,11 +553,11 @@ class LegacyResult(dict): if self.engine: self.engines.add(self.engine) - def defaults_from(self, other: LegacyResult): + def defaults_from(self, other: "LegacyResult"): for k, v in other.items(): if not self.get(k): self[k] = v - def filter_urls(self, filter_func: Callable[[Result | LegacyResult, str, str], str | bool]): + def filter_urls(self, filter_func: "Callable[[Result | LegacyResult, str, str], str | bool]"): """See :py:obj:`Result.filter_urls`""" _filter_urls(self, filter_func=filter_func) diff --git a/searx/result_types/answer.py b/searx/result_types/answer.py index 7ea0787a1..2946a27bc 100644 --- a/searx/result_types/answer.py +++ b/searx/result_types/answer.py @@ -119,7 +119,7 @@ class Translations(BaseAnswer, kw_only=True): """The template in :origin:`answer/translations.html <searx/templates/simple/answer/translations.html>`""" - translations: list[Translations.Item] + translations: "list[Translations.Item]" """List of translations.""" def __post_init__(self): @@ -158,10 +158,10 @@ class WeatherAnswer(BaseAnswer, kw_only=True): """The template is located at :origin:`answer/weather.html <searx/templates/simple/answer/weather.html>`""" - current: WeatherAnswer.Item + current: "WeatherAnswer.Item" """Current weather at ``location``.""" - forecasts: list[WeatherAnswer.Item] = [] + forecasts: "list[WeatherAnswer.Item]" = [] """Weather forecasts for ``location``.""" service: str = "" |