fix(geocoder): le contexte pays passait après la ville nue une fois sur quatre
build_fallback_queries cherchait le code pays comme SOUS-CHAÎNE du lieu : country_code.upper() in location_raw.upper() Or "DE" est contenu dans "DRESDEN", "FR" dans "FRESNES", "NO" dans "NOTODDEN", "ES" dans "TORRES". Le pays était donc considéré comme déjà présent, et la variante « ville, pays » se retrouvait reléguée APRÈS la ville nue. Le worker s'arrête au PREMIER résultat fiable : il interrogeait donc Geoapify sans aucun contexte pays, précisément sur les noms ambigus — il existe un Dresden dans l'Ohio. Sur un échantillon de 25 villes européennes réelles, 11 partaient sans désambiguïsation. Le code est désormais cherché comme mot entier. Le test existant n'attrapait rien parce qu'il vérifiait la PRÉSENCE du pays quelque part dans la liste (`any(...)`), jamais sa priorité : les nouveaux cas verrouillent l'ordre. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
22b7b8762f
commit
ebdcd74973
2 changed files with 34 additions and 1 deletions
|
|
@ -197,9 +197,18 @@ def build_fallback_queries(location_raw: str, country_code: str | None) -> list[
|
||||||
seen.add(q)
|
seen.add(q)
|
||||||
result.append(q)
|
result.append(q)
|
||||||
|
|
||||||
|
# Le code pays doit être cherché comme MOT ENTIER, pas comme sous-chaîne.
|
||||||
|
# `"DE" in "DRESDEN"` est vrai : le pays était donc considéré comme déjà
|
||||||
|
# présent, et la variante « ville, pays » se retrouvait reléguée APRÈS la
|
||||||
|
# ville nue. Or le worker s'arrête au premier résultat fiable — il
|
||||||
|
# interrogeait donc Geoapify sans aucun contexte pays, précisément sur les
|
||||||
|
# noms ambigus (il existe un Dresden dans l'Ohio). Le cas touchait environ
|
||||||
|
# une ville européenne sur quatre : Dresden/Dessau/Detmold (DE),
|
||||||
|
# Fresnes/Fréjus (FR), Notodden/Nordfjord (NO), Cáceres/Torres (ES)…
|
||||||
|
tokens = set(re.findall(r"[A-Za-z]+", location_raw.upper()))
|
||||||
has_country = bool(country_name) and (
|
has_country = bool(country_name) and (
|
||||||
country_name.lower() in location_raw.lower()
|
country_name.lower() in location_raw.lower()
|
||||||
or (country_code and country_code.upper() in location_raw.upper())
|
or (country_code and country_code.upper() in tokens)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Requête complète + pays (si pays pas déjà dans le texte)
|
# Requête complète + pays (si pays pas déjà dans le texte)
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,30 @@ class TestBuildFallbackQueries:
|
||||||
queries = build_fallback_queries("Bergen, Norway", "NO")
|
queries = build_fallback_queries("Bergen, Norway", "NO")
|
||||||
assert not any(q.count("Norway") > 1 for q in queries)
|
assert not any(q.count("Norway") > 1 for q in queries)
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("ville", "code", "pays"),
|
||||||
|
[
|
||||||
|
("Dresden", "DE", "Germany"), # "DE" est une sous-chaîne de "DRESDEN"
|
||||||
|
("Dessau", "DE", "Germany"),
|
||||||
|
("Fresnes", "FR", "France"),
|
||||||
|
("Notodden", "NO", "Norway"),
|
||||||
|
("Torres", "ES", "Spain"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_le_contexte_pays_passe_en_premier(self, ville, code, pays):
|
||||||
|
# Le worker s'arrête au PREMIER résultat fiable : l'ordre est la seule
|
||||||
|
# chose qui compte. Un code pays contenu par hasard dans le nom de la
|
||||||
|
# ville faisait passer la requête nue devant, supprimant toute
|
||||||
|
# désambiguïsation là où elle était le plus nécessaire.
|
||||||
|
assert build_fallback_queries(ville, code)[0] == f"{ville}, {pays}"
|
||||||
|
|
||||||
|
def test_le_code_pays_reellement_present_reste_prioritaire(self):
|
||||||
|
# Contrepartie : quand le code EST un mot du texte, le texte d'origine
|
||||||
|
# passe en premier — on ne le double pas d'un contexte redondant. La
|
||||||
|
# forme « ville, pays » reste en dernier recours, ce qui est voulu.
|
||||||
|
queries = build_fallback_queries("Berlin, DE", "DE")
|
||||||
|
assert queries[0] == "Berlin, DE"
|
||||||
|
|
||||||
def test_pays_inconnu_ne_plante_pas(self):
|
def test_pays_inconnu_ne_plante_pas(self):
|
||||||
assert build_fallback_queries("Bergen", "ZZ") == ["Bergen"]
|
assert build_fallback_queries("Bergen", "ZZ") == ["Bergen"]
|
||||||
assert build_fallback_queries("Bergen", None) == ["Bergen"]
|
assert build_fallback_queries("Bergen", None) == ["Bergen"]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue