From f1f93a87b324da277b4ea859d8aa1b5a99e5a948 Mon Sep 17 00:00:00 2001 From: nicarl Date: Wed, 27 Oct 2021 18:49:42 +0200 Subject: [PATCH] Take into account area codes for French phone numbers (#1560) French landline numbers (starting with 01, 02, 03, 04, 05) are limited to well-known area codes. This is taken into account when generating the phone numbers. Mobile phone numbers starting with 07 are also added. Fixes: #1516 --- .../providers/phone_number/fr_FR/__init__.py | 284 ++++++++++++++++-- tests/providers/test_phone_number.py | 25 ++ 2 files changed, 277 insertions(+), 32 deletions(-) diff --git a/faker/providers/phone_number/fr_FR/__init__.py b/faker/providers/phone_number/fr_FR/__init__.py index 43827eb2d6..decf7d35ce 100644 --- a/faker/providers/phone_number/fr_FR/__init__.py +++ b/faker/providers/phone_number/fr_FR/__init__.py @@ -3,36 +3,256 @@ class Provider(PhoneNumberProvider): formats = ( - "+33 (0)1 ## ## ## ##", - "+33 (0)1 ## ## ## ##", - "+33 (0)2 ## ## ## ##", - "+33 (0)3 ## ## ## ##", - "+33 (0)4 ## ## ## ##", - "+33 (0)5 ## ## ## ##", - "+33 (0)6 ## ## ## ##", - "+33 (0)8 0# ## ## ##", - "+33 1 ## ## ## ##", - "+33 1 ## ## ## ##", - "+33 2 ## ## ## ##", - "+33 3 ## ## ## ##", - "+33 4 ## ## ## ##", - "+33 5 ## ## ## ##", - "+33 6 ## ## ## ##", - "+33 8 0# ## ## ##", - "01########", - "01########", - "02########", - "03########", - "04########", - "05########", - "06########", - "080#######", - "01 ## ## ## ##", - "01 ## ## ## ##", - "02 ## ## ## ##", - "03 ## ## ## ##", - "04 ## ## ## ##", - "05 ## ## ## ##", - "06 ## ## ## ##", - "08 0# ## ## ##", + "+33 (0){{area_code_with_separator}} ## ## ##", + "+33 {{area_code_with_separator}} ## ## ##", + "0{{area_code_without_separator}}######", + "0{{area_code_with_separator}} ## ## ##", ) + + # https://fr.wikipedia.org/wiki/Liste_des_indicatifs_t%C3%A9l%C3%A9phoniques_en_France#Liste_des_indicatifs_d%C3%A9partementaux_fran%C3%A7ais_class%C3%A9s_par_indicatif + area_codes = ( + # landlines + "130", + "134", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "153", + "155", + "156", + "158", + "160", + "164", + "169", + "170", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "188", + "214", + "218", + "219", + "221", + "222", + "223", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "240", + "241", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "261", + "262", + "269", + "272", + "276", + "277", + "278", + "279", + "285", + "290", + "296", + "297", + "298", + "299", + "310", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "339", + "344", + "345", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "375", + "376", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "411", + "413", + "415", + "420", + "422", + "423", + "426", + "427", + "430", + "432", + "434", + "437", + "438", + "442", + "443", + "444", + "449", + "450", + "456", + "457", + "458", + "463", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "497", + "498", + "499", + "58 ", + "516", + "517", + "518", + "519", + "524", + "531", + "532", + "533", + "534", + "535", + "536", + "540", + "545", + "546", + "547", + "549", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "561", + "562", + "563", + "564", + "565", + "567", + "579", + "581", + "582", + "586", + "587", + "590", + "594", + "596", + # mobile numbers + "6##", + "7##", + "80#", + ) + + def area_code_without_separator(self) -> str: + return self.numerify(self.random_element(self.area_codes)) + + def area_code_with_separator(self) -> str: + area_code: str = self.random_element(self.area_codes) + return self.numerify(f"{area_code[0]} {area_code[1:]}") + + def phone_number(self) -> str: + pattern: str = self.random_element(self.formats) + return self.numerify(self.generator.parse(pattern)) diff --git a/tests/providers/test_phone_number.py b/tests/providers/test_phone_number.py index 3bfc044340..33f4438d30 100644 --- a/tests/providers/test_phone_number.py +++ b/tests/providers/test_phone_number.py @@ -291,3 +291,28 @@ def test_phone_number(self, faker, num_samples): for _ in range(num_samples): phone = faker.phone_number() assert pattern.fullmatch(phone) + + +class TestFrFr: + def test_phone_number(self, faker, num_samples): + pattern_no_whitespaces: Pattern = re.compile( + r"^0\d{9}$", + ) + pattern_no_country_prefix: Pattern = re.compile( + r"^0\d \d{2} \d{2} \d{2} \d{2}$", + ) + pattern_country_prefix_1: Pattern = re.compile( + r"^\+33 \(0\)\d \d{2} \d{2} \d{2} \d{2}$", + ) + pattern_country_prefix_2: Pattern = re.compile( + r"^\+33 \d \d{2} \d{2} \d{2} \d{2}$", + ) + patterns = [ + pattern_no_whitespaces, + pattern_no_country_prefix, + pattern_country_prefix_1, + pattern_country_prefix_2, + ] + for _ in range(num_samples): + phone_number = faker.phone_number() + assert any([re.match(pattern, phone_number) for pattern in patterns])