Corregir lo que reportó ruff, que nunca se había ejecutado
ruff estaba configurado en pyproject.toml desde el primer commit y jamás se había corrido. Tenía 15 hallazgos. Dos importan más allá del estilo: - zip() sin strict= trunca en silencio al más corto. En las comparaciones de lotes eso significa que un test podía pasar sin haber comparado todo. Donde los largos deben coincidir ahora es strict=True; donde difieren a propósito (pares consecutivos) queda strict=False, que documenta la intención. - Un import sin usar delataba algo peor: BraveBackend se había escrito sin una sola prueba. Se agregan ocho, contra una respuesta con la forma que devuelve la API, incluidas la limpieza de etiquetas, el caso de límite de tasa —que tiene que distinguirse de 'no respondió'— y que la credencial viaje en la cabecera y nunca en la URL. El respaldo tiene que funcionar justo cuando el primario ya falló; merecía la misma cobertura. El resto es orden de imports, collections.abc y líneas largas.
This commit is contained in:
@@ -30,7 +30,10 @@ from dataclasses import dataclass
|
||||
from typing import Protocol
|
||||
|
||||
# Un navegador real: el endpoint lite rechaza clientes sin User-Agent.
|
||||
_USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125 Safari/537.36"
|
||||
_USER_AGENT = (
|
||||
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 "
|
||||
"(KHTML, like Gecko) Chrome/125 Safari/537.36"
|
||||
)
|
||||
|
||||
_RE_LINK = re.compile(
|
||||
r"<a[^>]*?href=[\"'](?P<url>[^\"']+)[\"'][^>]*?class=['\"]result-link['\"][^>]*?>"
|
||||
@@ -168,13 +171,17 @@ class BraveBackend:
|
||||
self.language = language
|
||||
|
||||
def search(self, query: str, max_results: int) -> list[SearchResult]:
|
||||
url = self.ENDPOINT + "?" + urllib.parse.urlencode(
|
||||
{
|
||||
"q": query,
|
||||
"count": max_results,
|
||||
"country": self.country,
|
||||
"search_lang": self.language,
|
||||
}
|
||||
url = (
|
||||
self.ENDPOINT
|
||||
+ "?"
|
||||
+ urllib.parse.urlencode(
|
||||
{
|
||||
"q": query,
|
||||
"count": max_results,
|
||||
"country": self.country,
|
||||
"search_lang": self.language,
|
||||
}
|
||||
)
|
||||
)
|
||||
request = urllib.request.Request(
|
||||
url,
|
||||
@@ -283,9 +290,7 @@ class CadenaDeBackends:
|
||||
self.ultimo_backend = nombre
|
||||
return resultados
|
||||
|
||||
raise SearchError(
|
||||
"ningún backend de búsqueda respondió — " + " | ".join(fallos)
|
||||
)
|
||||
raise SearchError("ningún backend de búsqueda respondió — " + " | ".join(fallos))
|
||||
|
||||
|
||||
class WebSearch:
|
||||
@@ -357,9 +362,7 @@ def _construir_uno(nombre: str, config) -> SearchBackend:
|
||||
)
|
||||
if nombre == "searxng":
|
||||
if not config.searxng_url:
|
||||
raise SearchError(
|
||||
"backend searxng sin searxng_url: definí ENLACE_SEARXNG_URL en .env"
|
||||
)
|
||||
raise SearchError("backend searxng sin searxng_url: definí ENLACE_SEARXNG_URL en .env")
|
||||
return SearxNGBackend(
|
||||
base_url=config.searxng_url, timeout=config.timeout, language=config.language
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user