Skip to content

Commit 21e0397

Browse files
committed
Handle special letters in by_name() ignore_accents
remove_accents() only stripped accents that Unicode can split off from their base letter (NFD normalization), so letters with no such decomposition (ß, œ, æ, ø, ł, đ, etc.) passed through unchanged. Add an explicit translation map, applied after the NFD strip so composed forms (e.g. "ǿ") are also handled correctly. Updated test.
1 parent 3eed40f commit 21e0397

2 files changed

Lines changed: 31 additions & 2 deletions

File tree

pipeline/src/additional_methods/by_name.py.txt

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
all (bool, optional): Whether to return all objects that match the name, or only the first. Defaults to False.
2727
case_sensitive (bool, optional): Whether the search should be case-sensitive. Defaults to True.
2828
ignore_accents (bool, optional): Whether to ignore accents (acute, grave, circumflex) and
29-
other diacritical marks (cedilla, tilde, ring, etc.) when matching. Defaults to False.
29+
other diacritical marks (cedilla, tilde, ring, etc.) when matching. Also treat
30+
special letters (ß, œ, æ, ø, ł, etc.) as their closest plain-letter equivalents
31+
(e.g. "ß" as "ss"). Defaults to False.
3032
"""
3133
namelike_properties = ("name", "lookup_label", "family_name", "full_name", "short_name", "abbreviation")
3234
if cls._instance_lookup is None:
@@ -49,8 +51,21 @@
4951
def remove_accents(s):
5052
import unicodedata
5153

54+
special = str.maketrans({
55+
"Ł": "L", "ł": "l",
56+
"Ø": "O", "ø": "o",
57+
"Đ": "D", "đ": "d",
58+
"Ð": "D", "ð": "d",
59+
"Þ": "Th", "þ": "th",
60+
"Æ": "AE", "æ": "ae",
61+
"Œ": "OE", "œ": "oe",
62+
"ß": "ss", "ẞ": "SS",
63+
"Ə": "E", "ə": "e",
64+
"ı": "i",
65+
})
5266
nfd_form = unicodedata.normalize("NFD", s)
53-
return "".join(c for c in nfd_form if not unicodedata.combining(c))
67+
stripped = "".join(c for c in nfd_form if not unicodedata.combining(c))
68+
return stripped.translate(special)
5469

5570
def normalize(s):
5671
if not case_sensitive:

pipeline/tests/test_regressions.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,3 +749,17 @@ def test_pr0103_by_name_ignore_accents(om):
749749
for query, case_sensitive, ignore_accents, should_match in cases:
750750
match = SovereignState.by_name(query, case_sensitive=case_sensitive, ignore_accents=ignore_accents)
751751
assert (match is not None and match.name == "France") == should_match
752+
753+
# ignore_accents also has to map special letters
754+
special_letter_cases = [
755+
# (query, ignore_accents, expected_country_or_None)
756+
("Azərbaycan Respublikası", False, "Azerbaijan"), # exact
757+
("Azerbaycan Respublikasi", True, "Azerbaijan"),
758+
("Azerbaycan Respublikasi", False, None),
759+
("Wááshindoon Bikéyah Ałhidadiidzooígíí", False, "United States"), # exact
760+
("Waashindoon Bikeyah Alhidadiidzooigii", True, "United States"),
761+
("Waashindoon Bikeyah Alhidadiidzooigii", False, None),
762+
]
763+
for query, ignore_accents, expected_name in special_letter_cases:
764+
match = SovereignState.by_name(query, ignore_accents=ignore_accents)
765+
assert (match.name if match else None) == expected_name

0 commit comments

Comments
 (0)