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:
2026-07-28 07:25:51 -03:00
parent ba61125a3b
commit 4048936067
11 changed files with 185 additions and 64 deletions
+17 -14
View File
@@ -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
)