Skip to content

Commit 122f0f3

Browse files
committed
Merge code changes from upstream v8.10.8
1 parent 5db545a commit 122f0f3

2 files changed

Lines changed: 60 additions & 47 deletions

File tree

python/phonenumbers/phonenumbermatcher.py

Lines changed: 57 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ class Leniency(object):
206206
EXACT_GROUPING = 3
207207

208208

209-
def _verify(leniency, numobj, candidate):
209+
def _verify(leniency, numobj, candidate, matcher):
210210
"""Returns True if number is a verified number according to the
211211
leniency."""
212212
if leniency == Leniency.POSSIBLE:
@@ -217,21 +217,21 @@ def _verify(leniency, numobj, candidate):
217217
return False
218218
return _is_national_prefix_present_if_required(numobj)
219219
elif leniency == Leniency.STRICT_GROUPING:
220-
return _verify_strict_grouping(numobj, candidate)
220+
return _verify_strict_grouping(numobj, candidate, matcher)
221221
elif leniency == Leniency.EXACT_GROUPING:
222-
return _verify_exact_grouping(numobj, candidate)
222+
return _verify_exact_grouping(numobj, candidate, matcher)
223223
else:
224224
raise Exception("Error: unsupported Leniency value %s" % leniency)
225225

226226

227-
def _verify_strict_grouping(numobj, candidate):
227+
def _verify_strict_grouping(numobj, candidate, matcher):
228228
if (not is_valid_number(numobj) or
229229
not _contains_only_valid_x_chars(numobj, candidate) or
230230
_contains_more_than_one_slash_in_national_number(numobj, candidate) or
231231
not _is_national_prefix_present_if_required(numobj)):
232232
return False
233-
return _check_number_grouping_is_valid(numobj, candidate,
234-
_all_number_groups_remain_grouped)
233+
return matcher._check_number_grouping_is_valid(numobj, candidate,
234+
_all_number_groups_remain_grouped)
235235

236236

237237
def _all_number_groups_remain_grouped(numobj, normalized_candidate, formatted_number_groups):
@@ -284,14 +284,14 @@ def _all_number_groups_remain_grouped(numobj, normalized_candidate, formatted_nu
284284
return (normalized_candidate[from_index:].find(numobj.extension or U_EMPTY_STRING) != -1)
285285

286286

287-
def _verify_exact_grouping(numobj, candidate):
287+
def _verify_exact_grouping(numobj, candidate, matcher):
288288
if (not is_valid_number(numobj) or
289289
not _contains_only_valid_x_chars(numobj, candidate) or
290290
_contains_more_than_one_slash_in_national_number(numobj, candidate) or
291291
not _is_national_prefix_present_if_required(numobj)):
292292
return False
293-
return _check_number_grouping_is_valid(numobj, candidate,
294-
_all_number_groups_are_exactly_present)
293+
return matcher._check_number_grouping_is_valid(numobj, candidate,
294+
_all_number_groups_are_exactly_present)
295295

296296

297297
def _all_number_groups_are_exactly_present(numobj, normalized_candidate, formatted_number_groups):
@@ -334,43 +334,32 @@ def _all_number_groups_are_exactly_present(numobj, normalized_candidate, formatt
334334
candidate_groups[candidate_number_group_index].endswith(formatted_number_groups[0]))
335335

336336

337-
def _get_national_number_groups(numobj, formatting_pattern=None):
337+
def _get_national_number_groups_without_pattern(numobj):
338338
"""Helper method to get the national-number part of a number, formatted without any national
339-
prefix, and return it as a set of digit blocks that would be formatted together."""
340-
if formatting_pattern is None:
341-
# This will be in the format +CC-DG;ext=EXT where DG represents groups of digits.
342-
rfc3966_format = format_number(numobj, PhoneNumberFormat.RFC3966)
343-
# We remove the extension part from the formatted string before splitting
344-
# it into different groups.
345-
end_index = rfc3966_format.find(U_SEMICOLON)
346-
if end_index < 0:
347-
end_index = len(rfc3966_format)
348-
349-
# The country-code will have a '-' following it.
350-
start_index = rfc3966_format.find(U_DASH) + 1
351-
return rfc3966_format[start_index:end_index].split(U_DASH)
352-
else:
353-
# We format the NSN only, and split that according to the separator.
354-
nsn = national_significant_number(numobj)
355-
return _format_nsn_using_pattern(nsn, formatting_pattern,
356-
PhoneNumberFormat.RFC3966).split(U_DASH)
357-
358-
359-
def _check_number_grouping_is_valid(numobj, candidate, checker):
360-
# TODO: Evaluate how this works for other locales (testing has been
361-
# limited to NANPA regions) and optimise if necessary.
362-
normalized_candidate = normalize_digits_only(candidate, True) # keep non-digits
363-
formatted_number_groups = _get_national_number_groups(numobj, None)
364-
if checker(numobj, normalized_candidate, formatted_number_groups):
365-
return True
366-
# If this didn't pass, see if there are any alternate formats, and try them instead.
367-
alternate_formats = _ALT_NUMBER_FORMATS.get(numobj.country_code, None)
368-
if alternate_formats is not None:
369-
for alternate_format in alternate_formats:
370-
formatted_number_groups = _get_national_number_groups(numobj, alternate_format)
371-
if checker(numobj, normalized_candidate, formatted_number_groups):
372-
return True
373-
return False
339+
prefix, and return it as a set of digit blocks that would be formatted together following
340+
standard formatting rules."""
341+
# This will be in the format +CC-DG1-DG2-DGX;ext=EXT where DG1..DGX represents groups of
342+
# digits.
343+
rfc3966_format = format_number(numobj, PhoneNumberFormat.RFC3966)
344+
# We remove the extension part from the formatted string before splitting
345+
# it into different groups.
346+
end_index = rfc3966_format.find(U_SEMICOLON)
347+
if end_index < 0:
348+
end_index = len(rfc3966_format)
349+
350+
# The country-code will have a '-' following it.
351+
start_index = rfc3966_format.find(U_DASH) + 1
352+
return rfc3966_format[start_index:end_index].split(U_DASH)
353+
354+
355+
def _get_national_number_groups(numobj, formatting_pattern):
356+
"""Helper method to get the national-number part of a number, formatted without any national
357+
prefix, and return it as a set of digit blocks that should be formatted together according to
358+
the formatting pattern passed in."""
359+
# If a format is provided, we format the NSN only, and split that according to the separator.
360+
nsn = national_significant_number(numobj)
361+
return _format_nsn_using_pattern(nsn, formatting_pattern,
362+
PhoneNumberFormat.RFC3966).split(U_DASH)
374363

375364

376365
def _contains_more_than_one_slash_in_national_number(numobj, candidate):
@@ -662,7 +651,7 @@ def _parse_and_verify(self, candidate, offset):
662651
return None
663652

664653
numobj = parse(candidate, self.preferred_region, keep_raw_input=True)
665-
if _verify(self.leniency, numobj, candidate):
654+
if _verify(self.leniency, numobj, candidate, self):
666655
# We used parse(keep_raw_input=True) to create this number,
667656
# but for now we don't return the extra values parsed.
668657
# TODO: stop clearing all values here and switch all users
@@ -677,6 +666,28 @@ def _parse_and_verify(self, candidate, offset):
677666
pass
678667
return None
679668

669+
def _check_number_grouping_is_valid(self, numobj, candidate, checker):
670+
normalized_candidate = normalize_digits_only(candidate, True) # keep non-digits
671+
formatted_number_groups = _get_national_number_groups_without_pattern(numobj)
672+
if checker(numobj, normalized_candidate, formatted_number_groups):
673+
return True
674+
# If this didn't pass, see if there are any alternate formats that match, and try them instead.
675+
alternate_formats = _ALT_NUMBER_FORMATS.get(numobj.country_code, None)
676+
nsn = national_significant_number(numobj)
677+
if alternate_formats is not None:
678+
for alternate_format in alternate_formats:
679+
if len(alternate_format.leading_digits_pattern) > 0:
680+
# There is only one leading digits pattern for alternate formats.
681+
pattern = re.compile(alternate_format.leading_digits_pattern[0])
682+
if not pattern.match(nsn):
683+
# Leading digits don't match; try another one.
684+
continue
685+
formatted_number_groups = _get_national_number_groups(numobj, alternate_format)
686+
if checker(numobj, normalized_candidate, formatted_number_groups):
687+
return True
688+
return False
689+
690+
680691
def has_next(self):
681692
"""Indicates whether there is another match available"""
682693
if self._state == PhoneNumberMatcher._NOT_READY:

python/tests/phonenumbermatchertest.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ def __str__(self):
171171
NumberTest("03 0 -3 2 23 12 34", "DE"),
172172
NumberTest("(0)3 0 -3 2 23 12 34", "DE"),
173173
NumberTest("0 3 0 -3 2 23 12 34", "DE"),
174+
# Fits an alternate pattern, but the leading digits don't match.
175+
NumberTest("+52 332 123 23 23", "MX"),
174176
]
175177

176178
# Strings with number-like things that should only be found up to and
@@ -973,7 +975,7 @@ def testInternals(self):
973975
self.assertRaises(Exception, _limit, *(1, 0))
974976
self.assertRaises(Exception, _limit, *(2, 1))
975977
number = PhoneNumber(country_code=44, national_number=7912345678)
976-
self.assertRaises(Exception, _verify, *(99, number, "12345678"))
978+
self.assertRaises(Exception, _verify, *(99, number, "12345678", None))
977979
self.assertRaises(ValueError, PhoneNumberMatcher, *("text", "US"), **{"leniency": None})
978980
self.assertRaises(ValueError, PhoneNumberMatcher, *("text", "US"), **{"max_tries": -2})
979981
# Invalid country looks like national prefix is present (no way to tell)

0 commit comments

Comments
 (0)