3333from .phonenumberutil import _PLUS_SIGN , _PLUS_CHARS_PATTERN
3434from .phonenumberutil import _extract_country_code , region_code_for_country_code
3535from .phonenumberutil import country_code_for_region
36+ from .phonenumberutil import _formatting_rule_has_first_group_only
3637
38+ # Character used when appropriate to separate a prefix, such as a long NDD or
39+ # a country calling code, from the national number.
40+ _SEPARATOR_BEFORE_NATIONAL_NUMBER = u' '
3741_EMPTY_METADATA = PhoneMetadata (id = u"" , international_prefix = u"NA" , register = False )
3842
3943# A pattern that is used to match character classes in regular expressions. An
4650# two-digit number, since the phone number can be as long as 15 digits.
4751_STANDALONE_DIGIT_PATTERN = re .compile (u"\\ d(?=[^,}][^,}])" )
4852
53+ # A set of characters that, if found in a national prefix formatting rules, are an indicator to
54+ # us that we should separate the national prefix from the number when formatting.
55+ _NATIONAL_PREFIX_SEPARATORS_PATTERN = re .compile ("[- ]" )
56+
4957# A pattern that is used to determine if a number_format under
5058# available_formats is eligible to be used by the AYTF. It is eligible when
5159# the format element under number_format contains groups of the dollar sign
@@ -107,6 +115,10 @@ def _maybe_create_new_template(self):
107115 return False
108116 if self ._create_formatting_template (number_format ):
109117 self ._current_formatting_pattern = pattern
118+ if number_format .national_prefix_formatting_rule is None :
119+ self ._should_add_space_after_national_prefix = False
120+ else :
121+ self ._should_add_space_after_national_prefix = bool (_NATIONAL_PREFIX_SEPARATORS_PATTERN .search (number_format .national_prefix_formatting_rule ))
110122 # With a new formatting template, the matched position using
111123 # the old template needs to be reset.
112124 self ._last_match_position = 0
@@ -120,14 +132,16 @@ def _maybe_create_new_template(self):
120132 return False
121133
122134 def _get_available_formats (self , leading_three_digits ):
123- if (self ._is_international_formatting and
135+ if (self ._is_complete_number and
124136 len (self ._current_metadata .intl_number_format ) > 0 ):
125137 format_list = self ._current_metadata .intl_number_format
126138 else :
127139 format_list = self ._current_metadata .number_format
128140 for this_format in format_list :
129- if self ._is_format_eligible (this_format .format ):
130- self ._possible_formats .append (this_format )
141+ if (self ._is_complete_number or this_format .national_prefix_optional_when_formatting or
142+ _formatting_rule_has_first_group_only (this_format .national_prefix_formatting_rule )):
143+ if self ._is_format_eligible (this_format .format ):
144+ self ._possible_formats .append (this_format )
131145 self ._narrow_down_possible_formats (leading_three_digits )
132146
133147 def _is_format_eligible (self , format ):
@@ -207,6 +221,7 @@ def _clear(self):
207221 # inserted). For example, this can contain IDD, country code, and/or
208222 # NDD, etc.
209223 self ._prefix_before_national_number = ""
224+ self ._should_add_space_after_national_prefix = False
210225 # This contains the national prefix that has been extracted. It
211226 # contains only digits without formatting.
212227 self ._national_prefix_extracted = ""
@@ -225,7 +240,11 @@ def _clear(self):
225240 # most recently invoked, as found in the original sequence of
226241 # characters the user entered.
227242 self ._original_position = 0
228- self ._is_international_formatting = False
243+ # This is set to true when we know the user is entering a full
244+ # national significant number, since we have either detected a
245+ # national prefix or an international dialing prefix. When this is
246+ # true, we will no longer use local number formatting patterns.
247+ self ._is_complete_number = False
229248 self ._is_expecting_country_calling_code = False
230249 self ._possible_formats = []
231250
@@ -281,8 +300,11 @@ def input_digit(self, next_char, remember_position=False):
281300 return self ._current_output
282301 elif self ._able_to_extract_longer_ndd ():
283302 # Add an additional space to separate long NDD and national
284- # significant number for readability.
285- self ._prefix_before_national_number += " "
303+ # significant number for readability. We don't set
304+ # should_add_space_after_national_prefix to True, since we don't
305+ # want this to change later when we choose formatting
306+ # templates.
307+ self ._prefix_before_national_number += _SEPARATOR_BEFORE_NATIONAL_NUMBER
286308 self ._current_output = self ._attempt_to_choose_pattern_with_prefix_extracted ()
287309 return self ._current_output
288310
@@ -310,8 +332,7 @@ def input_digit(self, next_char, remember_position=False):
310332 self ._current_output = self ._prefix_before_national_number + self ._national_number
311333 return self ._current_output
312334
313- if len (self ._possible_formats ) > 0 :
314- # The formatting pattern is already chosen.
335+ if len (self ._possible_formats ) > 0 : # The formatting pattern is already chosen.
315336 temp_national_number = self ._input_digit_helper (next_char )
316337 # See if the accrued digits can be formatted properly already. If
317338 # not, use the results from input_digit_helper, which does
@@ -325,7 +346,7 @@ def input_digit(self, next_char, remember_position=False):
325346 self ._current_output = self ._input_accrued_national_number ()
326347 return self ._current_output
327348 if self ._able_to_format :
328- self ._current_output = self ._prefix_before_national_number + temp_national_number
349+ self ._current_output = self ._append_national_number ( temp_national_number )
329350 return self ._current_output
330351 else :
331352 self ._current_output = self ._accrued_input
@@ -362,11 +383,18 @@ def _is_digit_or_leading_plus_sign(self, next_char):
362383 fullmatch (_PLUS_CHARS_PATTERN , next_char )))
363384
364385 def _attempt_to_format_accrued_digits (self ):
365- for num_format in self ._possible_formats :
366- num_re = re .compile (num_format .pattern )
386+ """Check to see if there is an exact pattern match for these digits. If so, we should use this
387+ instead of any other formatting template whose leadingDigitsPattern also matches the input.
388+ """
389+ for number_format in self ._possible_formats :
390+ num_re = re .compile (number_format .pattern )
367391 if fullmatch (num_re , self ._national_number ):
368- formatted_number = re .sub (num_re , num_format .format , self ._national_number )
369- return self ._prefix_before_national_number + formatted_number
392+ if number_format .national_prefix_formatting_rule is None :
393+ self ._should_add_space_after_national_prefix = False
394+ else :
395+ self ._should_add_space_after_national_prefix = bool (_NATIONAL_PREFIX_SEPARATORS_PATTERN .search (number_format .national_prefix_formatting_rule ))
396+ formatted_number = re .sub (num_re , number_format .format , self ._national_number )
397+ return self ._append_national_number (formatted_number )
370398 return ""
371399
372400 def get_remembered_position (self ):
@@ -385,6 +413,23 @@ def get_remembered_position(self):
385413 current_output_index += 1
386414 return current_output_index
387415
416+ def _append_national_number (self , national_number ):
417+ """Combines the national number with any prefix (IDD/+ and country
418+ code or national prefix) that was collected. A space will be inserted
419+ between them if the current formatting template indicates this to be
420+ suitable.
421+ """
422+ prefix_before_nn_len = len (self ._prefix_before_national_number )
423+ if (self ._should_add_space_after_national_prefix and prefix_before_nn_len > 0 and
424+ self ._prefix_before_national_number [- 1 ] != _SEPARATOR_BEFORE_NATIONAL_NUMBER ):
425+ # We want to add a space after the national prefix if the national
426+ # prefix formatting rule indicates that this would normally be
427+ # done, with the exception of the case where we already appended a
428+ # space because the NDD was surprisingly long.
429+ return self ._prefix_before_national_number + _SEPARATOR_BEFORE_NATIONAL_NUMBER + national_number
430+ else :
431+ return self ._prefix_before_national_number + national_number
432+
388433 def _attempt_to_choose_formatting_pattern (self ):
389434 """Attempts to set the formatting template and returns a string which
390435 contains the formatted version of the digits entered so far."""
@@ -397,7 +442,7 @@ def _attempt_to_choose_formatting_pattern(self):
397442 else :
398443 return self ._accrued_input
399444 else :
400- return self ._prefix_before_national_number + self ._national_number
445+ return self ._append_national_number ( self ._national_number )
401446
402447 def _input_accrued_national_number (self ):
403448 """Invokes input_digit_helper on each digit of the national number
@@ -408,18 +453,30 @@ def _input_accrued_national_number(self):
408453 for ii in xrange (length_of_national_number ):
409454 temp_national_number = self ._input_digit_helper (self ._national_number [ii ])
410455 if self ._able_to_format :
411- return self ._prefix_before_national_number + temp_national_number
456+ return self ._append_national_number ( temp_national_number )
412457 else :
413458 return self ._accrued_input
414459 else :
415460 return self ._prefix_before_national_number
416461
462+ def _is_nanpa_number_with_national_prefix (self ):
463+ """Returns true if the current country is a NANPA country and the
464+ national number begins with the national prefix.
465+ """
466+ # For NANPA numbers beginning with 1[2-9], treat the 1 as the national
467+ # prefix. The reason is that national significant numbers in NANPA
468+ # always start with [2-9] after the national prefix. Numbers
469+ # beginning with 1[01] can only be short/emergency numbers, which
470+ # don't need the national prefix.
471+ return (self ._current_metadata .country_code == 1 and self ._national_number [0 ] == '1' and
472+ self ._national_number [1 ] != '0' and self ._national_number [1 ] != '1' )
473+
417474 def _remove_national_prefix_from_national_number (self ):
418475 start_of_national_number = 0
419- if self ._current_metadata . country_code == 1 and self . _national_number [ 0 ] == '1' :
476+ if self ._is_nanpa_number_with_national_prefix () :
420477 start_of_national_number = 1
421- self ._prefix_before_national_number += "1 "
422- self ._is_international_formatting = True
478+ self ._prefix_before_national_number += "1" + _SEPARATOR_BEFORE_NATIONAL_NUMBER
479+ self ._is_complete_number = True
423480 elif self ._current_metadata .national_prefix_for_parsing is not None :
424481 npp_re = re .compile (self ._current_metadata .national_prefix_for_parsing )
425482 m = npp_re .match (self ._national_number )
@@ -428,7 +485,7 @@ def _remove_national_prefix_from_national_number(self):
428485 # formatting rules instead of national ones, because national
429486 # formatting rules could contain local formatting rules for
430487 # numbers entered without area code.
431- self ._is_international_formatting = True
488+ self ._is_complete_number = True
432489 start_of_national_number = m .end ()
433490 self ._prefix_before_national_number += self ._national_number [:start_of_national_number ]
434491 national_prefix = self ._national_number [:start_of_national_number ]
@@ -446,12 +503,12 @@ def _attempt_to_extract_idd(self):
446503 international_prefix = re .compile ("\\ " + _PLUS_SIGN + "|" + self ._current_metadata .international_prefix )
447504 idd_match = international_prefix .match (self ._accrued_input_without_formatting )
448505 if idd_match :
449- self ._is_international_formatting = True
506+ self ._is_complete_number = True
450507 start_of_country_calling_code = idd_match .end ()
451508 self ._national_number = self ._accrued_input_without_formatting [start_of_country_calling_code :]
452509 self ._prefix_before_national_number = self ._accrued_input_without_formatting [:start_of_country_calling_code ]
453510 if self ._accrued_input_without_formatting [0 ] != _PLUS_SIGN :
454- self ._prefix_before_national_number += " "
511+ self ._prefix_before_national_number += _SEPARATOR_BEFORE_NATIONAL_NUMBER
455512 return True
456513 return False
457514
@@ -478,7 +535,7 @@ def _attempt_to_extract_ccc(self):
478535 self ._current_metadata = _get_metadata_for_region (new_region_code )
479536
480537 self ._prefix_before_national_number += str (country_code )
481- self ._prefix_before_national_number += " "
538+ self ._prefix_before_national_number += _SEPARATOR_BEFORE_NATIONAL_NUMBER
482539 return True
483540
484541 def _normalize_and_accrue_digits_and_plus_sign (self , next_char , remember_position ):
0 commit comments