mirror of
https://github.com/searxng/searxng.git
synced 2026-05-07 18:03:51 +02:00
[fix] Result.defaults_from() inverted logic (#6019)
The bug was introduced in commit 8769b7c6d (typification of result items); this
patch fixes the bug and also addresses the peculiarity that fields can be set
but contain no *usable* value:
If a field is set (exists) but contains an empty string or the value ``None``,
it is also considered *not set*. This also ensures that an integer 0 is
evaluated *as set*!
Co-Authored: Markus Heiser <markus.heiser@darmarit.de>
This commit is contained in:
+13
-11
@@ -32,7 +32,7 @@ import msgspec
|
|||||||
from searx import logger as log
|
from searx import logger as log
|
||||||
|
|
||||||
WHITESPACE_REGEX = re.compile('( |\t|\n)+', re.M | re.U)
|
WHITESPACE_REGEX = re.compile('( |\t|\n)+', re.M | re.U)
|
||||||
UNKNOWN = object()
|
UNSET = object()
|
||||||
|
|
||||||
|
|
||||||
def _normalize_url_fields(result: "Result | LegacyResult"):
|
def _normalize_url_fields(result: "Result | LegacyResult"):
|
||||||
@@ -326,12 +326,13 @@ class Result(msgspec.Struct, kw_only=True):
|
|||||||
|
|
||||||
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
|
"""Fields not set in *self* will be updated from the field values of the
|
||||||
*other*.
|
*other*. If a field is set (exists) but contains an empty string
|
||||||
|
or the value ``None``, it is also considered *not set*.
|
||||||
"""
|
"""
|
||||||
for field_name in self.__struct_fields__:
|
for field_name in self.__struct_fields__:
|
||||||
self_val = getattr(self, field_name, False)
|
self_val = getattr(self, field_name, UNSET)
|
||||||
other_val = getattr(other, field_name, False)
|
other_val = getattr(other, field_name, UNSET)
|
||||||
if self_val:
|
if self_val is UNSET and other_val not in (UNSET, "", None):
|
||||||
setattr(self, field_name, other_val)
|
setattr(self, field_name, other_val)
|
||||||
|
|
||||||
|
|
||||||
@@ -440,8 +441,6 @@ class LegacyResult(dict[str, t.Any]):
|
|||||||
Do not use this class in your own implementations!
|
Do not use this class in your own implementations!
|
||||||
"""
|
"""
|
||||||
|
|
||||||
UNSET: object = object()
|
|
||||||
|
|
||||||
# emulate field types from type class Result
|
# emulate field types from type class Result
|
||||||
url: str | None
|
url: str | None
|
||||||
template: str
|
template: str
|
||||||
@@ -512,7 +511,7 @@ class LegacyResult(dict[str, t.Any]):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def __getattr__(self, name: str, default: t.Any = UNSET) -> t.Any:
|
def __getattr__(self, name: str, default: t.Any = UNSET) -> t.Any:
|
||||||
if default == self.UNSET and name not in self:
|
if default == UNSET and name not in self:
|
||||||
raise AttributeError(f"LegacyResult object has no field named: {name}")
|
raise AttributeError(f"LegacyResult object has no field named: {name}")
|
||||||
return self[name]
|
return self[name]
|
||||||
|
|
||||||
@@ -563,9 +562,12 @@ class LegacyResult(dict[str, t.Any]):
|
|||||||
self.engines.add(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 a field is set (exists) but contains an empty string or the value
|
||||||
if not self.get(k):
|
# ``None``, it is also considered *not set*.
|
||||||
self[k] = v
|
for field_name, other_val in other.items():
|
||||||
|
self_val = self.get(field_name, UNSET)
|
||||||
|
if self_val is UNSET and other_val not in ("", UNSET):
|
||||||
|
self[field_name] = other_val
|
||||||
|
|
||||||
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`"""
|
"""See :py:obj:`Result.filter_urls`"""
|
||||||
|
|||||||
Reference in New Issue
Block a user