Skip to content

Commit 91abecb

Browse files
authored
Add API type definitions through stub files (daviddrysdale#207)
1 parent d3d5bfb commit 91abecb

20 files changed

Lines changed: 1098 additions & 3 deletions

.github/workflows/typing.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: Test type stubs
2+
on: [push, pull_request]
3+
4+
jobs:
5+
stubtest:
6+
name: Run stubtest
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@v2
10+
11+
- name: Set up latest Python 3
12+
uses: actions/setup-python@v2
13+
with:
14+
python-version: 3
15+
16+
- name: Install dependencies
17+
run: |
18+
python -m pip install --upgrade pip
19+
pip install mypy types-protobuf
20+
21+
- name: Run mypy.stubtest
22+
run: |
23+
cd python
24+
python run_stubtest.py
25+
26+
mypy:
27+
name: Run mypy on stubs
28+
runs-on: ubuntu-latest
29+
steps:
30+
- uses: actions/checkout@v2
31+
32+
- name: Set up latest Python 3
33+
uses: actions/setup-python@v2
34+
with:
35+
python-version: 3
36+
37+
- name: Install dependencies
38+
run: |
39+
python -m pip install --upgrade pip
40+
pip install mypy types-protobuf
41+
42+
- name: Run mypy
43+
run: |
44+
cd python
45+
mypy --exclude pb2/ -p phonenumbers

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,16 @@ load of metadata will not cause a pause or memory exhaustion):
210210
The `phonenumberslite` version of the package does not include the geocoding, carrier and timezone metadata,
211211
which can be useful if you have problems installing the main `phonenumbers` package due to space/memory limitations.
212212

213+
Static Typing
214+
-------------
215+
216+
The library includes a set of type [stub files](https://www.python.org/dev/peps/pep-0484/#stub-files) to support static
217+
type checking by library users. These stub files signal the types that should be used, and may also be of use in IDEs
218+
which have integrated type checking functionalities.
219+
220+
These files are written for Python 3, and as such type checking the library with these stubs on Python 2.5-2.7 is
221+
unsupported.
222+
213223
Project Layout
214224
--------------
215225

python/MANIFEST.in

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
recursive-include tests *.py
21
include HISTORY.md
32
include LICENSE
43
include testwrapper.py

python/phonenumbers/__init__.pyi

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
from .asyoutypeformatter import AsYouTypeFormatter as AsYouTypeFormatter
2+
from .phonemetadata import NumberFormat as NumberFormat
3+
from .phonemetadata import PhoneMetadata as PhoneMetadata
4+
from .phonemetadata import PhoneNumberDesc as PhoneNumberDesc
5+
from .phonemetadata import REGION_CODE_FOR_NON_GEO_ENTITY as REGION_CODE_FOR_NON_GEO_ENTITY
6+
from .phonenumber import CountryCodeSource as CountryCodeSource
7+
from .phonenumber import FrozenPhoneNumber as FrozenPhoneNumber
8+
from .phonenumber import PhoneNumber as PhoneNumber
9+
from .phonenumbermatcher import Leniency as Leniency
10+
from .phonenumbermatcher import PhoneNumberMatch as PhoneNumberMatch
11+
from .phonenumbermatcher import PhoneNumberMatcher as PhoneNumberMatcher
12+
from .phonenumberutil import can_be_internationally_dialled as can_be_internationally_dialled
13+
from .phonenumberutil import convert_alpha_characters_in_number as convert_alpha_characters_in_number
14+
from .phonenumberutil import country_code_for_region as country_code_for_region
15+
from .phonenumberutil import country_code_for_valid_region as country_code_for_valid_region
16+
from .phonenumberutil import COUNTRY_CODE_TO_REGION_CODE as COUNTRY_CODE_TO_REGION_CODE
17+
from .phonenumberutil import COUNTRY_CODES_FOR_NON_GEO_REGIONS as COUNTRY_CODES_FOR_NON_GEO_REGIONS
18+
from .phonenumberutil import country_mobile_token as country_mobile_token
19+
from .phonenumberutil import example_number as example_number
20+
from .phonenumberutil import example_number_for_non_geo_entity as example_number_for_non_geo_entity
21+
from .phonenumberutil import example_number_for_type as example_number_for_type
22+
from .phonenumberutil import format_by_pattern as format_by_pattern
23+
from .phonenumberutil import format_in_original_format as format_in_original_format
24+
from .phonenumberutil import format_national_number_with_carrier_code as format_national_number_with_carrier_code
25+
from .phonenumberutil import format_national_number_with_preferred_carrier_code as format_national_number_with_preferred_carrier_code
26+
from .phonenumberutil import format_number as format_number
27+
from .phonenumberutil import format_number_for_mobile_dialing as format_number_for_mobile_dialing
28+
from .phonenumberutil import format_out_of_country_calling_number as format_out_of_country_calling_number
29+
from .phonenumberutil import format_out_of_country_keeping_alpha_chars as format_out_of_country_keeping_alpha_chars
30+
from .phonenumberutil import invalid_example_number as invalid_example_number
31+
from .phonenumberutil import is_alpha_number as is_alpha_number
32+
from .phonenumberutil import is_mobile_number_portable_region as is_mobile_number_portable_region
33+
from .phonenumberutil import is_nanpa_country as is_nanpa_country
34+
from .phonenumberutil import is_number_geographical as is_number_geographical
35+
from .phonenumberutil import is_number_match as is_number_match
36+
from .phonenumberutil import is_number_type_geographical as is_number_type_geographical
37+
from .phonenumberutil import is_possible_number as is_possible_number
38+
from .phonenumberutil import is_possible_number_for_type as is_possible_number_for_type
39+
from .phonenumberutil import is_possible_number_for_type_with_reason as is_possible_number_for_type_with_reason
40+
from .phonenumberutil import is_possible_number_string as is_possible_number_string
41+
from .phonenumberutil import is_possible_number_with_reason as is_possible_number_with_reason
42+
from .phonenumberutil import is_valid_number as is_valid_number
43+
from .phonenumberutil import is_valid_number_for_region as is_valid_number_for_region
44+
from .phonenumberutil import length_of_geographical_area_code as length_of_geographical_area_code
45+
from .phonenumberutil import length_of_national_destination_code as length_of_national_destination_code
46+
from .phonenumberutil import MatchType as MatchType
47+
from .phonenumberutil import national_significant_number as national_significant_number
48+
from .phonenumberutil import ndd_prefix_for_region as ndd_prefix_for_region
49+
from .phonenumberutil import NON_DIGITS_PATTERN as NON_DIGITS_PATTERN
50+
from .phonenumberutil import normalize_diallable_chars_only as normalize_diallable_chars_only
51+
from .phonenumberutil import normalize_digits_only as normalize_digits_only
52+
from .phonenumberutil import number_type as number_type
53+
from .phonenumberutil import NumberParseException as NumberParseException
54+
from .phonenumberutil import parse as parse
55+
from .phonenumberutil import PhoneNumberFormat as PhoneNumberFormat
56+
from .phonenumberutil import PhoneNumberType as PhoneNumberType
57+
from .phonenumberutil import region_code_for_country_code as region_code_for_country_code
58+
from .phonenumberutil import region_code_for_number as region_code_for_number
59+
from .phonenumberutil import region_codes_for_country_code as region_codes_for_country_code
60+
from .phonenumberutil import supported_calling_codes as supported_calling_codes
61+
from .phonenumberutil import SUPPORTED_REGIONS as SUPPORTED_REGIONS
62+
from .phonenumberutil import supported_types_for_non_geo_entity as supported_types_for_non_geo_entity
63+
from .phonenumberutil import supported_types_for_region as supported_types_for_region
64+
from .phonenumberutil import truncate_too_long_number as truncate_too_long_number
65+
from .phonenumberutil import UNKNOWN_REGION as UNKNOWN_REGION
66+
from .phonenumberutil import ValidationResult as ValidationResult
67+
from .shortnumberinfo import connects_to_emergency_number as connects_to_emergency_number
68+
from .shortnumberinfo import expected_cost as expected_cost
69+
from .shortnumberinfo import expected_cost_for_region as expected_cost_for_region
70+
from .shortnumberinfo import is_carrier_specific as is_carrier_specific
71+
from .shortnumberinfo import is_carrier_specific_for_region as is_carrier_specific_for_region
72+
from .shortnumberinfo import is_emergency_number as is_emergency_number
73+
from .shortnumberinfo import is_possible_short_number as is_possible_short_number
74+
from .shortnumberinfo import is_possible_short_number_for_region as is_possible_short_number_for_region
75+
from .shortnumberinfo import is_sms_service_for_region as is_sms_service_for_region
76+
from .shortnumberinfo import is_valid_short_number as is_valid_short_number
77+
from .shortnumberinfo import is_valid_short_number_for_region as is_valid_short_number_for_region
78+
from .shortnumberinfo import ShortNumberCost as ShortNumberCost
79+
from .shortnumberinfo import SUPPORTED_SHORT_REGIONS as SUPPORTED_SHORT_REGIONS
80+
81+
__version__: str
82+
__all__: list[str]
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
from re import Pattern
2+
3+
from .phonemetadata import NumberFormat
4+
from .phonemetadata import PhoneMetadata
5+
6+
_SEPARATOR_BEFORE_NATIONAL_NUMBER: str
7+
_EMPTY_METADATA: PhoneMetadata
8+
_NATIONAL_PREFIX_SEPARATORS_PATTERN: Pattern[str]
9+
_ELIGIBLE_FORMAT_PATTERN: Pattern[str]
10+
_MIN_LEADING_DIGITS_LENGTH: int
11+
_DIGIT_PLACEHOLDER: str
12+
_DIGIT_PATTERN: Pattern[str]
13+
14+
def _get_metadata_for_region(region_code: str) -> PhoneMetadata: ...
15+
16+
class AsYouTypeFormatter:
17+
_default_country: str
18+
_current_metadata: PhoneMetadata
19+
_default_metadata: PhoneMetadata
20+
_current_output: str
21+
_accrued_input: str
22+
_accrued_input_without_formatting: str
23+
_formatting_template: str
24+
_last_match_position: int
25+
_current_formatting_pattern: str
26+
_prefix_before_national_number: str
27+
_should_add_space_after_national_prefix: bool
28+
_extracted_national_prefix: str
29+
_national_number: str
30+
_able_to_format: bool
31+
_input_has_formatting: bool
32+
_position_to_remember: int
33+
_original_position: int
34+
_is_complete_number: bool
35+
_is_expecting_country_calling_code: bool
36+
_possible_formats: list[NumberFormat]
37+
def __init__(self, region_code: str) -> None: ...
38+
def _maybe_create_new_template(self) -> bool: ...
39+
def _get_available_formats(self, leading_digits: str) -> None: ...
40+
def _narrow_down_possible_formats(self, leading_digits: str) -> None: ...
41+
def _create_formatting_template(self, num_format: NumberFormat) -> bool: ...
42+
def _get_formatting_template(self, number_pattern: str, number_format: str) -> str: ...
43+
def _clear(self) -> None: ...
44+
def clear(self) -> None: ...
45+
def input_digit(self, next_char: str, remember_position: bool = ...) -> str: ...
46+
def _attempt_to_choose_pattern_with_prefix_extracted(self) -> str: ...
47+
def _able_to_extract_longer_ndd(self) -> bool: ...
48+
def _is_digit_or_leading_plus_sign(self, next_char: str) -> bool: ...
49+
def _attempt_to_format_accrued_digits(self) -> str: ...
50+
def get_remembered_position(self) -> int: ...
51+
def _append_national_number(self, national_number: str) -> str: ...
52+
def _attempt_to_choose_formatting_pattern(self) -> str: ...
53+
def _input_accrued_national_number(self) -> str: ...
54+
def _is_nanpa_number_with_national_prefix(self) -> bool: ...
55+
def _remove_national_prefix_from_national_number(self) -> str: ...
56+
def _attempt_to_extract_idd(self) -> bool: ...
57+
def _attempt_to_extract_ccc(self) -> bool: ...
58+
def _normalize_and_accrue_digits_and_plus_sign(self, next_char: str, remember_position: bool) -> str: ...
59+
def _input_digit_helper(self, next_char: str) -> str: ...

python/phonenumbers/carrier.pyi

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from .phonenumber import PhoneNumber
2+
3+
__all__: list[str]
4+
5+
def name_for_valid_number(numobj: PhoneNumber, lang: str, script: str | None = ..., region: str | None = ...) -> str: ...
6+
def name_for_number(numobj: PhoneNumber, lang: str, script: str | None = ..., region: str | None = ...) -> str: ...
7+
def safe_display_name(numobj: PhoneNumber, lang: str, script: str | None = ..., region: str | None = ...) -> str: ...
8+
def _is_mobile(ntype: int) -> bool: ...

python/phonenumbers/geocoder.pyi

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from .phonenumber import PhoneNumber
2+
3+
__all__: list[str]
4+
5+
def country_name_for_number(numobj: PhoneNumber, lang: str, script: str | None = ..., region: str | None = ...) -> str: ...
6+
def _region_display_name(region_code: str, lang: str, script: str | None = ..., region: str | None = ...) -> str: ...
7+
def description_for_valid_number(numobj: PhoneNumber, lang: str, script: str | None = ..., region: str | None = ...) -> str: ...
8+
def description_for_number(numobj: PhoneNumber, lang: str, script: str | None = ..., region: str | None = ...) -> str: ...
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
from collections.abc import Callable
2+
import threading
3+
4+
from .util import ImmutableMixin
5+
from .util import UnicodeMixin
6+
7+
REGION_CODE_FOR_NON_GEO_ENTITY: str
8+
9+
class NumberFormat(UnicodeMixin, ImmutableMixin):
10+
pattern: str | None
11+
format: str | None
12+
leading_digits_pattern: list[str]
13+
national_prefix_formatting_rule: str | None
14+
national_prefix_optional_when_formatting: bool | None
15+
domestic_carrier_code_formatting_rule: str | None
16+
def __init__(
17+
self,
18+
pattern: str | None = ...,
19+
format: str | None = ...,
20+
leading_digits_pattern: list[str] | None = ...,
21+
national_prefix_formatting_rule: str | None = ...,
22+
national_prefix_optional_when_formatting: bool | None = ...,
23+
domestic_carrier_code_formatting_rule: str | None = ...,
24+
) -> None: ...
25+
def merge_from(self, other: NumberFormat) -> None: ...
26+
def __eq__(self, other: object) -> bool: ...
27+
def __ne__(self, other: object) -> bool: ...
28+
def __repr__(self) -> str: ...
29+
def __unicode__(self) -> str: ...
30+
31+
class PhoneNumberDesc(UnicodeMixin, ImmutableMixin):
32+
national_number_pattern: str | None
33+
example_number: str | None
34+
possible_length: tuple[int, ...]
35+
possible_length_local_only: tuple[int, ...]
36+
def __init__(
37+
self,
38+
national_number_pattern: str | None = ...,
39+
example_number: str | None = ...,
40+
possible_length: tuple[int, ...] | None = ...,
41+
possible_length_local_only: tuple[int, ...] | None = ...,
42+
) -> None: ...
43+
def merge_from(self, other: PhoneNumberDesc) -> None: ...
44+
def __eq__(self, other: object) -> bool: ...
45+
def __ne__(self, other: object) -> bool: ...
46+
def __repr__(self) -> str: ...
47+
def __unicode__(self) -> str: ...
48+
49+
def _same_pattern(left: PhoneNumberDesc | None, right: PhoneNumberDesc | None) -> bool: ...
50+
51+
class PhoneMetadata(UnicodeMixin, ImmutableMixin):
52+
_metadata_lock: threading.Lock
53+
_region_available: dict[str, Callable[[str], None] | None]
54+
_short_region_available: dict[str, Callable[[str], None] | None]
55+
_country_code_available: dict[int, Callable[[int], None] | None]
56+
_region_metadata: dict[str, PhoneMetadata]
57+
_short_region_metadata: dict[str, PhoneMetadata]
58+
_country_code_metadata: dict[int, PhoneMetadata]
59+
general_desc: PhoneNumberDesc | None
60+
fixed_line: PhoneNumberDesc | None
61+
mobile: PhoneNumberDesc | None
62+
toll_free: PhoneNumberDesc | None
63+
premium_rate: PhoneNumberDesc | None
64+
shared_cost: PhoneNumberDesc | None
65+
personal_number: PhoneNumberDesc | None
66+
voip: PhoneNumberDesc | None
67+
pager: PhoneNumberDesc | None
68+
uan: PhoneNumberDesc | None
69+
emergency: PhoneNumberDesc | None
70+
voicemail: PhoneNumberDesc | None
71+
short_code: PhoneNumberDesc | None
72+
standard_rate: PhoneNumberDesc | None
73+
carrier_specific: PhoneNumberDesc | None
74+
sms_services: PhoneNumberDesc | None
75+
no_international_dialling: PhoneNumberDesc | None
76+
id: str
77+
country_code: int | None
78+
international_prefix: str | None
79+
preferred_international_prefix: str | None
80+
national_prefix: str | None
81+
preferred_extn_prefix: str | None
82+
national_prefix_for_parsing: str | None
83+
national_prefix_transform_rule: str | None
84+
same_mobile_and_fixed_line_pattern: bool
85+
number_format: list[NumberFormat]
86+
intl_number_format: list[NumberFormat]
87+
main_country_for_code: bool
88+
leading_digits: str | None
89+
leading_zero_possible: bool
90+
mobile_number_portable_region: bool
91+
short_data: bool
92+
@classmethod
93+
def metadata_for_region(cls, region_code: str, default: PhoneMetadata | None = ...) -> PhoneMetadata | None: ...
94+
@classmethod
95+
def short_metadata_for_region(cls, region_code: str, default: PhoneMetadata | None = ...) -> PhoneMetadata | None: ...
96+
@classmethod
97+
def metadata_for_nongeo_region(cls, country_code: int, default: PhoneMetadata | None = ...) -> PhoneMetadata | None: ...
98+
@classmethod
99+
def metadata_for_region_or_calling_code(cls, country_calling_code: int, region_code: str) -> PhoneMetadata | None: ...
100+
@classmethod
101+
def register_region_loader(cls, region_code: str, loader: Callable[[str], None]) -> None: ...
102+
@classmethod
103+
def register_short_region_loader(cls, region_code: str, loader: Callable[[str], None]) -> None: ...
104+
@classmethod
105+
def register_nongeo_region_loader(cls, country_code: int, loader: Callable[[int], None]) -> None: ...
106+
@classmethod
107+
def load_all(cls) -> None: ...
108+
def __init__(
109+
self,
110+
id: str,
111+
general_desc: PhoneNumberDesc | None = ...,
112+
fixed_line: PhoneNumberDesc | None = ...,
113+
mobile: PhoneNumberDesc | None = ...,
114+
toll_free: PhoneNumberDesc | None = ...,
115+
premium_rate: PhoneNumberDesc | None = ...,
116+
shared_cost: PhoneNumberDesc | None = ...,
117+
personal_number: PhoneNumberDesc | None = ...,
118+
voip: PhoneNumberDesc | None = ...,
119+
pager: PhoneNumberDesc | None = ...,
120+
uan: PhoneNumberDesc | None = ...,
121+
emergency: PhoneNumberDesc | None = ...,
122+
voicemail: PhoneNumberDesc | None = ...,
123+
short_code: PhoneNumberDesc | None = ...,
124+
standard_rate: PhoneNumberDesc | None = ...,
125+
carrier_specific: PhoneNumberDesc | None = ...,
126+
sms_services: PhoneNumberDesc | None = ...,
127+
no_international_dialling: PhoneNumberDesc | None = ...,
128+
country_code: int | None = ...,
129+
international_prefix: str | None = ...,
130+
preferred_international_prefix: str | None = ...,
131+
national_prefix: str | None = ...,
132+
preferred_extn_prefix: str | None = ...,
133+
national_prefix_for_parsing: str | None = ...,
134+
national_prefix_transform_rule: str | None = ...,
135+
number_format: list[NumberFormat] | None = ...,
136+
intl_number_format: list[NumberFormat] | None = ...,
137+
main_country_for_code: bool = ...,
138+
leading_digits: str | None = ...,
139+
leading_zero_possible: bool = ...,
140+
mobile_number_portable_region: bool = ...,
141+
short_data: bool = ...,
142+
register: bool = ...,
143+
) -> None: ...
144+
def __eq__(self, other: object) -> bool: ...
145+
def __ne__(self, other: object) -> bool: ...
146+
def __repr__(self) -> str: ...
147+
def __unicode__(self) -> str: ...

0 commit comments

Comments
 (0)