3434from .phonenumberutil import _PLUS_SIGN , _PLUS_CHARS_PATTERN
3535from .phonenumberutil import _extract_country_code , region_code_for_country_code
3636from .phonenumberutil import country_code_for_region
37+ from .phonenumberutil import _formatting_rule_has_first_group_only
3738
39+ # Character used when appropriate to separate a prefix, such as a long NDD or
40+ # a country calling code, from the national number.
41+ _SEPARATOR_BEFORE_NATIONAL_NUMBER = U_SPACE
3842_EMPTY_METADATA = PhoneMetadata (id = unicod ("" ),
3943 international_prefix = unicod ("NA" ),
4044 register = False )
4953# two-digit number, since the phone number can be as long as 15 digits.
5054_STANDALONE_DIGIT_PATTERN = re .compile (unicod ("\\ d(?=[^,}][^,}])" ))
5155
56+ # A set of characters that, if found in a national prefix formatting rules, are an indicator to
57+ # us that we should separate the national prefix from the number when formatting.
58+ _NATIONAL_PREFIX_SEPARATORS_PATTERN = re .compile ("[- ]" )
59+
5260# A pattern that is used to determine if a number_format under
5361# available_formats is eligible to be used by the AYTF. It is eligible when
5462# the format element under number_format contains groups of the dollar sign
@@ -110,6 +118,10 @@ def _maybe_create_new_template(self):
110118 return False
111119 if self ._create_formatting_template (number_format ):
112120 self ._current_formatting_pattern = pattern
121+ if number_format .national_prefix_formatting_rule is None :
122+ self ._should_add_space_after_national_prefix = False
123+ else :
124+ self ._should_add_space_after_national_prefix = bool (_NATIONAL_PREFIX_SEPARATORS_PATTERN .search (number_format .national_prefix_formatting_rule ))
113125 # With a new formatting template, the matched position using
114126 # the old template needs to be reset.
115127 self ._last_match_position = 0
@@ -123,14 +135,18 @@ def _maybe_create_new_template(self):
123135 return False
124136
125137 def _get_available_formats (self , leading_three_digits ):
126- if (self ._is_international_formatting and
138+ if (self ._is_complete_number and
127139 len (self ._current_metadata .intl_number_format ) > 0 ):
128140 format_list = self ._current_metadata .intl_number_format
129141 else :
130142 format_list = self ._current_metadata .number_format
143+ national_prefix_is_used_by_country = (self ._current_metadata .national_prefix is not None )
131144 for this_format in format_list :
132- if self ._is_format_eligible (this_format .format ):
133- self ._possible_formats .append (this_format )
145+ if (not national_prefix_is_used_by_country or self ._is_complete_number or
146+ this_format .national_prefix_optional_when_formatting or
147+ _formatting_rule_has_first_group_only (this_format .national_prefix_formatting_rule )):
148+ if self ._is_format_eligible (this_format .format ):
149+ self ._possible_formats .append (this_format )
134150 self ._narrow_down_possible_formats (leading_three_digits )
135151
136152 def _is_format_eligible (self , format ):
@@ -210,6 +226,7 @@ def _clear(self):
210226 # inserted). For example, this can contain IDD, country code, and/or
211227 # NDD, etc.
212228 self ._prefix_before_national_number = U_EMPTY_STRING
229+ self ._should_add_space_after_national_prefix = False
213230 # This contains the national prefix that has been extracted. It
214231 # contains only digits without formatting.
215232 self ._national_prefix_extracted = U_EMPTY_STRING
@@ -228,7 +245,11 @@ def _clear(self):
228245 # most recently invoked, as found in the original sequence of
229246 # characters the user entered.
230247 self ._original_position = 0
231- self ._is_international_formatting = False
248+ # This is set to true when we know the user is entering a full
249+ # national significant number, since we have either detected a
250+ # national prefix or an international dialing prefix. When this is
251+ # true, we will no longer use local number formatting patterns.
252+ self ._is_complete_number = False
232253 self ._is_expecting_country_calling_code = False
233254 self ._possible_formats = []
234255
@@ -284,8 +305,11 @@ def input_digit(self, next_char, remember_position=False):
284305 return self ._current_output
285306 elif self ._able_to_extract_longer_ndd ():
286307 # Add an additional space to separate long NDD and national
287- # significant number for readability.
288- self ._prefix_before_national_number += U_SPACE
308+ # significant number for readability. We don't set
309+ # should_add_space_after_national_prefix to True, since we don't
310+ # want this to change later when we choose formatting
311+ # templates.
312+ self ._prefix_before_national_number += _SEPARATOR_BEFORE_NATIONAL_NUMBER
289313 self ._current_output = self ._attempt_to_choose_pattern_with_prefix_extracted ()
290314 return self ._current_output
291315
@@ -313,8 +337,7 @@ def input_digit(self, next_char, remember_position=False):
313337 self ._current_output = self ._prefix_before_national_number + self ._national_number
314338 return self ._current_output
315339
316- if len (self ._possible_formats ) > 0 :
317- # The formatting pattern is already chosen.
340+ if len (self ._possible_formats ) > 0 : # The formatting pattern is already chosen.
318341 temp_national_number = self ._input_digit_helper (next_char )
319342 # See if the accrued digits can be formatted properly already. If
320343 # not, use the results from input_digit_helper, which does
@@ -328,7 +351,7 @@ def input_digit(self, next_char, remember_position=False):
328351 self ._current_output = self ._input_accrued_national_number ()
329352 return self ._current_output
330353 if self ._able_to_format :
331- self ._current_output = self ._prefix_before_national_number + temp_national_number
354+ self ._current_output = self ._append_national_number ( temp_national_number )
332355 return self ._current_output
333356 else :
334357 self ._current_output = self ._accrued_input
@@ -365,11 +388,18 @@ def _is_digit_or_leading_plus_sign(self, next_char):
365388 fullmatch (_PLUS_CHARS_PATTERN , next_char )))
366389
367390 def _attempt_to_format_accrued_digits (self ):
368- for num_format in self ._possible_formats :
369- num_re = re .compile (num_format .pattern )
391+ """Check to see if there is an exact pattern match for these digits. If so, we should use this
392+ instead of any other formatting template whose leadingDigitsPattern also matches the input.
393+ """
394+ for number_format in self ._possible_formats :
395+ num_re = re .compile (number_format .pattern )
370396 if fullmatch (num_re , self ._national_number ):
371- formatted_number = re .sub (num_re , num_format .format , self ._national_number )
372- return self ._prefix_before_national_number + formatted_number
397+ if number_format .national_prefix_formatting_rule is None :
398+ self ._should_add_space_after_national_prefix = False
399+ else :
400+ self ._should_add_space_after_national_prefix = bool (_NATIONAL_PREFIX_SEPARATORS_PATTERN .search (number_format .national_prefix_formatting_rule ))
401+ formatted_number = re .sub (num_re , number_format .format , self ._national_number )
402+ return self ._append_national_number (formatted_number )
373403 return U_EMPTY_STRING
374404
375405 def get_remembered_position (self ):
@@ -388,6 +418,23 @@ def get_remembered_position(self):
388418 current_output_index += 1
389419 return current_output_index
390420
421+ def _append_national_number (self , national_number ):
422+ """Combines the national number with any prefix (IDD/+ and country
423+ code or national prefix) that was collected. A space will be inserted
424+ between them if the current formatting template indicates this to be
425+ suitable.
426+ """
427+ prefix_before_nn_len = len (self ._prefix_before_national_number )
428+ if (self ._should_add_space_after_national_prefix and prefix_before_nn_len > 0 and
429+ self ._prefix_before_national_number [- 1 ] != _SEPARATOR_BEFORE_NATIONAL_NUMBER ):
430+ # We want to add a space after the national prefix if the national
431+ # prefix formatting rule indicates that this would normally be
432+ # done, with the exception of the case where we already appended a
433+ # space because the NDD was surprisingly long.
434+ return self ._prefix_before_national_number + _SEPARATOR_BEFORE_NATIONAL_NUMBER + national_number
435+ else :
436+ return self ._prefix_before_national_number + national_number
437+
391438 def _attempt_to_choose_formatting_pattern (self ):
392439 """Attempts to set the formatting template and returns a string which
393440 contains the formatted version of the digits entered so far."""
@@ -400,7 +447,7 @@ def _attempt_to_choose_formatting_pattern(self):
400447 else :
401448 return self ._accrued_input
402449 else :
403- return self ._prefix_before_national_number + self ._national_number
450+ return self ._append_national_number ( self ._national_number )
404451
405452 def _input_accrued_national_number (self ):
406453 """Invokes input_digit_helper on each digit of the national number
@@ -411,18 +458,30 @@ def _input_accrued_national_number(self):
411458 for ii in range (length_of_national_number ):
412459 temp_national_number = self ._input_digit_helper (self ._national_number [ii ])
413460 if self ._able_to_format :
414- return self ._prefix_before_national_number + temp_national_number
461+ return self ._append_national_number ( temp_national_number )
415462 else :
416463 return self ._accrued_input
417464 else :
418465 return self ._prefix_before_national_number
419466
467+ def _is_nanpa_number_with_national_prefix (self ):
468+ """Returns true if the current country is a NANPA country and the
469+ national number begins with the national prefix.
470+ """
471+ # For NANPA numbers beginning with 1[2-9], treat the 1 as the national
472+ # prefix. The reason is that national significant numbers in NANPA
473+ # always start with [2-9] after the national prefix. Numbers
474+ # beginning with 1[01] can only be short/emergency numbers, which
475+ # don't need the national prefix.
476+ return (self ._current_metadata .country_code == 1 and self ._national_number [0 ] == '1' and
477+ self ._national_number [1 ] != '0' and self ._national_number [1 ] != '1' )
478+
420479 def _remove_national_prefix_from_national_number (self ):
421480 start_of_national_number = 0
422- if self ._current_metadata . country_code == 1 and self . _national_number [ 0 ] == unicod ( '1' ):
481+ if self ._is_nanpa_number_with_national_prefix ( ):
423482 start_of_national_number = 1
424- self ._prefix_before_national_number += unicod ("1 " )
425- self ._is_international_formatting = True
483+ self ._prefix_before_national_number += unicod ("1" ) + _SEPARATOR_BEFORE_NATIONAL_NUMBER
484+ self ._is_complete_number = True
426485 elif self ._current_metadata .national_prefix_for_parsing is not None :
427486 npp_re = re .compile (self ._current_metadata .national_prefix_for_parsing )
428487 m = npp_re .match (self ._national_number )
@@ -431,7 +490,7 @@ def _remove_national_prefix_from_national_number(self):
431490 # formatting rules instead of national ones, because national
432491 # formatting rules could contain local formatting rules for
433492 # numbers entered without area code.
434- self ._is_international_formatting = True
493+ self ._is_complete_number = True
435494 start_of_national_number = m .end ()
436495 self ._prefix_before_national_number += self ._national_number [:start_of_national_number ]
437496 national_prefix = self ._national_number [:start_of_national_number ]
@@ -450,12 +509,12 @@ def _attempt_to_extract_idd(self):
450509 unicod ("|" ) + self ._current_metadata .international_prefix )
451510 idd_match = international_prefix .match (self ._accrued_input_without_formatting )
452511 if idd_match :
453- self ._is_international_formatting = True
512+ self ._is_complete_number = True
454513 start_of_country_calling_code = idd_match .end ()
455514 self ._national_number = self ._accrued_input_without_formatting [start_of_country_calling_code :]
456515 self ._prefix_before_national_number = self ._accrued_input_without_formatting [:start_of_country_calling_code ]
457516 if self ._accrued_input_without_formatting [0 ] != _PLUS_SIGN :
458- self ._prefix_before_national_number += U_SPACE
517+ self ._prefix_before_national_number += _SEPARATOR_BEFORE_NATIONAL_NUMBER
459518 return True
460519 return False
461520
@@ -482,7 +541,7 @@ def _attempt_to_extract_ccc(self):
482541 self ._current_metadata = _get_metadata_for_region (new_region_code )
483542
484543 self ._prefix_before_national_number += str (country_code )
485- self ._prefix_before_national_number += U_SPACE
544+ self ._prefix_before_national_number += _SEPARATOR_BEFORE_NATIONAL_NUMBER
486545 return True
487546
488547 def _normalize_and_accrue_digits_and_plus_sign (self , next_char , remember_position ):
0 commit comments