@@ -234,3 +234,61 @@ def test_reversed_order_unchanged(self) -> None:
234234 assert n .first == "Aliyev"
235235 assert n .middle == "Vusal Said"
236236 assert n .last == "oglu"
237+
238+
239+ class PatronymicHandlerInteractionTests (HumanNameTestBase ):
240+ """Both handlers run in sequence under the same flag; confirm no interference."""
241+
242+ def setup_method (self ) -> None :
243+ self .C = Constants (patronymic_name_order = True )
244+
245+ def hn (self , name : str ) -> HumanName :
246+ return HumanName (name , constants = self .C )
247+
248+ def test_east_slavic_shape_unaffected_by_turkic_handler (self ) -> None :
249+ # If handle_turkic_patronymic_name_order() ran BEFORE the East-Slavic
250+ # handler could fire, middle_list would already be length 1 (not 2),
251+ # so the Turkic guard is a no-op here regardless of call order.
252+ n = self .hn ("Ivanov Ivan Ivanovich" )
253+ assert n .first == "Ivan"
254+ assert n .middle == "Ivanovich"
255+ assert n .last == "Ivanov"
256+
257+ def test_turkic_shape_unaffected_by_east_slavic_handler (self ) -> None :
258+ # East-Slavic's own guard requires middle_list of length 1; this
259+ # input has middle_list of length 2, so it's a genuine no-op rather
260+ # than a partial mutation before the Turkic handler runs.
261+ n = self .hn ("Aliyev Vusal Said oglu" )
262+ assert n .first == "Vusal"
263+ assert n .middle == "Said oglu"
264+ assert n .last == "Aliyev"
265+
266+ def test_no_regex_collision_latin (self ) -> None :
267+ C = Constants ()
268+ east_slavic_examples = [
269+ "Ivanovich" , "Ivanovna" , "Sergeevich" , "Sergeevna" ,
270+ "Nikitichna" , "Ilyich" , "Kuzmich" , "Lukich" , "Fomich" , "Fokich" ,
271+ ]
272+ turkic_examples = [
273+ "oglu" , "oğlu" , "ogly" , "ogli" , "o'g'li" ,
274+ "qizi" , "qızı" , "kizi" , "kyzy" , "gyzy" , "uly" , "uulu" ,
275+ ]
276+ for word in east_slavic_examples :
277+ assert not C .regexes .turkic_patronymic_marker .match (word ), word
278+ for word in turkic_examples :
279+ assert not C .regexes .east_slavic_patronymic .search (word ), word
280+
281+ def test_no_regex_collision_cyrillic (self ) -> None :
282+ C = Constants ()
283+ east_slavic_examples = [
284+ "Иванович" , "Ивановна" , "Сергеевич" , "Сергеевна" ,
285+ "Никитична" , "Ильич" , "Кузьмич" , "Лукич" , "Фомич" , "Фокич" ,
286+ ]
287+ turkic_examples = [
288+ "оглу" , "оглы" , "оғлу" , "ўғли" , "угли" ,
289+ "кызы" , "гызы" , "қызы" , "қизи" , "улы" , "ұлы" , "уулу" ,
290+ ]
291+ for word in east_slavic_examples :
292+ assert not C .regexes .turkic_patronymic_marker_cyrillic .match (word ), word
293+ for word in turkic_examples :
294+ assert not C .regexes .east_slavic_patronymic_cyrillic .search (word ), word
0 commit comments