summaryrefslogtreecommitdiff
path: root/searx/plugins/_core.py
diff options
context:
space:
mode:
authorMarkus Heiser <markus.heiser@darmarit.de>2025-09-30 14:00:09 +0200
committerMarkus Heiser <markus.heiser@darmarIT.de>2025-10-01 07:13:10 +0200
commite16b6cb148d9fe6599ec8ce4b2803f0aed3a1d6b (patch)
tree3beec5a878f90987954fb0a3e4fc52919eacd570 /searx/plugins/_core.py
parent41e0f2abf0546c3d27aa33d84e6220ea8bf257d0 (diff)
[fix] JSON format: serialization of the result-types
The ``JSONEncoder`` (``format="json"``) must perform a conversion to the built-in types for the ``msgspec.Struct``:: if isinstance(o, msgspec.Struct): return msgspec.to_builtins(o) The result types are already of type ``msgspec.Struct``, so they can be converted into built-in types. The field types (in the result type) that were not yet of type ``msgspec.Struct`` have been converted to:: searx.weather.GeoLocation@dataclass -> msgspec.Struct searx.weather.DateTime -> msgspec.Struct searx.weather.Temperature -> msgspec.Struct searx.weather.PressureUnits -> msgspec.Struct searx.weather.WindSpeed -> msgspec.Struct searx.weather.RelativeHumidity -> msgspec.Struct searx.weather.Compass -> msgspec.Struct BTW: Wherever it seemed sensible, the typing was also modernized in the modified files. Closes: https://github.com/searxng/searxng/issues/5250 Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
Diffstat (limited to 'searx/plugins/_core.py')
-rw-r--r--searx/plugins/_core.py30
1 files changed, 16 insertions, 14 deletions
diff --git a/searx/plugins/_core.py b/searx/plugins/_core.py
index ef8e5cf46..4b9db076e 100644
--- a/searx/plugins/_core.py
+++ b/searx/plugins/_core.py
@@ -1,7 +1,6 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
# pylint: disable=too-few-public-methods,missing-module-docstring
-
__all__ = ["PluginInfo", "Plugin", "PluginCfg", "PluginStorage"]
import abc
@@ -9,16 +8,17 @@ import importlib
import inspect
import logging
import re
-import typing
-from collections.abc import Sequence
+
+import typing as t
+from collections.abc import Generator
from dataclasses import dataclass, field
from searx.extended_types import SXNG_Request
-from searx.result_types import Result
-if typing.TYPE_CHECKING:
+if t.TYPE_CHECKING:
from searx.search import SearchWithPlugins
+ from searx.result_types import Result, EngineResults, LegacyResult # pyright: ignore[reportPrivateLocalImportUsage]
import flask
log: logging.Logger = logging.getLogger("searx.plugins")
@@ -42,7 +42,7 @@ class PluginInfo:
description: str
"""Short description of the *answerer*."""
- preference_section: typing.Literal["general", "ui", "privacy", "query"] | None = "general"
+ preference_section: t.Literal["general", "ui", "privacy", "query"] | None = "general"
"""Section (tab/group) in the preferences where this plugin is shown to the
user.
@@ -71,7 +71,7 @@ class Plugin(abc.ABC):
id: str = ""
"""The ID (suffix) in the HTML form."""
- active: typing.ClassVar[bool]
+ active: t.ClassVar[bool]
"""Plugin is enabled/disabled by default (:py:obj:`PluginCfg.active`)."""
keywords: list[str] = []
@@ -109,7 +109,7 @@ class Plugin(abc.ABC):
raise ValueError(f"plugin ID {self.id} contains invalid character (use lowercase ASCII)")
if not getattr(self, "log", None):
- pkg_name = inspect.getmodule(self.__class__).__package__ # type: ignore
+ pkg_name = inspect.getmodule(self.__class__).__package__ # pyright: ignore[reportOptionalMemberAccess]
self.log = logging.getLogger(f"{pkg_name}.{self.id}")
def __hash__(self) -> int:
@@ -120,7 +120,7 @@ class Plugin(abc.ABC):
return id(self)
- def __eq__(self, other: typing.Any):
+ def __eq__(self, other: t.Any):
"""py:obj:`Plugin` objects are equal if the hash values of the two
objects are equal."""
@@ -146,7 +146,7 @@ class Plugin(abc.ABC):
"""
return True
- def on_result(self, request: SXNG_Request, search: "SearchWithPlugins", result: Result) -> bool:
+ def on_result(self, request: SXNG_Request, search: "SearchWithPlugins", result: "Result") -> bool:
"""Runs for each result of each engine and returns a boolean:
- ``True`` to keep the result
@@ -166,7 +166,9 @@ class Plugin(abc.ABC):
"""
return True
- def post_search(self, request: SXNG_Request, search: "SearchWithPlugins") -> None | Sequence[Result]:
+ def post_search(
+ self, request: SXNG_Request, search: "SearchWithPlugins"
+ ) -> "None | list[Result | LegacyResult] | EngineResults":
"""Runs AFTER the search request. Can return a list of
:py:obj:`Result <searx.result_types._base.Result>` objects to be added to the
final result list."""
@@ -196,7 +198,7 @@ class PluginStorage:
def __init__(self):
self.plugin_list = set()
- def __iter__(self):
+ def __iter__(self) -> Generator[Plugin]:
yield from self.plugin_list
def __len__(self):
@@ -207,7 +209,7 @@ class PluginStorage:
return [p.info for p in self.plugin_list]
- def load_settings(self, cfg: dict[str, dict[str, typing.Any]]):
+ def load_settings(self, cfg: dict[str, dict[str, t.Any]]):
"""Load plugins configured in SearXNG's settings :ref:`settings
plugins`."""
@@ -262,7 +264,7 @@ class PluginStorage:
break
return ret
- def on_result(self, request: SXNG_Request, search: "SearchWithPlugins", result: Result) -> bool:
+ def on_result(self, request: SXNG_Request, search: "SearchWithPlugins", result: "Result") -> bool:
ret = True
for plugin in [p for p in self.plugin_list if p.id in search.user_plugins]: