Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/phonenumbers/asyoutypeformatter.py: 10%
302 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1"""A formatter which formats phone numbers as they are entered.
3An AsYouTypeFormatter can be created by invoking
4AsYouTypeFormatter(region_code). After that digits can be added by invoking
5input_digit() on the formatter instance, and the partially formatted phone
6number will be returned each time a digit is added. clear() should be invoked
7before a new number needs to be formatted.
9See the unit tests for more details on how the formatter is to be used.
10"""
12# Based on original Java code:
13# java/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java
14# Copyright (C) 2009-2011 The Libphonenumber Authors
15#
16# Licensed under the Apache License, Version 2.0 (the "License");
17# you may not use this file except in compliance with the License.
18# You may obtain a copy of the License at
19#
20# http://www.apache.org/licenses/LICENSE-2.0
21#
22# Unless required by applicable law or agreed to in writing, software
23# distributed under the License is distributed on an "AS IS" BASIS,
24# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25# See the License for the specific language governing permissions and
26# limitations under the License.
27import re
29from .util import u, unicod, U_EMPTY_STRING, U_SPACE
30from .unicode_util import digit as unicode_digit
31from .re_util import fullmatch
32from .phonemetadata import PhoneMetadata, REGION_CODE_FOR_NON_GEO_ENTITY
33from .phonenumberutil import _VALID_PUNCTUATION
34from .phonenumberutil import _PLUS_SIGN, _PLUS_CHARS_PATTERN
35from .phonenumberutil import _extract_country_code, region_code_for_country_code
36from .phonenumberutil import country_code_for_region, normalize_diallable_chars_only
37from .phonenumberutil import _formatting_rule_has_first_group_only
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
42_EMPTY_METADATA = PhoneMetadata(id=unicod(""),
43 international_prefix=unicod("NA"),
44 register=False)
46# A set of characters that, if found in a national prefix formatting rules, are an indicator to
47# us that we should separate the national prefix from the number when formatting.
48_NATIONAL_PREFIX_SEPARATORS_PATTERN = re.compile("[- ]")
50# A pattern that is used to determine if a number_format under
51# available_formats is eligible to be used by the AYTF. It is eligible when
52# the format element under number_format contains groups of the dollar sign
53# followed by a single digit, separated by valid phone number
54# punctuation. This prevents invalid punctuation (such as the star sign in
55# Israeli star numbers) getting into the output of the AYTF. We require that
56# the first group is present in the output pattern to ensure no data is lost
57# while formatting; when we format as you type, this should always be the case.
58_ELIGIBLE_FORMAT_PATTERN = re.compile(unicod("[") + _VALID_PUNCTUATION + unicod("]*") +
59 unicod("\\\\1") + unicod("[") + _VALID_PUNCTUATION + unicod("]*") +
60 unicod("(\\\\\\d") + unicod("[") + _VALID_PUNCTUATION + unicod("]*)*"))
62# This is the minimum length of national number accrued that is required to
63# trigger the formatter. The first element of the leading_digits_pattern of each
64# number_format contains a regular expression that matches up to this number of
65# digits.
66_MIN_LEADING_DIGITS_LENGTH = 3
67# The digits that have not been entered yet will be represented by a \u2008,
68# the punctuation space.
69_DIGIT_PLACEHOLDER = u("\u2008")
70_DIGIT_PATTERN = re.compile(_DIGIT_PLACEHOLDER)
73def _get_metadata_for_region(region_code):
74 """The metadata needed by this class is the same for all regions
75 sharing the same country calling code. Therefore, we return the
76 metadata for "main" region for this country calling code."""
77 country_calling_code = country_code_for_region(region_code)
78 main_country = region_code_for_country_code(country_calling_code)
79 # Set to a default instance of the metadata. This allows us to
80 # function with an incorrect region code, even if formatting only
81 # works for numbers specified with "+".
82 return PhoneMetadata.metadata_for_region(main_country, _EMPTY_METADATA)
85class AsYouTypeFormatter(object):
86 def __init__(self, region_code):
87 """Gets an AsYouTypeFormatter for the specific region.
89 Arguments:
90 region_code -- The region where the phone number is being entered
92 Return an AsYouTypeFormatter} object, which could be used to format
93 phone numbers in the specific region "as you type"
94 """
95 self._clear()
96 self._default_country = region_code.upper()
97 self._current_metadata = _get_metadata_for_region(self._default_country)
98 self._default_metadata = self._current_metadata
100 def _maybe_create_new_template(self):
101 """Returns True if a new template is created as opposed to reusing the existing template.
103 When there are multiple available formats, the formatter uses the
104 first format where a formatting template could be created.
105 """
106 ii = 0
107 while ii < len(self._possible_formats):
108 number_format = self._possible_formats[ii]
109 pattern = number_format.pattern
110 if self._current_formatting_pattern == pattern:
111 return False
112 if self._create_formatting_template(number_format):
113 self._current_formatting_pattern = pattern
114 if number_format.national_prefix_formatting_rule is None:
115 self._should_add_space_after_national_prefix = False
116 else:
117 self._should_add_space_after_national_prefix = bool(_NATIONAL_PREFIX_SEPARATORS_PATTERN.search(number_format.national_prefix_formatting_rule))
118 # With a new formatting template, the matched position using
119 # the old template needs to be reset.
120 self._last_match_position = 0
121 return True
122 else:
123 # Remove the current number format from _possible_formats
124 del self._possible_formats[ii]
125 ii -= 1
126 ii += 1
127 self._able_to_format = False
128 return False
130 def _get_available_formats(self, leading_digits):
131 # First decide whether we should use international or national number rules.
132 is_international_number = (self._is_complete_number and len(self._extracted_national_prefix) == 0)
133 if (is_international_number and
134 len(self._current_metadata.intl_number_format) > 0):
135 format_list = self._current_metadata.intl_number_format
136 else:
137 format_list = self._current_metadata.number_format
138 for this_format in format_list:
139 # Discard a few formats that we know are not relevant based on the presence of the national
140 # prefix.
141 if (len(self._extracted_national_prefix) > 0 and
142 _formatting_rule_has_first_group_only(this_format.national_prefix_formatting_rule) and
143 not this_format.national_prefix_optional_when_formatting and
144 not (this_format.domestic_carrier_code_formatting_rule is not None)):
145 # If it is a national number that had a national prefix, any rules that aren't valid with a
146 # national prefix should be excluded. A rule that has a carrier-code formatting rule is
147 # kept since the national prefix might actually be an extracted carrier code - we don't
148 # distinguish between these when extracting it in the AYTF.
149 continue
150 elif (len(self._extracted_national_prefix) == 0 and
151 not self._is_complete_number and
152 not _formatting_rule_has_first_group_only(this_format.national_prefix_formatting_rule) and
153 not this_format.national_prefix_optional_when_formatting):
154 # This number was entered without a national prefix, and this formatting rule requires one,
155 # so we discard it.
156 continue
157 if fullmatch(_ELIGIBLE_FORMAT_PATTERN, this_format.format):
158 self._possible_formats.append(this_format)
159 self._narrow_down_possible_formats(leading_digits)
161 def _narrow_down_possible_formats(self, leading_digits):
162 index_of_leading_digits_pattern = len(leading_digits) - _MIN_LEADING_DIGITS_LENGTH
163 ii = 0
164 while ii < len(self._possible_formats):
165 num_format = self._possible_formats[ii]
166 ii += 1
167 if len(num_format.leading_digits_pattern) == 0:
168 # Keep everything that isn't restricted by leading digits.
169 continue
170 last_leading_digits_pattern = min(index_of_leading_digits_pattern,
171 len(num_format.leading_digits_pattern) - 1)
172 leading_digits_pattern = re.compile(num_format.leading_digits_pattern[last_leading_digits_pattern])
173 m = leading_digits_pattern.match(leading_digits)
174 if not m:
175 # remove the element we've just examined, now at (ii-1)
176 ii -= 1
177 self._possible_formats.pop(ii)
179 def _create_formatting_template(self, num_format):
180 number_pattern = num_format.pattern
181 self.formatting_template = U_EMPTY_STRING
182 temp_template = self._get_formatting_template(number_pattern, num_format.format)
183 if len(temp_template) > 0:
184 self._formatting_template = temp_template
185 return True
186 return False
188 def _get_formatting_template(self, number_pattern, number_format):
189 """Gets a formatting template which can be used to efficiently
190 format a partial number where digits are added one by one."""
191 # Create a phone number consisting only of the digit 9 that matches the
192 # number_pattern by applying the pattern to the longest_phone_number string.
193 longest_phone_number = unicod("999999999999999")
194 number_re = re.compile(number_pattern)
195 m = number_re.search(longest_phone_number) # this will always succeed
196 a_phone_number = m.group(0)
197 # No formatting template can be created if the number of digits
198 # entered so far is longer than the maximum the current formatting
199 # rule can accommodate.
200 if len(a_phone_number) < len(self._national_number):
201 return U_EMPTY_STRING
202 # Formats the number according to number_format
203 template = re.sub(number_pattern, number_format, a_phone_number)
204 # Replaces each digit with character _DIGIT_PLACEHOLDER
205 template = re.sub("9", _DIGIT_PLACEHOLDER, template)
206 return template
208 def _clear(self):
209 """Clears the internal state of the formatter, so it can be reused."""
210 self._current_output = U_EMPTY_STRING
211 self._accrued_input = U_EMPTY_STRING
212 self._accrued_input_without_formatting = U_EMPTY_STRING
213 self._formatting_template = U_EMPTY_STRING
214 self._last_match_position = 0
216 # The pattern from number_format that is currently used to create
217 # formatting_template.
218 self._current_formatting_pattern = U_EMPTY_STRING
219 # This contains anything that has been entered so far preceding the
220 # national significant number, and it is formatted (e.g. with space
221 # inserted). For example, this can contain IDD, country code, and/or
222 # NDD, etc.
223 self._prefix_before_national_number = U_EMPTY_STRING
224 self._should_add_space_after_national_prefix = False
225 # This contains the national prefix that has been extracted. It
226 # contains only digits without formatting.
227 self._extracted_national_prefix = U_EMPTY_STRING
228 self._national_number = U_EMPTY_STRING
229 # This indicates whether AsYouTypeFormatter is currently doing the
230 # formatting.
231 self._able_to_format = True
232 # Set to true when users enter their own
233 # formatting. AsYouTypeFormatter will do no formatting at all when
234 # this is set to True.
235 self._input_has_formatting = False
236 # The position of a digit upon which input_digit(remember_position=True) is
237 # most recently invoked, as found in accrued_input_without_formatting.
238 self._position_to_remember = 0
239 # The position of a digit upon which input_digit(remember_position=True) is
240 # most recently invoked, as found in the original sequence of
241 # characters the user entered.
242 self._original_position = 0
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
248 self._is_expecting_country_calling_code = False
249 self._possible_formats = []
251 def clear(self):
252 """Clears the internal state of the formatter, so it can be reused."""
253 self._clear()
254 if self._current_metadata != self._default_metadata:
255 self._current_metadata = _get_metadata_for_region(self._default_country)
257 def input_digit(self, next_char, remember_position=False):
258 """Formats a phone number on-the-fly as each digit is entered.
260 If remember_position is set, remembers the position where next_char is
261 inserted, so that it can be retrieved later by using
262 get_remembered_position. The remembered position will be automatically
263 adjusted if additional formatting characters are later
264 inserted/removed in front of next_char.
266 Arguments:
268 next_char -- The most recently entered digit of a phone
269 number. Formatting characters are allowed, but as soon as they
270 are encountered this method formats the number as entered and
271 not "as you type" anymore. Full width digits and Arabic-indic
272 digits are allowed, and will be shown as they are.
273 remember_position -- Whether to track the position where next_char is
274 inserted.
276 Returns the partially formatted phone number.
277 """
278 self._accrued_input += next_char
279 if remember_position:
280 self._original_position = len(self._accrued_input)
281 # We do formatting on-the-fly only when each character entered is
282 # either a digit, or a plus sign (accepted at the start of the number
283 # only).
284 if not self._is_digit_or_leading_plus_sign(next_char):
285 self._able_to_format = False
286 self._input_has_formatting = True
287 else:
288 next_char = self._normalize_and_accrue_digits_and_plus_sign(next_char, remember_position)
289 if not self._able_to_format:
290 # When we are unable to format because of reasons other than that
291 # formatting chars have been entered, it can be due to really long
292 # IDDs or NDDs. If that is the case, we might be able to do
293 # formatting again after extracting them.
294 if self._input_has_formatting:
295 self._current_output = self._accrued_input
296 return self._current_output
297 elif self._attempt_to_extract_idd():
298 if self._attempt_to_extract_ccc():
299 self._current_output = self._attempt_to_choose_pattern_with_prefix_extracted()
300 return self._current_output
301 elif self._able_to_extract_longer_ndd():
302 # Add an additional space to separate long NDD and national
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
308 self._current_output = self._attempt_to_choose_pattern_with_prefix_extracted()
309 return self._current_output
311 self._current_output = self._accrued_input
312 return self._current_output
314 # We start to attempt to format only when at least
315 # MIN_LEADING_DIGITS_LENGTH digits (the plus sign is counted as a
316 # digit as well for this purpose) have been entered.
317 len_input = len(self._accrued_input_without_formatting)
318 if len_input >= 0 and len_input <= 2:
319 self._current_output = self._accrued_input
320 return self._current_output
321 elif len_input == 3:
322 if self._attempt_to_extract_idd():
323 self._is_expecting_country_calling_code = True
324 else:
325 # No IDD or plus sign is found, might be entering in national format.
326 self._extracted_national_prefix = self._remove_national_prefix_from_national_number()
327 self._current_output = self._attempt_to_choose_formatting_pattern()
328 return self._current_output
329 if self._is_expecting_country_calling_code:
330 if self._attempt_to_extract_ccc():
331 self._is_expecting_country_calling_code = False
332 self._current_output = self._prefix_before_national_number + self._national_number
333 return self._current_output
335 if len(self._possible_formats) > 0: # The formatting patterns are already chosen.
336 temp_national_number = self._input_digit_helper(next_char)
337 # See if the accrued digits can be formatted properly already. If
338 # not, use the results from input_digit_helper, which does
339 # formatting based on the formatting pattern chosen.
340 formatted_number = self._attempt_to_format_accrued_digits()
341 if len(formatted_number) > 0:
342 self._current_output = formatted_number
343 return self._current_output
344 self._narrow_down_possible_formats(self._national_number)
345 if self._maybe_create_new_template():
346 self._current_output = self._input_accrued_national_number()
347 return self._current_output
348 if self._able_to_format:
349 self._current_output = self._append_national_number(temp_national_number)
350 return self._current_output
351 else:
352 self._current_output = self._accrued_input
353 return self._current_output
354 else:
355 self._current_output = self._attempt_to_choose_formatting_pattern()
356 return self._current_output
358 def _attempt_to_choose_pattern_with_prefix_extracted(self):
359 self._able_to_format = True
360 self._is_expecting_country_calling_code = False
361 self._possible_formats = []
362 self._last_match_position = 0
363 self._formatting_template = U_EMPTY_STRING
364 self._current_formatting_pattern = U_EMPTY_STRING
365 return self._attempt_to_choose_formatting_pattern()
367 # Some national prefixes are a substring of others. If extracting the
368 # shorter NDD doesn't result in a number we can format, we try to see if
369 # we can extract a longer version here.
370 def _able_to_extract_longer_ndd(self):
371 if len(self._extracted_national_prefix) > 0:
372 # Put the extracted NDD back to the national number before
373 # attempting to extract a new NDD.
374 self._national_number = self._extracted_national_prefix + self._national_number
375 # Remove the previously extracted NDD from
376 # prefixBeforeNationalNumber. We cannot simply set it to empty
377 # string because people sometimes incorrectly enter national
378 # prefix after the country code, e.g. +44 (0)20-1234-5678.
379 index_of_previous_ndd = self._prefix_before_national_number.rfind(self._extracted_national_prefix)
380 self._prefix_before_national_number = self._prefix_before_national_number[:index_of_previous_ndd]
381 return self._extracted_national_prefix != self._remove_national_prefix_from_national_number()
383 def _is_digit_or_leading_plus_sign(self, next_char):
384 return (next_char.isdigit() or
385 (len(self._accrued_input) == 1 and
386 fullmatch(_PLUS_CHARS_PATTERN, next_char)))
388 def _attempt_to_format_accrued_digits(self):
389 """Checks to see if there is an exact pattern match for these digits. If so, we should use this
390 instead of any other formatting template whose leadingDigitsPattern also matches the input.
391 """
392 for number_format in self._possible_formats:
393 num_re = re.compile(number_format.pattern)
394 if fullmatch(num_re, self._national_number):
395 if number_format.national_prefix_formatting_rule is None:
396 self._should_add_space_after_national_prefix = False
397 else:
398 self._should_add_space_after_national_prefix = bool(_NATIONAL_PREFIX_SEPARATORS_PATTERN.search(number_format.national_prefix_formatting_rule))
399 formatted_number = re.sub(num_re, number_format.format, self._national_number)
400 # Check that we did not remove nor add any extra digits when we matched
401 # this formatting pattern. This usually happens after we entered the last
402 # digit during AYTF. Eg: In case of MX, we swallow mobile token (1) when
403 # formatted but AYTF should retain all the number entered and not change
404 # in order to match a format (of same leading digits and length) display
405 # in that way.
406 full_output = self._append_national_number(formatted_number)
407 formatted_number_digits_only = normalize_diallable_chars_only(full_output)
408 if formatted_number_digits_only == self._accrued_input_without_formatting:
409 # If it's the same (i.e entered number and format is same), then it's
410 # safe to return this in formatted number as nothing is lost / added.
411 return full_output
412 return U_EMPTY_STRING
414 def get_remembered_position(self):
415 """Returns the current position in the partially formatted phone
416 number of the character which was previously passed in as the
417 parameter of input_digit(remember_position=True)."""
418 if not self._able_to_format:
419 return self._original_position
420 accrued_input_index = 0
421 current_output_index = 0
422 while (accrued_input_index < self._position_to_remember and
423 current_output_index < len(self._current_output)):
424 if (self._accrued_input_without_formatting[accrued_input_index] ==
425 self._current_output[current_output_index]):
426 accrued_input_index += 1
427 current_output_index += 1
428 return current_output_index
430 def _append_national_number(self, national_number):
431 """Combines the national number with any prefix (IDD/+ and country
432 code or national prefix) that was collected. A space will be inserted
433 between them if the current formatting template indicates this to be
434 suitable.
435 """
436 prefix_before_nn_len = len(self._prefix_before_national_number)
437 if (self._should_add_space_after_national_prefix and prefix_before_nn_len > 0 and
438 self._prefix_before_national_number[-1] != _SEPARATOR_BEFORE_NATIONAL_NUMBER):
439 # We want to add a space after the national prefix if the national
440 # prefix formatting rule indicates that this would normally be
441 # done, with the exception of the case where we already appended a
442 # space because the NDD was surprisingly long.
443 return self._prefix_before_national_number + _SEPARATOR_BEFORE_NATIONAL_NUMBER + national_number
444 else:
445 return self._prefix_before_national_number + national_number
447 def _attempt_to_choose_formatting_pattern(self):
448 """Attempts to set the formatting template and returns a string which
449 contains the formatted version of the digits entered so far."""
450 # We start to attempt to format only when at least MIN_LEADING_DIGITS_LENGTH digits of national
451 # number (excluding national prefix) have been entered.
452 if len(self._national_number) >= _MIN_LEADING_DIGITS_LENGTH:
453 self._get_available_formats(self._national_number)
454 # See if the accrued digits can be formatted properly already.
455 formatted_number = self._attempt_to_format_accrued_digits()
456 if len(formatted_number) > 0:
457 return formatted_number
458 if self._maybe_create_new_template():
459 return self._input_accrued_national_number()
460 else:
461 return self._accrued_input
462 else:
463 return self._append_national_number(self._national_number)
465 def _input_accrued_national_number(self):
466 """Invokes input_digit_helper on each digit of the national number
467 accrued, and returns a formatted string in the end."""
468 length_of_national_number = len(self._national_number)
469 if length_of_national_number > 0:
470 temp_national_number = U_EMPTY_STRING
471 for ii in range(length_of_national_number):
472 temp_national_number = self._input_digit_helper(self._national_number[ii])
473 if self._able_to_format:
474 return self._append_national_number(temp_national_number)
475 else:
476 return self._accrued_input
477 else:
478 return self._prefix_before_national_number
480 def _is_nanpa_number_with_national_prefix(self):
481 """Returns true if the current country is a NANPA country and the
482 national number begins with the national prefix.
483 """
484 # For NANPA numbers beginning with 1[2-9], treat the 1 as the national
485 # prefix. The reason is that national significant numbers in NANPA
486 # always start with [2-9] after the national prefix. Numbers
487 # beginning with 1[01] can only be short/emergency numbers, which
488 # don't need the national prefix.
489 return (self._current_metadata.country_code == 1 and self._national_number[0] == '1' and
490 self._national_number[1] != '0' and self._national_number[1] != '1')
492 def _remove_national_prefix_from_national_number(self):
493 start_of_national_number = 0
494 if self._is_nanpa_number_with_national_prefix():
495 start_of_national_number = 1
496 self._prefix_before_national_number += unicod("1") + _SEPARATOR_BEFORE_NATIONAL_NUMBER
497 self._is_complete_number = True
498 elif self._current_metadata.national_prefix_for_parsing is not None:
499 npp_re = re.compile(self._current_metadata.national_prefix_for_parsing)
500 m = npp_re.match(self._national_number)
501 # Since some national prefix patterns are entirely optional, check
502 # that a national prefix could actually be extracted.
503 if m and m.end() > 0:
504 # When the national prefix is detected, we use international
505 # formatting rules instead of national ones, because national
506 # formatting rules could contain local formatting rules for
507 # numbers entered without area code.
508 self._is_complete_number = True
509 start_of_national_number = m.end()
510 self._prefix_before_national_number += self._national_number[:start_of_national_number]
511 national_prefix = self._national_number[:start_of_national_number]
512 self._national_number = self._national_number[start_of_national_number:]
513 return national_prefix
515 def _attempt_to_extract_idd(self):
516 """Extracts IDD and plus sign to self._prefix_before_national_number
517 when they are available, and places the remaining input into
518 _national_number.
520 Returns True when accrued_input_without_formatting begins with the plus sign or valid IDD for
521 default_country.
522 """
523 international_prefix = re.compile(unicod("\\") + _PLUS_SIGN + unicod("|") +
524 (self._current_metadata.international_prefix or U_EMPTY_STRING))
525 idd_match = international_prefix.match(self._accrued_input_without_formatting)
526 if idd_match:
527 self._is_complete_number = True
528 start_of_country_calling_code = idd_match.end()
529 self._national_number = self._accrued_input_without_formatting[start_of_country_calling_code:]
530 self._prefix_before_national_number = self._accrued_input_without_formatting[:start_of_country_calling_code]
531 if self._accrued_input_without_formatting[0] != _PLUS_SIGN:
532 self._prefix_before_national_number += _SEPARATOR_BEFORE_NATIONAL_NUMBER
533 return True
534 return False
536 def _attempt_to_extract_ccc(self):
537 """Extracts the country calling code from the beginning of
538 _national_number to _prefix_before_national_number when they are
539 available, and places the remaining input into _national_number.
541 Returns True when a valid country calling code can be found.
542 """
543 if len(self._national_number) == 0:
544 return False
546 country_code, number_without_ccc = _extract_country_code(self._national_number)
547 if country_code == 0:
548 return False
550 self._national_number = number_without_ccc
551 new_region_code = region_code_for_country_code(country_code)
552 if new_region_code == REGION_CODE_FOR_NON_GEO_ENTITY:
553 self._current_metadata = PhoneMetadata.metadata_for_nongeo_region(country_code)
554 elif new_region_code != self._default_country:
555 self._current_metadata = _get_metadata_for_region(new_region_code)
557 self._prefix_before_national_number += str(country_code)
558 self._prefix_before_national_number += _SEPARATOR_BEFORE_NATIONAL_NUMBER
559 # When we have successfully extracted the IDD, the previously
560 # extracted NDD should be cleared because it is no longer valid.
561 self._extracted_national_prefix = U_EMPTY_STRING
562 return True
564 def _normalize_and_accrue_digits_and_plus_sign(self, next_char, remember_position):
565 """Accrues digits and the plus sign to
566 _accrued_input_without_formatting for later use. If next_char contains
567 a digit in non-ASCII format (e.g. the full-width version of digits),
568 it is first normalized to the ASCII version. The return value is
569 next_char itself, or its normalized version, if next_char is a digit
570 in non-ASCII format. This method assumes its input is either a digit
571 or the plus sign."""
572 if next_char == _PLUS_SIGN:
573 normalized_char = next_char
574 self._accrued_input_without_formatting += next_char
575 else:
576 next_digit = unicode_digit(next_char, -1)
577 if next_digit != -1:
578 normalized_char = unicod(next_digit)
579 else: # pragma no cover
580 normalized_char = next_char
581 self._accrued_input_without_formatting += normalized_char
582 self._national_number += normalized_char
583 if remember_position:
584 self._position_to_remember = len(self._accrued_input_without_formatting)
585 return normalized_char
587 def _input_digit_helper(self, next_char):
588 # Note that formattingTemplate is not guaranteed to have a value, it
589 # could be empty, e.g. when the next digit is entered after extracting
590 # an IDD or NDD.
591 digit_match = _DIGIT_PATTERN.search(self._formatting_template, self._last_match_position)
592 if digit_match:
593 # Reset to search for _DIGIT_PLACEHOLDER from start of string
594 digit_match = _DIGIT_PATTERN.search(self._formatting_template)
595 temp_template = re.sub(_DIGIT_PATTERN,
596 next_char,
597 self._formatting_template,
598 count=1)
599 self._formatting_template = temp_template + self._formatting_template[len(temp_template):]
600 self._last_match_position = digit_match.start()
601 return self._formatting_template[:self._last_match_position + 1]
602 else:
603 if len(self._possible_formats) == 1:
604 # More digits are entered than we could handle, and there are
605 # no other valid patterns to try.
606 self._able_to_format = False
607 # else, we just reset the formatting pattern.
608 self._current_formatting_pattern = U_EMPTY_STRING
609 return self._accrued_input